├── .github
├── renovate.json5
└── workflows
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── .npmrc
├── .vscode
├── extensions.json
└── settings.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── biome.json
├── package.json
├── playground
├── package.json
├── rsbuild.config.ts
└── src
│ ├── index.css
│ └── index.js
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── rslib.config.ts
├── src
├── Set.prototype.isSubsetOf.ts
├── TailwindCSSRspackPlugin.ts
└── index.ts
├── test
├── basic
│ ├── index.test.ts
│ └── src
│ │ └── index.js
├── cjs
│ ├── config
│ │ ├── package.json
│ │ └── tailwind.config.js
│ ├── index.test.ts
│ └── src
│ │ └── index.js
├── config
│ ├── config
│ │ └── tailwind.config.js
│ ├── index.test.ts
│ └── src
│ │ └── index.js
├── exclude-include
│ ├── index.test.ts
│ └── src
│ │ ├── exclude.js
│ │ ├── include.jsx
│ │ ├── index.js
│ │ ├── not-exclude.js
│ │ └── not-include.ts
├── exclude
│ ├── index.test.ts
│ └── src
│ │ ├── exclude.js
│ │ ├── index.js
│ │ └── not-exclude.js
├── helper.ts
├── include
│ ├── index.test.ts
│ └── src
│ │ ├── include.jsx
│ │ ├── index.js
│ │ └── not-include.ts
├── isSubsetOf.test.ts
├── multi-entries
│ ├── a.js
│ ├── b.js
│ ├── c.js
│ ├── d.js
│ ├── e.js
│ └── index.test.ts
├── postcss-config
│ ├── flex-to-grid.js
│ ├── index.test.ts
│ ├── postcss.config.js
│ └── src
│ │ └── index.js
├── tools-postcss
│ ├── flex-to-grid.js
│ ├── index.test.ts
│ └── src
│ │ └── index.js
└── with-resource-query
│ ├── index.test.ts
│ └── src
│ └── index.js
└── tsconfig.json
/.github/renovate.json5:
--------------------------------------------------------------------------------
1 | {
2 | $schema: 'https://docs.renovatebot.com/renovate-schema.json',
3 | extends: [
4 | 'config:recommended',
5 | 'schedule:monthly',
6 | 'group:allNonMajor',
7 | ],
8 | rangeStrategy: 'bump',
9 | packageRules: [
10 | {
11 | matchDepTypes: [
12 | 'peerDependencies',
13 | ],
14 | enabled: false,
15 | },
16 | ],
17 | }
18 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # This action will publish the package to npm and create a GitHub release.
2 | name: Release
3 |
4 | on:
5 | # Run `npm run bump` to bump the version and create a git tag.
6 | push:
7 | tags:
8 | - "v*"
9 |
10 | workflow_dispatch:
11 |
12 | permissions:
13 | contents: write
14 | id-token: write
15 |
16 | jobs:
17 | publish:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v4
22 |
23 | - name: Install Pnpm
24 | run: npm i -g corepack@latest --force && corepack enable
25 |
26 | - name: Setup Node.js
27 | uses: actions/setup-node@v4
28 | with:
29 | node-version: 22
30 | cache: "pnpm"
31 |
32 | - name: Install Dependencies
33 | run: pnpm install
34 |
35 | - name: Publish
36 | uses: JS-DevTools/npm-publish@v3
37 | with:
38 | token: ${{ secrets.NPM_TOKEN }}
39 |
40 | - name: Create GitHub Release
41 | uses: ncipollo/release-action@v1
42 | with:
43 | generateReleaseNotes: "true"
44 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | # Controls when the action will run.
4 | on:
5 | # Triggers the workflow on pull request events but only for the main branch
6 | pull_request:
7 | branches: [main]
8 | push:
9 | branches: [main]
10 | # Allows you to run this workflow manually from the Actions tab
11 | workflow_dispatch:
12 |
13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
14 | jobs:
15 | test:
16 | runs-on: ${{ matrix.os }}
17 | name: Test tailwindcss@${{ matrix.tailwindcss }} on ${{ matrix.os }}
18 | strategy:
19 | matrix:
20 | os: [ubuntu-latest, windows-latest]
21 | tailwindcss:
22 | - "^3"
23 | - "3.1.0" # The fist version that support `options.config`.
24 |
25 | # Steps represent a sequence of tasks that will be executed as part of the job
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 |
30 | - name: Install Pnpm
31 | run: npm i -g corepack@latest --force && corepack enable
32 |
33 | - name: Setup Node.js
34 | uses: actions/setup-node@v4
35 | with:
36 | node-version: 22
37 | cache: "pnpm"
38 |
39 | - name: Install Dependencies
40 | run: pnpm install && npx playwright install chromium
41 |
42 | - name: Install tailwindcss@${{ matrix.tailwindcss }}
43 | if: ${{ matrix.tailwindcss }} != "latest"
44 | # Tailwind CSS <= v3.4.0 does not have correct TypeScript definition, which will make `rslib build` fail.
45 | continue-on-error: true
46 | run: pnpm add -D -w tailwindcss@${{ matrix.tailwindcss }}
47 |
48 | - name: Run Test
49 | run: pnpm run test
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local
2 | .DS_Store
3 | *.local
4 | *.log*
5 |
6 | # Dist
7 | node_modules
8 | dist/
9 | test-results
10 |
11 | # IDE
12 | .vscode/*
13 | !.vscode/settings.json
14 | !.vscode/extensions.json
15 | .idea
16 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | # Disable the default public-hoist-pattern(*-eslint-*, *-prettier-*)
2 | public-hoist-pattern=
3 | hoist-workspace-packages=true
4 | strict-peer-dependencies=true
5 | engine-strict=true
6 | registry=https://registry.npmjs.org/
7 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["biomejs.biome"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.useIgnoreFiles": true,
3 | "[json]": {
4 | "editor.defaultFormatter": "biomejs.biome"
5 | },
6 | "[typescript]": {
7 | "editor.defaultFormatter": "biomejs.biome"
8 | },
9 | "[javascript]": {
10 | "editor.defaultFormatter": "biomejs.biome"
11 | },
12 | "[javascriptreact]": {
13 | "editor.defaultFormatter": "biomejs.biome"
14 | },
15 | "[css]": {
16 | "editor.defaultFormatter": "biomejs.biome"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 | ## 0.2.0
4 |
5 | - Fixed bug that other postcss plugins should not run before tailwindcss.
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Rspack Contrib
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rsbuild-plugin-tailwindcss
2 |
3 | An Rsbuild plugin to integrate with [Tailwind CSS](https://tailwindcss.com/) V3.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## Why?
14 |
15 | Tailwind CSS is able to remove unused CSS classes through [Content Configuration](https://tailwindcss.com/docs/content-configuration). However, its accuracy may be insufficient when:
16 |
17 | - Using multiple entries
18 | - Using a Tailwind CSS-based component library
19 |
20 | This plugin uses the Rspack module graph to override the `content` configuration with imported modules, generating Tailwind CSS output _**based on usage**_.
21 |
22 | ## Usage
23 |
24 | Install:
25 |
26 | ```bash
27 | npm add tailwindcss@3 rsbuild-plugin-tailwindcss -D
28 | ```
29 |
30 | Add plugin to your `rsbuild.config.ts`:
31 |
32 | ```ts
33 | // rsbuild.config.ts
34 | import { pluginTailwindCSS } from "rsbuild-plugin-tailwindcss";
35 |
36 | export default {
37 | plugins: [pluginTailwindCSS()],
38 | };
39 | ```
40 |
41 | ### Custom Tailwind CSS Configuration
42 |
43 | Create a `tailwind.config.js` file at the root of the project:
44 |
45 | ```js
46 | /** @type {import('tailwindcss').Config} */
47 | export default {
48 | theme: {
49 | colors: {
50 | blue: "#1fb6ff",
51 | purple: "#7e5bef",
52 | pink: "#ff49db",
53 | orange: "#ff7849",
54 | green: "#13ce66",
55 | yellow: "#ffc82c",
56 | "gray-dark": "#273444",
57 | gray: "#8492a6",
58 | "gray-light": "#d3dce6",
59 | },
60 | },
61 | };
62 | ```
63 |
64 | This will be auto-loaded by Rsbuild and applied by `rsbuild-plugin-tailwindcss`.
65 |
66 | > [!NOTE]
67 | >
68 | > You don't need to add `content` in the `tailwind.config.js`. `rsbuild-plugin-tailwindcss` will add the imported modules for you.
69 |
70 | ### Custom PostCSS Options
71 |
72 | Create a `postcss.config.js` file at the root of the project:
73 |
74 | ```js
75 | export default {
76 | plugins: {
77 | cssnano: process.env["NODE_ENV"] === "production" ? {} : false,
78 | },
79 | };
80 | ```
81 |
82 | > [!NOTE]
83 | >
84 | > You don't need to add `tailwindcss` in the `postcss.config.js`. `rsbuild-plugin-tailwindcss` will add the plugin for you.
85 |
86 | Or use the [`tools.postcss`](https://rsbuild.dev/config/tools/postcss) option in `rsbuild.config.ts`.
87 |
88 | ## Options
89 |
90 | ### `config`
91 |
92 | - Type: `string | undefined`
93 | - Default: `tailwind.config.js`
94 |
95 | The path to custom Tailwind CSS configuration. Could be a relative path from the root of the project or an absolute path.
96 |
97 | - Example:
98 |
99 | ```js
100 | // rsbuild.config.ts
101 | import { pluginTailwindCSS } from "rsbuild-plugin-tailwindcss";
102 |
103 | export default {
104 | plugins: [
105 | pluginTailwindCSS({
106 | config: "./config/tailwind.config.js",
107 | }),
108 | ],
109 | };
110 | ```
111 |
112 | ### `exclude` / `include`
113 |
114 | - Type: `ReadonlyArray | string | RegExp | null | undefined`
115 | - Default: `undefined`
116 |
117 | These two options are used to filter which module to be processed by Tailwind CSS using [`picomatch`](https://github.com/micromatch/picomatch#globbing-features) pattern.
118 |
119 | If `include` is omitted or empty, all modules that do not match any of the `exclude` patterns will be included.
120 | Otherwise, only modules that match one or more of the `include` patterns and do not match any of the `exclude` patterns will be included.
121 |
122 | - Example:
123 |
124 | Include all `.js`, `.jsx`, `.ts`, `.tsx` files but exclude files in `./src/store` and `node_modules`:
125 |
126 | ```js
127 | // rsbuild.config.ts
128 | import { pluginTailwindCSS } from "@byted-lynx/plugin-tailwindcss";
129 |
130 | export default {
131 | plugins: [
132 | pluginTailwindCSS({
133 | include: /\.[jt]sx?/,
134 | exclude: ["./src/store/**", /[\\/]node_modules[\\/]/],
135 | }),
136 | ],
137 | };
138 | ```
139 |
140 | Note that `picomatch` patterns are very similar to [`minimatch`](https://github.com/isaacs/minimatch#readme) patterns, and in most use cases, they are interchangeable. If you have more specific pattern matching needs, you can view [this comparison table](https://github.com/micromatch/picomatch#library-comparisons) to learn more about where the libraries differ.
141 |
142 | ## Debugging
143 |
144 | Use `DEBUG='rsbuild'` to enable debugging mode for the plugin. When debugging is enabled, the plugin will:
145 |
146 | 1. Save the generated Tailwind CSS configuration files in the `.rsbuild/` directory inside your project's output path.
147 | 2. Generate readable configuration files that include all modules being processed by Tailwind CSS.
148 |
149 | This is helpful for:
150 |
151 | - Inspecting which modules are included in the Tailwind CSS content scanning
152 | - Troubleshooting issues with CSS purging
153 | - Understanding how the plugin is generating configurations for each entry point
154 |
155 | Example:
156 |
157 | ```bash
158 | # For macOS/Linux
159 | DEBUG=rsbuild npm run build
160 |
161 | # For Windows (cmd)
162 | set DEBUG=rsbuild && npm run build
163 |
164 | # For Windows (PowerShell)
165 | $env:DEBUG="rsbuild"; npm run build
166 | ```
167 |
168 | You can also use more specific debug patterns:
169 |
170 | - `DEBUG=rsbuild:tailwind` - Debug only the Tailwind CSS plugin
171 | - `DEBUG=rsbuild:*` - Debug all Rsbuild plugins
172 | - `DEBUG=*` - Debug everything
173 |
174 | ## Credits
175 |
176 | Thanks to:
177 |
178 | - [Tailwind CSS V4](https://tailwindcss.com/blog/tailwindcss-v4-alpha) for the idea of purge CSS by module graph.
179 | - The [purge-tailwind-plugin](https://github.com/hardfist/purge-tailwind-plugin) created by [@hardfist](https://github.com/hardfist) for the implementation of the Rspack plugin.
180 | - The [Rollup](https://github.com/rollup/) project created by [Rich Harris](https://github.com/Rich-Harris) and maintained by [Lukas Taegert-Atkinson](https://github.com/lukastaegert) for the implementaion of `exclude` and `include`.
181 |
182 | ## License
183 |
184 | [MIT](./LICENSE).
185 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
3 | "organizeImports": {
4 | "enabled": true
5 | },
6 | "vcs": {
7 | "enabled": true,
8 | "defaultBranch": "main",
9 | "clientKind": "git",
10 | "useIgnoreFile": true
11 | },
12 | "formatter": {
13 | "indentStyle": "space"
14 | },
15 | "javascript": {
16 | "formatter": {
17 | "quoteStyle": "single"
18 | }
19 | },
20 | "css": {
21 | "formatter": {
22 | "enabled": true
23 | }
24 | },
25 | "linter": {
26 | "enabled": true,
27 | "rules": {
28 | "recommended": true
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rsbuild-plugin-tailwindcss",
3 | "version": "0.2.1",
4 | "repository": "https://github.com/rspack-contrib/rsbuild-plugin-tailwindcss",
5 | "license": "MIT",
6 | "type": "module",
7 | "exports": {
8 | ".": {
9 | "types": "./dist/index.d.ts",
10 | "import": "./dist/index.js",
11 | "require": "./dist/index.cjs"
12 | }
13 | },
14 | "main": "./dist/index.js",
15 | "module": "./dist/index.mjs",
16 | "types": "./dist/index.d.ts",
17 | "files": ["dist"],
18 | "scripts": {
19 | "build": "rslib build",
20 | "bump": "npx bumpp",
21 | "dev": "rslib build --watch",
22 | "lint": "biome check .",
23 | "lint:write": "biome check . --write",
24 | "prepare": "simple-git-hooks && npm run build",
25 | "test": "playwright test"
26 | },
27 | "simple-git-hooks": {
28 | "pre-commit": "npm run lint:write"
29 | },
30 | "devDependencies": {
31 | "@biomejs/biome": "^1.9.4",
32 | "@playwright/test": "^1.52.0",
33 | "@rollup/pluginutils": "^5.1.4",
34 | "@rsbuild/core": "^1.4.0-beta.1",
35 | "@rslib/core": "^0.9.1",
36 | "@rsbuild/webpack": "^1.3.2",
37 | "@types/node": "^22.15.29",
38 | "@types/semver": "^7.7.0",
39 | "playwright": "^1.52.0",
40 | "postcss": "^8.5.4",
41 | "semver": "^7.7.2",
42 | "simple-git-hooks": "^2.13.0",
43 | "tailwindcss": "^3.4.17",
44 | "typescript": "^5.8.3"
45 | },
46 | "peerDependencies": {
47 | "@rsbuild/core": "^1.1.0",
48 | "tailwindcss": "^3.1.0"
49 | },
50 | "peerDependenciesMeta": {
51 | "@rsbuild/core": {
52 | "optional": true
53 | }
54 | },
55 | "packageManager": "pnpm@10.11.1",
56 | "publishConfig": {
57 | "access": "public",
58 | "provenance": true,
59 | "registry": "https://registry.npmjs.org/"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/playground/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "private": true,
4 | "version": "0.0.0",
5 | "devDependencies": {
6 | "rsbuild-plugin-tailwindcss": "workspace:*"
7 | },
8 | "scripts": {
9 | "dev": "npx rsbuild dev",
10 | "build": "npx rsbuild build"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/playground/rsbuild.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@rsbuild/core';
2 | import { pluginTailwindCSS } from 'rsbuild-plugin-tailwindcss';
3 |
4 | export default defineConfig({
5 | plugins: [pluginTailwindCSS()],
6 | });
7 |
--------------------------------------------------------------------------------
/playground/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind utilities;
2 |
--------------------------------------------------------------------------------
/playground/src/index.js:
--------------------------------------------------------------------------------
1 | import './index.css';
2 |
3 | document.querySelector('#root').innerHTML = `
4 |
5 |
Vanilla Rsbuild
6 |
Start building amazing things with Rsbuild.
7 |
8 | `;
9 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | devDependencies:
11 | '@biomejs/biome':
12 | specifier: ^1.9.4
13 | version: 1.9.4
14 | '@playwright/test':
15 | specifier: ^1.52.0
16 | version: 1.52.0
17 | '@rollup/pluginutils':
18 | specifier: ^5.1.4
19 | version: 5.1.4
20 | '@rsbuild/core':
21 | specifier: ^1.4.0-beta.1
22 | version: 1.4.0-beta.1
23 | '@rsbuild/webpack':
24 | specifier: ^1.3.2
25 | version: 1.3.2(@rsbuild/core@1.4.0-beta.1)(@rspack/core@1.3.13(@swc/helpers@0.5.17))
26 | '@rslib/core':
27 | specifier: ^0.9.1
28 | version: 0.9.1(typescript@5.8.3)
29 | '@types/node':
30 | specifier: ^22.15.29
31 | version: 22.15.29
32 | '@types/semver':
33 | specifier: ^7.7.0
34 | version: 7.7.0
35 | playwright:
36 | specifier: ^1.52.0
37 | version: 1.52.0
38 | postcss:
39 | specifier: ^8.5.4
40 | version: 8.5.4
41 | semver:
42 | specifier: ^7.7.2
43 | version: 7.7.2
44 | simple-git-hooks:
45 | specifier: ^2.13.0
46 | version: 2.13.0
47 | tailwindcss:
48 | specifier: ^3.4.17
49 | version: 3.4.17
50 | typescript:
51 | specifier: ^5.8.3
52 | version: 5.8.3
53 |
54 | playground:
55 | devDependencies:
56 | rsbuild-plugin-tailwindcss:
57 | specifier: workspace:*
58 | version: link:..
59 |
60 | packages:
61 |
62 | '@alloc/quick-lru@5.2.0':
63 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
64 | engines: {node: '>=10'}
65 |
66 | '@ast-grep/napi-darwin-arm64@0.37.0':
67 | resolution: {integrity: sha512-QAiIiaAbLvMEg/yBbyKn+p1gX2/FuaC0SMf7D7capm/oG4xGMzdeaQIcSosF4TCxxV+hIH4Bz9e4/u7w6Bnk3Q==}
68 | engines: {node: '>= 10'}
69 | cpu: [arm64]
70 | os: [darwin]
71 |
72 | '@ast-grep/napi-darwin-x64@0.37.0':
73 | resolution: {integrity: sha512-zvcvdgekd4ySV3zUbUp8HF5nk5zqwiMXTuVzTUdl/w08O7JjM6XPOIVT+d2o/MqwM9rsXdzdergY5oY2RdhSPA==}
74 | engines: {node: '>= 10'}
75 | cpu: [x64]
76 | os: [darwin]
77 |
78 | '@ast-grep/napi-linux-arm64-gnu@0.37.0':
79 | resolution: {integrity: sha512-L7Sj0lXy8X+BqSMgr1LB8cCoWk0rericdeu+dC8/c8zpsav5Oo2IQKY1PmiZ7H8IHoFBbURLf8iklY9wsD+cyA==}
80 | engines: {node: '>= 10'}
81 | cpu: [arm64]
82 | os: [linux]
83 |
84 | '@ast-grep/napi-linux-arm64-musl@0.37.0':
85 | resolution: {integrity: sha512-LF9sAvYy6es/OdyJDO3RwkX3I82Vkfsng1sqUBcoWC1jVb1wX5YVzHtpQox9JrEhGl+bNp7FYxB4Qba9OdA5GA==}
86 | engines: {node: '>= 10'}
87 | cpu: [arm64]
88 | os: [linux]
89 |
90 | '@ast-grep/napi-linux-x64-gnu@0.37.0':
91 | resolution: {integrity: sha512-TViz5/klqre6aSmJzswEIjApnGjJzstG/SE8VDWsrftMBMYt2PTu3MeluZVwzSqDao8doT/P+6U11dU05UOgxw==}
92 | engines: {node: '>= 10'}
93 | cpu: [x64]
94 | os: [linux]
95 |
96 | '@ast-grep/napi-linux-x64-musl@0.37.0':
97 | resolution: {integrity: sha512-/BcCH33S9E3ovOAEoxYngUNXgb+JLg991sdyiNP2bSoYd30a9RHrG7CYwW6fMgua3ijQ474eV6cq9yZO1bCpXg==}
98 | engines: {node: '>= 10'}
99 | cpu: [x64]
100 | os: [linux]
101 |
102 | '@ast-grep/napi-win32-arm64-msvc@0.37.0':
103 | resolution: {integrity: sha512-TjQA4cFoIEW2bgjLkaL9yqT4XWuuLa5MCNd0VCDhGRDMNQ9+rhwi9eLOWRaap3xzT7g+nlbcEHL3AkVCD2+b3A==}
104 | engines: {node: '>= 10'}
105 | cpu: [arm64]
106 | os: [win32]
107 |
108 | '@ast-grep/napi-win32-ia32-msvc@0.37.0':
109 | resolution: {integrity: sha512-uNmVka8fJCdYsyOlF9aZqQMLTatEYBynjChVTzUfFMDfmZ0bihs/YTqJVbkSm8TZM7CUX82apvn50z/dX5iWRA==}
110 | engines: {node: '>= 10'}
111 | cpu: [ia32]
112 | os: [win32]
113 |
114 | '@ast-grep/napi-win32-x64-msvc@0.37.0':
115 | resolution: {integrity: sha512-vCiFOT3hSCQuHHfZ933GAwnPzmL0G04JxQEsBRfqONywyT8bSdDc/ECpAfr3S9VcS4JZ9/F6tkePKW/Om2Dq2g==}
116 | engines: {node: '>= 10'}
117 | cpu: [x64]
118 | os: [win32]
119 |
120 | '@ast-grep/napi@0.37.0':
121 | resolution: {integrity: sha512-Hb4o6h1Pf6yRUAX07DR4JVY7dmQw+RVQMW5/m55GoiAT/VRoKCWBtIUPPOnqDVhbx1Cjfil9b6EDrgJsUAujEQ==}
122 | engines: {node: '>= 10'}
123 |
124 | '@biomejs/biome@1.9.4':
125 | resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==}
126 | engines: {node: '>=14.21.3'}
127 | hasBin: true
128 |
129 | '@biomejs/cli-darwin-arm64@1.9.4':
130 | resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==}
131 | engines: {node: '>=14.21.3'}
132 | cpu: [arm64]
133 | os: [darwin]
134 |
135 | '@biomejs/cli-darwin-x64@1.9.4':
136 | resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==}
137 | engines: {node: '>=14.21.3'}
138 | cpu: [x64]
139 | os: [darwin]
140 |
141 | '@biomejs/cli-linux-arm64-musl@1.9.4':
142 | resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==}
143 | engines: {node: '>=14.21.3'}
144 | cpu: [arm64]
145 | os: [linux]
146 |
147 | '@biomejs/cli-linux-arm64@1.9.4':
148 | resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==}
149 | engines: {node: '>=14.21.3'}
150 | cpu: [arm64]
151 | os: [linux]
152 |
153 | '@biomejs/cli-linux-x64-musl@1.9.4':
154 | resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==}
155 | engines: {node: '>=14.21.3'}
156 | cpu: [x64]
157 | os: [linux]
158 |
159 | '@biomejs/cli-linux-x64@1.9.4':
160 | resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==}
161 | engines: {node: '>=14.21.3'}
162 | cpu: [x64]
163 | os: [linux]
164 |
165 | '@biomejs/cli-win32-arm64@1.9.4':
166 | resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==}
167 | engines: {node: '>=14.21.3'}
168 | cpu: [arm64]
169 | os: [win32]
170 |
171 | '@biomejs/cli-win32-x64@1.9.4':
172 | resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==}
173 | engines: {node: '>=14.21.3'}
174 | cpu: [x64]
175 | os: [win32]
176 |
177 | '@isaacs/cliui@8.0.2':
178 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
179 | engines: {node: '>=12'}
180 |
181 | '@jridgewell/gen-mapping@0.3.5':
182 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
183 | engines: {node: '>=6.0.0'}
184 |
185 | '@jridgewell/resolve-uri@3.1.2':
186 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
187 | engines: {node: '>=6.0.0'}
188 |
189 | '@jridgewell/set-array@1.2.1':
190 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
191 | engines: {node: '>=6.0.0'}
192 |
193 | '@jridgewell/source-map@0.3.6':
194 | resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
195 |
196 | '@jridgewell/sourcemap-codec@1.5.0':
197 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
198 |
199 | '@jridgewell/trace-mapping@0.3.25':
200 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
201 |
202 | '@module-federation/error-codes@0.14.0':
203 | resolution: {integrity: sha512-GGk+EoeSACJikZZyShnLshtq9E2eCrDWbRiB4QAFXCX4oYmGgFfzXlx59vMNwqTKPJWxkEGnPYacJMcr2YYjag==}
204 |
205 | '@module-federation/error-codes@0.14.3':
206 | resolution: {integrity: sha512-sBJ3XKU9g5Up31jFeXPFsD8AgORV7TLO/cCSMuRewSfgYbG/3vSKLJmfHrO6+PvjZSb9VyV2UaF02ojktW65vw==}
207 |
208 | '@module-federation/runtime-core@0.14.0':
209 | resolution: {integrity: sha512-fGE1Ro55zIFDp/CxQuRhKQ1pJvG7P0qvRm2N+4i8z++2bgDjcxnCKUqDJ8lLD+JfJQvUJf0tuSsJPgevzueD4g==}
210 |
211 | '@module-federation/runtime-core@0.14.3':
212 | resolution: {integrity: sha512-xMFQXflLVW/AJTWb4soAFP+LB4XuhE7ryiLIX8oTyUoBBgV6U2OPghnFljPjeXbud72O08NYlQ1qsHw1kN/V8Q==}
213 |
214 | '@module-federation/runtime-tools@0.14.0':
215 | resolution: {integrity: sha512-y/YN0c2DKsLETE+4EEbmYWjqF9G6ZwgZoDIPkaQ9p0pQu0V4YxzWfQagFFxR0RigYGuhJKmSU/rtNoHq+qF8jg==}
216 |
217 | '@module-federation/runtime-tools@0.14.3':
218 | resolution: {integrity: sha512-QBETX7iMYXdSa3JtqFlYU+YkpymxETZqyIIRiqg0gW+XGpH3jgU68yjrme2NBJp7URQi/CFZG8KWtfClk0Pjgw==}
219 |
220 | '@module-federation/runtime@0.14.0':
221 | resolution: {integrity: sha512-kR3cyHw/Y64SEa7mh4CHXOEQYY32LKLK75kJOmBroLNLO7/W01hMNAvGBYTedS7hWpVuefPk1aFZioy3q2VLdQ==}
222 |
223 | '@module-federation/runtime@0.14.3':
224 | resolution: {integrity: sha512-7ZHpa3teUDVhraYdxQGkfGHzPbjna4LtwbpudgzAxSLLFxLDNanaxCuSeIgSM9c+8sVUNC9kvzUgJEZB0krPJw==}
225 |
226 | '@module-federation/sdk@0.14.0':
227 | resolution: {integrity: sha512-lg/OWRsh18hsyTCamOOhEX546vbDiA2O4OggTxxH2wTGr156N6DdELGQlYIKfRdU/0StgtQS81Goc0BgDZlx9A==}
228 |
229 | '@module-federation/sdk@0.14.3':
230 | resolution: {integrity: sha512-THJZMfbXpqjQOLblCQ8jjcBFFXsGRJwUWE9l/Q4SmuCSKMgAwie7yLT0qSGrHmyBYrsUjAuy+xNB4nfKP0pnGw==}
231 |
232 | '@module-federation/webpack-bundler-runtime@0.14.0':
233 | resolution: {integrity: sha512-POWS6cKBicAAQ3DNY5X7XEUSfOfUsRaBNxbuwEfSGlrkTE9UcWheO06QP2ndHi8tHQuUKcIHi2navhPkJ+k5xg==}
234 |
235 | '@module-federation/webpack-bundler-runtime@0.14.3':
236 | resolution: {integrity: sha512-hIyJFu34P7bY2NeMIUHAS/mYUHEY71VTAsN0A0AqEJFSVPszheopu9VdXq0VDLrP9KQfuXT8SDxeYeJXyj0mgA==}
237 |
238 | '@nodelib/fs.scandir@2.1.5':
239 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
240 | engines: {node: '>= 8'}
241 |
242 | '@nodelib/fs.stat@2.0.5':
243 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
244 | engines: {node: '>= 8'}
245 |
246 | '@nodelib/fs.walk@1.2.8':
247 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
248 | engines: {node: '>= 8'}
249 |
250 | '@pkgjs/parseargs@0.11.0':
251 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
252 | engines: {node: '>=14'}
253 |
254 | '@playwright/test@1.52.0':
255 | resolution: {integrity: sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==}
256 | engines: {node: '>=18'}
257 | hasBin: true
258 |
259 | '@rollup/pluginutils@5.1.4':
260 | resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==}
261 | engines: {node: '>=14.0.0'}
262 | peerDependencies:
263 | rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
264 | peerDependenciesMeta:
265 | rollup:
266 | optional: true
267 |
268 | '@rsbuild/core@1.3.22':
269 | resolution: {integrity: sha512-FGB7m8Tn/uiOhvqk0lw+NRMyD+VYJ+eBqVfpn0X11spkJDiPWn8UkMRvfzCX4XFcNZwRKYuuKJaZK1DNU8UG+w==}
270 | engines: {node: '>=16.10.0'}
271 | hasBin: true
272 |
273 | '@rsbuild/core@1.4.0-beta.1':
274 | resolution: {integrity: sha512-kE78UEmnxtIn/oy8Y37VKF33cqVhEmns+jvZ+42rGjqfCfNC38+B/jU6g2D/WumE6OzyCUfgxqyuN3/HZVzLoA==}
275 | engines: {node: '>=16.10.0'}
276 | hasBin: true
277 |
278 | '@rsbuild/webpack@1.3.2':
279 | resolution: {integrity: sha512-ecpZDyKLunUkEM5Yg6UVCONJFHD4+qY5Vtci8t2BRZneQgwZiYrENz+RKYN7NBir6+7nHy3pYMVPU5WJAkGPSA==}
280 | peerDependencies:
281 | '@rsbuild/core': ^1.3.21
282 |
283 | '@rslib/core@0.9.1':
284 | resolution: {integrity: sha512-aa/LXYxr49lCNm/b0B4CQoTB5286MPglGsE5/YFoY0VwIcKJdMz0zBJ4DsPwh27/fcfDQvmN1+J9tzjt9TxQtQ==}
285 | engines: {node: '>=16.7.0'}
286 | hasBin: true
287 | peerDependencies:
288 | '@microsoft/api-extractor': ^7
289 | typescript: ^5
290 | peerDependenciesMeta:
291 | '@microsoft/api-extractor':
292 | optional: true
293 | typescript:
294 | optional: true
295 |
296 | '@rspack/binding-darwin-arm64@1.3.12':
297 | resolution: {integrity: sha512-8hKjVTBeWPqkMzFPNWIh72oU9O3vFy3e88wRjMPImDCXBiEYrKqGTTLd/J0SO+efdL3SBD1rX1IvdJpxCv6Yrw==}
298 | cpu: [arm64]
299 | os: [darwin]
300 |
301 | '@rspack/binding-darwin-arm64@1.3.13':
302 | resolution: {integrity: sha512-1c+KC+TFaKRWu+SO4cJZ5oHKOFuDhTIitbSIG9boJpDRoZmJxHDmFyTTxVI2r2QUjxJaDdUlSFepybhhJ3UiPg==}
303 | cpu: [arm64]
304 | os: [darwin]
305 |
306 | '@rspack/binding-darwin-x64@1.3.12':
307 | resolution: {integrity: sha512-Sj4m+mCUxL7oCpdu7OmWT7fpBM7hywk5CM9RDc3D7StaBZbvNtNftafCrTZzTYKuZrKmemTh5SFzT5Tz7tf6GA==}
308 | cpu: [x64]
309 | os: [darwin]
310 |
311 | '@rspack/binding-darwin-x64@1.3.13':
312 | resolution: {integrity: sha512-YBF+XjoGSjhJ5o/xOaCBd39BntMudMeup11j2Dz+rrTH+wG6TvH017HYIgDMT3UBVv66eNsQpzA0ZW5raJ0lbA==}
313 | cpu: [x64]
314 | os: [darwin]
315 |
316 | '@rspack/binding-linux-arm64-gnu@1.3.12':
317 | resolution: {integrity: sha512-7MuOxf3/Mhv4mgFdLTvgnt/J+VouNR65DEhorth+RZm3LEWojgoFEphSAMAvpvAOpYSS68Sw4SqsOZi719ia2w==}
318 | cpu: [arm64]
319 | os: [linux]
320 |
321 | '@rspack/binding-linux-arm64-gnu@1.3.13':
322 | resolution: {integrity: sha512-II71Ez7Z0/5ZpcK+kCgvXFKK0AysS9La8LNQbqf2wmzxDJi5H8eVUiwkM5BabICxzOWYtTGJLZ89QbCYaFbqCg==}
323 | cpu: [arm64]
324 | os: [linux]
325 |
326 | '@rspack/binding-linux-arm64-musl@1.3.12':
327 | resolution: {integrity: sha512-s6KKj20T9Z1bA8caIjU6EzJbwyDo1URNFgBAlafCT2UC6yX7flstDJJ38CxZacA9A2P24RuQK2/jPSZpWrTUFA==}
328 | cpu: [arm64]
329 | os: [linux]
330 |
331 | '@rspack/binding-linux-arm64-musl@1.3.13':
332 | resolution: {integrity: sha512-JFFhqglKVjlWcmmVwdS80Kw6v35yY9xlQJup09mL8gMtiiFiT36wTyTujz15Iv+2+S/Dv0Z+UeUJ99KRbQxgcQ==}
333 | cpu: [arm64]
334 | os: [linux]
335 |
336 | '@rspack/binding-linux-x64-gnu@1.3.12':
337 | resolution: {integrity: sha512-0w/sRREYbRgHgWvs2uMEJSLfvzbZkPHUg6CMcYQGNVK6axYRot6jPyKetyFYA9pR5fB5rsXegpnFaZaVrRIK2g==}
338 | cpu: [x64]
339 | os: [linux]
340 |
341 | '@rspack/binding-linux-x64-gnu@1.3.13':
342 | resolution: {integrity: sha512-ogm4rt+PMQHkMg/0mA9VTjfGE3c+YaHZQT8KrFgTsoj2YCW9WO2J/RjdMc6STG4Y10BWO9Ar2azLxxHrKb+8UQ==}
343 | cpu: [x64]
344 | os: [linux]
345 |
346 | '@rspack/binding-linux-x64-musl@1.3.12':
347 | resolution: {integrity: sha512-jEdxkPymkRxbijDRsBGdhopcbGXiXDg59lXqIRkVklqbDmZ/O6DHm7gImmlx5q9FoWbz0gqJuOKBz4JqWxjWVA==}
348 | cpu: [x64]
349 | os: [linux]
350 |
351 | '@rspack/binding-linux-x64-musl@1.3.13':
352 | resolution: {integrity: sha512-8icDyXhg1iMKhQ3X2FTgAGQTQqnli9FyqHCuRIBauxy1V4W478Mp9Y+V+ErVUY1YxbZEUrkt3a59hssjGeDEeg==}
353 | cpu: [x64]
354 | os: [linux]
355 |
356 | '@rspack/binding-win32-arm64-msvc@1.3.12':
357 | resolution: {integrity: sha512-ZRvUCb3TDLClAqcTsl/o9UdJf0B5CgzAxgdbnYJbldyuyMeTUB4jp20OfG55M3C2Nute2SNhu2bOOp9Se5Ongw==}
358 | cpu: [arm64]
359 | os: [win32]
360 |
361 | '@rspack/binding-win32-arm64-msvc@1.3.13':
362 | resolution: {integrity: sha512-y5XxwxDW4DrPKy+8P6t7I7IbA7B/iXjLoaS0jP/EwjSHWf/EnZzq9MgWqdop1km8Mwx6s1zcj+0qs73jL2N98w==}
363 | cpu: [arm64]
364 | os: [win32]
365 |
366 | '@rspack/binding-win32-ia32-msvc@1.3.12':
367 | resolution: {integrity: sha512-1TKPjuXStPJr14f3ZHuv40Xc/87jUXx10pzVtrPnw+f3hckECHrbYU/fvbVzZyuXbsXtkXpYca6ygCDRJAoNeQ==}
368 | cpu: [ia32]
369 | os: [win32]
370 |
371 | '@rspack/binding-win32-ia32-msvc@1.3.13':
372 | resolution: {integrity: sha512-n24sznsZe3lC8ok6MgsT1nG4lVx3SQ/lZ0g23i2BGMRN8/p+kaC2eoPaHe/4m9Liz/W4Z5LhZCCvg4DQMEzeLA==}
373 | cpu: [ia32]
374 | os: [win32]
375 |
376 | '@rspack/binding-win32-x64-msvc@1.3.12':
377 | resolution: {integrity: sha512-lCR0JfnYKpV+a6r2A2FdxyUKUS4tajePgpPJN5uXDgMGwrDtRqvx+d0BHhwjFudQVJq9VVbRaL89s2MQ6u+xYw==}
378 | cpu: [x64]
379 | os: [win32]
380 |
381 | '@rspack/binding-win32-x64-msvc@1.3.13':
382 | resolution: {integrity: sha512-CLyTNo0OrOD7xFKusFciKKG+8CXPowjPz+tcdkkrKYqGzAPzOcszblikITJhMbc7DLMzdTRSZUTkKLRydYH9sw==}
383 | cpu: [x64]
384 | os: [win32]
385 |
386 | '@rspack/binding@1.3.12':
387 | resolution: {integrity: sha512-4Ic8lV0+LCBfTlH5aIOujIRWZOtgmG223zC4L3o8WY/+ESAgpdnK6lSSMfcYgRanYLAy3HOmFIp20jwskMpbAg==}
388 |
389 | '@rspack/binding@1.3.13':
390 | resolution: {integrity: sha512-BdM6tfLCP7/0H5uGc+okG6AYsU9JEnR5bRHq4YuGaS4tb+N5ct0czm0LprGMZ7zRAnIql/zoLn/bHlheNxZw3g==}
391 |
392 | '@rspack/core@1.3.12':
393 | resolution: {integrity: sha512-mAPmV4LPPRgxpouUrGmAE4kpF1NEWJGyM5coebsjK/zaCMSjw3mkdxiU2b5cO44oIi0Ifv5iGkvwbdrZOvMyFA==}
394 | engines: {node: '>=16.0.0'}
395 | peerDependencies:
396 | '@swc/helpers': '>=0.5.1'
397 | peerDependenciesMeta:
398 | '@swc/helpers':
399 | optional: true
400 |
401 | '@rspack/core@1.3.13':
402 | resolution: {integrity: sha512-j9jsNzKeEN14yraqX4jAFrM/nMfX5YEPgEMPlp4g5NAu3siaBa8gDF5brbdNq6TDXnTHK1MwwjaMdKA+3YeBKQ==}
403 | engines: {node: '>=16.0.0'}
404 | peerDependencies:
405 | '@swc/helpers': '>=0.5.1'
406 | peerDependenciesMeta:
407 | '@swc/helpers':
408 | optional: true
409 |
410 | '@rspack/lite-tapable@1.0.1':
411 | resolution: {integrity: sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==}
412 | engines: {node: '>=16.0.0'}
413 |
414 | '@swc/helpers@0.5.17':
415 | resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
416 |
417 | '@types/eslint-scope@3.7.7':
418 | resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
419 |
420 | '@types/eslint@9.6.1':
421 | resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==}
422 |
423 | '@types/estree@1.0.6':
424 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
425 |
426 | '@types/html-minifier-terser@6.1.0':
427 | resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==}
428 |
429 | '@types/json-schema@7.0.15':
430 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
431 |
432 | '@types/node@22.15.29':
433 | resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==}
434 |
435 | '@types/semver@7.7.0':
436 | resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==}
437 |
438 | '@webassemblyjs/ast@1.14.1':
439 | resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
440 |
441 | '@webassemblyjs/floating-point-hex-parser@1.13.2':
442 | resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==}
443 |
444 | '@webassemblyjs/helper-api-error@1.13.2':
445 | resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==}
446 |
447 | '@webassemblyjs/helper-buffer@1.14.1':
448 | resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==}
449 |
450 | '@webassemblyjs/helper-numbers@1.13.2':
451 | resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==}
452 |
453 | '@webassemblyjs/helper-wasm-bytecode@1.13.2':
454 | resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==}
455 |
456 | '@webassemblyjs/helper-wasm-section@1.14.1':
457 | resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==}
458 |
459 | '@webassemblyjs/ieee754@1.13.2':
460 | resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==}
461 |
462 | '@webassemblyjs/leb128@1.13.2':
463 | resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==}
464 |
465 | '@webassemblyjs/utf8@1.13.2':
466 | resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==}
467 |
468 | '@webassemblyjs/wasm-edit@1.14.1':
469 | resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==}
470 |
471 | '@webassemblyjs/wasm-gen@1.14.1':
472 | resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==}
473 |
474 | '@webassemblyjs/wasm-opt@1.14.1':
475 | resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==}
476 |
477 | '@webassemblyjs/wasm-parser@1.14.1':
478 | resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==}
479 |
480 | '@webassemblyjs/wast-printer@1.14.1':
481 | resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
482 |
483 | '@xtuc/ieee754@1.2.0':
484 | resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
485 |
486 | '@xtuc/long@4.2.2':
487 | resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
488 |
489 | acorn@8.14.0:
490 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
491 | engines: {node: '>=0.4.0'}
492 | hasBin: true
493 |
494 | ajv-formats@2.1.1:
495 | resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
496 | peerDependencies:
497 | ajv: ^8.0.0
498 | peerDependenciesMeta:
499 | ajv:
500 | optional: true
501 |
502 | ajv-keywords@5.1.0:
503 | resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
504 | peerDependencies:
505 | ajv: ^8.8.2
506 |
507 | ajv@8.17.1:
508 | resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
509 |
510 | ansi-regex@5.0.1:
511 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
512 | engines: {node: '>=8'}
513 |
514 | ansi-regex@6.1.0:
515 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
516 | engines: {node: '>=12'}
517 |
518 | ansi-styles@4.3.0:
519 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
520 | engines: {node: '>=8'}
521 |
522 | ansi-styles@6.2.1:
523 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
524 | engines: {node: '>=12'}
525 |
526 | any-promise@1.3.0:
527 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
528 |
529 | anymatch@3.1.3:
530 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
531 | engines: {node: '>= 8'}
532 |
533 | arg@5.0.2:
534 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
535 |
536 | balanced-match@1.0.2:
537 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
538 |
539 | binary-extensions@2.3.0:
540 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
541 | engines: {node: '>=8'}
542 |
543 | boolbase@1.0.0:
544 | resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
545 |
546 | brace-expansion@2.0.1:
547 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
548 |
549 | braces@3.0.3:
550 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
551 | engines: {node: '>=8'}
552 |
553 | browserslist@4.24.2:
554 | resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
555 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
556 | hasBin: true
557 |
558 | buffer-from@1.1.2:
559 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
560 |
561 | camel-case@4.1.2:
562 | resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
563 |
564 | camelcase-css@2.0.1:
565 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
566 | engines: {node: '>= 6'}
567 |
568 | caniuse-lite@1.0.30001716:
569 | resolution: {integrity: sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==}
570 |
571 | caniuse-lite@1.0.30001721:
572 | resolution: {integrity: sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==}
573 |
574 | chalk@4.1.2:
575 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
576 | engines: {node: '>=10'}
577 |
578 | chokidar@3.6.0:
579 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
580 | engines: {node: '>= 8.10.0'}
581 |
582 | chrome-trace-event@1.0.4:
583 | resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
584 | engines: {node: '>=6.0'}
585 |
586 | clean-css@5.3.3:
587 | resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
588 | engines: {node: '>= 10.0'}
589 |
590 | color-convert@2.0.1:
591 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
592 | engines: {node: '>=7.0.0'}
593 |
594 | color-name@1.1.4:
595 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
596 |
597 | commander@2.20.3:
598 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
599 |
600 | commander@4.1.1:
601 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
602 | engines: {node: '>= 6'}
603 |
604 | commander@8.3.0:
605 | resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
606 | engines: {node: '>= 12'}
607 |
608 | copy-webpack-plugin@11.0.0:
609 | resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==}
610 | engines: {node: '>= 14.15.0'}
611 | peerDependencies:
612 | webpack: ^5.1.0
613 |
614 | core-js@3.42.0:
615 | resolution: {integrity: sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==}
616 |
617 | cross-spawn@7.0.6:
618 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
619 | engines: {node: '>= 8'}
620 |
621 | css-select@4.3.0:
622 | resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
623 |
624 | css-what@6.1.0:
625 | resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
626 | engines: {node: '>= 6'}
627 |
628 | cssesc@3.0.0:
629 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
630 | engines: {node: '>=4'}
631 | hasBin: true
632 |
633 | didyoumean@1.2.2:
634 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
635 |
636 | dir-glob@3.0.1:
637 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
638 | engines: {node: '>=8'}
639 |
640 | dlv@1.1.3:
641 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
642 |
643 | dom-converter@0.2.0:
644 | resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==}
645 |
646 | dom-serializer@1.4.1:
647 | resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
648 |
649 | domelementtype@2.3.0:
650 | resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
651 |
652 | domhandler@4.3.1:
653 | resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
654 | engines: {node: '>= 4'}
655 |
656 | domutils@2.8.0:
657 | resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
658 |
659 | dot-case@3.0.4:
660 | resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
661 |
662 | eastasianwidth@0.2.0:
663 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
664 |
665 | electron-to-chromium@1.5.67:
666 | resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==}
667 |
668 | emoji-regex@8.0.0:
669 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
670 |
671 | emoji-regex@9.2.2:
672 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
673 |
674 | enhanced-resolve@5.17.1:
675 | resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==}
676 | engines: {node: '>=10.13.0'}
677 |
678 | entities@2.2.0:
679 | resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
680 |
681 | es-module-lexer@1.5.4:
682 | resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
683 |
684 | escalade@3.2.0:
685 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
686 | engines: {node: '>=6'}
687 |
688 | eslint-scope@5.1.1:
689 | resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
690 | engines: {node: '>=8.0.0'}
691 |
692 | esrecurse@4.3.0:
693 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
694 | engines: {node: '>=4.0'}
695 |
696 | estraverse@4.3.0:
697 | resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
698 | engines: {node: '>=4.0'}
699 |
700 | estraverse@5.3.0:
701 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
702 | engines: {node: '>=4.0'}
703 |
704 | estree-walker@2.0.2:
705 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
706 |
707 | events@3.3.0:
708 | resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
709 | engines: {node: '>=0.8.x'}
710 |
711 | fast-deep-equal@3.1.3:
712 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
713 |
714 | fast-glob@3.3.2:
715 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
716 | engines: {node: '>=8.6.0'}
717 |
718 | fast-uri@3.0.3:
719 | resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==}
720 |
721 | fastq@1.17.1:
722 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
723 |
724 | fdir@6.4.4:
725 | resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
726 | peerDependencies:
727 | picomatch: ^3 || ^4
728 | peerDependenciesMeta:
729 | picomatch:
730 | optional: true
731 |
732 | fill-range@7.1.1:
733 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
734 | engines: {node: '>=8'}
735 |
736 | foreground-child@3.3.0:
737 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
738 | engines: {node: '>=14'}
739 |
740 | fsevents@2.3.2:
741 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
742 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
743 | os: [darwin]
744 |
745 | fsevents@2.3.3:
746 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
747 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
748 | os: [darwin]
749 |
750 | function-bind@1.1.2:
751 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
752 |
753 | glob-parent@5.1.2:
754 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
755 | engines: {node: '>= 6'}
756 |
757 | glob-parent@6.0.2:
758 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
759 | engines: {node: '>=10.13.0'}
760 |
761 | glob-to-regexp@0.4.1:
762 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
763 |
764 | glob@10.4.5:
765 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
766 | hasBin: true
767 |
768 | globby@13.2.2:
769 | resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
770 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
771 |
772 | graceful-fs@4.2.11:
773 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
774 |
775 | has-flag@4.0.0:
776 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
777 | engines: {node: '>=8'}
778 |
779 | hasown@2.0.2:
780 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
781 | engines: {node: '>= 0.4'}
782 |
783 | he@1.2.0:
784 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
785 | hasBin: true
786 |
787 | html-minifier-terser@6.1.0:
788 | resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==}
789 | engines: {node: '>=12'}
790 | hasBin: true
791 |
792 | html-webpack-plugin@5.6.3:
793 | resolution: {integrity: sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==}
794 | engines: {node: '>=10.13.0'}
795 | peerDependencies:
796 | '@rspack/core': 0.x || 1.x
797 | webpack: ^5.20.0
798 | peerDependenciesMeta:
799 | '@rspack/core':
800 | optional: true
801 | webpack:
802 | optional: true
803 |
804 | htmlparser2@6.1.0:
805 | resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
806 |
807 | ignore@5.3.2:
808 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
809 | engines: {node: '>= 4'}
810 |
811 | is-binary-path@2.1.0:
812 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
813 | engines: {node: '>=8'}
814 |
815 | is-core-module@2.15.1:
816 | resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
817 | engines: {node: '>= 0.4'}
818 |
819 | is-extglob@2.1.1:
820 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
821 | engines: {node: '>=0.10.0'}
822 |
823 | is-fullwidth-code-point@3.0.0:
824 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
825 | engines: {node: '>=8'}
826 |
827 | is-glob@4.0.3:
828 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
829 | engines: {node: '>=0.10.0'}
830 |
831 | is-number@7.0.0:
832 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
833 | engines: {node: '>=0.12.0'}
834 |
835 | isexe@2.0.0:
836 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
837 |
838 | jackspeak@3.4.3:
839 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
840 |
841 | jest-worker@27.5.1:
842 | resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
843 | engines: {node: '>= 10.13.0'}
844 |
845 | jiti@1.21.6:
846 | resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
847 | hasBin: true
848 |
849 | jiti@2.4.2:
850 | resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
851 | hasBin: true
852 |
853 | json-parse-even-better-errors@2.3.1:
854 | resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
855 |
856 | json-schema-traverse@1.0.0:
857 | resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
858 |
859 | json5@2.2.3:
860 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
861 | engines: {node: '>=6'}
862 | hasBin: true
863 |
864 | lilconfig@3.1.3:
865 | resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
866 | engines: {node: '>=14'}
867 |
868 | lines-and-columns@1.2.4:
869 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
870 |
871 | loader-runner@4.3.0:
872 | resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
873 | engines: {node: '>=6.11.5'}
874 |
875 | lodash@4.17.21:
876 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
877 |
878 | lower-case@2.0.2:
879 | resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
880 |
881 | lru-cache@10.4.3:
882 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
883 |
884 | magic-string@0.30.17:
885 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
886 |
887 | merge-stream@2.0.0:
888 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
889 |
890 | merge2@1.4.1:
891 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
892 | engines: {node: '>= 8'}
893 |
894 | micromatch@4.0.8:
895 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
896 | engines: {node: '>=8.6'}
897 |
898 | mime-db@1.52.0:
899 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
900 | engines: {node: '>= 0.6'}
901 |
902 | mime-types@2.1.35:
903 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
904 | engines: {node: '>= 0.6'}
905 |
906 | mini-css-extract-plugin@2.9.2:
907 | resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==}
908 | engines: {node: '>= 12.13.0'}
909 | peerDependencies:
910 | webpack: ^5.0.0
911 |
912 | minimatch@9.0.5:
913 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
914 | engines: {node: '>=16 || 14 >=14.17'}
915 |
916 | minimist@1.2.8:
917 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
918 |
919 | minipass@7.1.2:
920 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
921 | engines: {node: '>=16 || 14 >=14.17'}
922 |
923 | mz@2.7.0:
924 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
925 |
926 | nanoid@3.3.11:
927 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
928 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
929 | hasBin: true
930 |
931 | neo-async@2.6.2:
932 | resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
933 |
934 | no-case@3.0.4:
935 | resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
936 |
937 | node-releases@2.0.18:
938 | resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
939 |
940 | normalize-path@3.0.0:
941 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
942 | engines: {node: '>=0.10.0'}
943 |
944 | nth-check@2.1.1:
945 | resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
946 |
947 | object-assign@4.1.1:
948 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
949 | engines: {node: '>=0.10.0'}
950 |
951 | object-hash@3.0.0:
952 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
953 | engines: {node: '>= 6'}
954 |
955 | package-json-from-dist@1.0.1:
956 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
957 |
958 | param-case@3.0.4:
959 | resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
960 |
961 | pascal-case@3.1.2:
962 | resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
963 |
964 | path-key@3.1.1:
965 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
966 | engines: {node: '>=8'}
967 |
968 | path-parse@1.0.7:
969 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
970 |
971 | path-scurry@1.11.1:
972 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
973 | engines: {node: '>=16 || 14 >=14.18'}
974 |
975 | path-type@4.0.0:
976 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
977 | engines: {node: '>=8'}
978 |
979 | picocolors@1.1.1:
980 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
981 |
982 | picomatch@2.3.1:
983 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
984 | engines: {node: '>=8.6'}
985 |
986 | picomatch@4.0.2:
987 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
988 | engines: {node: '>=12'}
989 |
990 | pify@2.3.0:
991 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
992 | engines: {node: '>=0.10.0'}
993 |
994 | pirates@4.0.6:
995 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
996 | engines: {node: '>= 6'}
997 |
998 | playwright-core@1.52.0:
999 | resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==}
1000 | engines: {node: '>=18'}
1001 | hasBin: true
1002 |
1003 | playwright@1.52.0:
1004 | resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==}
1005 | engines: {node: '>=18'}
1006 | hasBin: true
1007 |
1008 | postcss-import@15.1.0:
1009 | resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
1010 | engines: {node: '>=14.0.0'}
1011 | peerDependencies:
1012 | postcss: ^8.0.0
1013 |
1014 | postcss-js@4.0.1:
1015 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
1016 | engines: {node: ^12 || ^14 || >= 16}
1017 | peerDependencies:
1018 | postcss: ^8.4.21
1019 |
1020 | postcss-load-config@4.0.2:
1021 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
1022 | engines: {node: '>= 14'}
1023 | peerDependencies:
1024 | postcss: '>=8.0.9'
1025 | ts-node: '>=9.0.0'
1026 | peerDependenciesMeta:
1027 | postcss:
1028 | optional: true
1029 | ts-node:
1030 | optional: true
1031 |
1032 | postcss-nested@6.2.0:
1033 | resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
1034 | engines: {node: '>=12.0'}
1035 | peerDependencies:
1036 | postcss: ^8.2.14
1037 |
1038 | postcss-selector-parser@6.1.2:
1039 | resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
1040 | engines: {node: '>=4'}
1041 |
1042 | postcss-value-parser@4.2.0:
1043 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1044 |
1045 | postcss@8.5.4:
1046 | resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
1047 | engines: {node: ^10 || ^12 || >=14}
1048 |
1049 | pretty-error@4.0.0:
1050 | resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==}
1051 |
1052 | queue-microtask@1.2.3:
1053 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1054 |
1055 | randombytes@2.1.0:
1056 | resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
1057 |
1058 | read-cache@1.0.0:
1059 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
1060 |
1061 | readdirp@3.6.0:
1062 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
1063 | engines: {node: '>=8.10.0'}
1064 |
1065 | reduce-configs@1.1.0:
1066 | resolution: {integrity: sha512-DQxy6liNadHfrLahZR7lMdc227NYVaQZhY5FMsxLEjX8X0SCuH+ESHSLCoz2yDZFq1/CLMDOAHdsEHwOEXKtvg==}
1067 |
1068 | relateurl@0.2.7:
1069 | resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
1070 | engines: {node: '>= 0.10'}
1071 |
1072 | renderkid@3.0.0:
1073 | resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==}
1074 |
1075 | require-from-string@2.0.2:
1076 | resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
1077 | engines: {node: '>=0.10.0'}
1078 |
1079 | resolve@1.22.8:
1080 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
1081 | hasBin: true
1082 |
1083 | reusify@1.0.4:
1084 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1085 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1086 |
1087 | rsbuild-plugin-dts@0.9.1:
1088 | resolution: {integrity: sha512-04pkKrebuajsCpC8Vj2z4n6NFFxUYAdUdqSQRFGkGhdmururoDFYW0k9+ZQq9XrSQTlB01F/HFv5mAc0dwG/Qg==}
1089 | engines: {node: '>=16.7.0'}
1090 | peerDependencies:
1091 | '@microsoft/api-extractor': ^7
1092 | '@rsbuild/core': 1.x
1093 | typescript: ^5
1094 | peerDependenciesMeta:
1095 | '@microsoft/api-extractor':
1096 | optional: true
1097 | typescript:
1098 | optional: true
1099 |
1100 | run-parallel@1.2.0:
1101 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1102 |
1103 | safe-buffer@5.2.1:
1104 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1105 |
1106 | schema-utils@4.3.0:
1107 | resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==}
1108 | engines: {node: '>= 10.13.0'}
1109 |
1110 | schema-utils@4.3.2:
1111 | resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==}
1112 | engines: {node: '>= 10.13.0'}
1113 |
1114 | semver@7.7.2:
1115 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
1116 | engines: {node: '>=10'}
1117 | hasBin: true
1118 |
1119 | serialize-javascript@6.0.2:
1120 | resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
1121 |
1122 | shebang-command@2.0.0:
1123 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1124 | engines: {node: '>=8'}
1125 |
1126 | shebang-regex@3.0.0:
1127 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1128 | engines: {node: '>=8'}
1129 |
1130 | signal-exit@4.1.0:
1131 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1132 | engines: {node: '>=14'}
1133 |
1134 | simple-git-hooks@2.13.0:
1135 | resolution: {integrity: sha512-N+goiLxlkHJlyaYEglFypzVNMaNplPAk5syu0+OPp/Bk6dwVoXF6FfOw2vO0Dp+JHsBaI+w6cm8TnFl2Hw6tDA==}
1136 | hasBin: true
1137 |
1138 | slash@4.0.0:
1139 | resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
1140 | engines: {node: '>=12'}
1141 |
1142 | source-map-js@1.2.1:
1143 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1144 | engines: {node: '>=0.10.0'}
1145 |
1146 | source-map-support@0.5.21:
1147 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
1148 |
1149 | source-map@0.6.1:
1150 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1151 | engines: {node: '>=0.10.0'}
1152 |
1153 | string-width@4.2.3:
1154 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1155 | engines: {node: '>=8'}
1156 |
1157 | string-width@5.1.2:
1158 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
1159 | engines: {node: '>=12'}
1160 |
1161 | strip-ansi@6.0.1:
1162 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1163 | engines: {node: '>=8'}
1164 |
1165 | strip-ansi@7.1.0:
1166 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
1167 | engines: {node: '>=12'}
1168 |
1169 | strip-bom@3.0.0:
1170 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
1171 | engines: {node: '>=4'}
1172 |
1173 | sucrase@3.35.0:
1174 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
1175 | engines: {node: '>=16 || 14 >=14.17'}
1176 | hasBin: true
1177 |
1178 | supports-color@7.2.0:
1179 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
1180 | engines: {node: '>=8'}
1181 |
1182 | supports-color@8.1.1:
1183 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
1184 | engines: {node: '>=10'}
1185 |
1186 | supports-preserve-symlinks-flag@1.0.0:
1187 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1188 | engines: {node: '>= 0.4'}
1189 |
1190 | tailwindcss@3.4.17:
1191 | resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
1192 | engines: {node: '>=14.0.0'}
1193 | hasBin: true
1194 |
1195 | tapable@2.2.1:
1196 | resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
1197 | engines: {node: '>=6'}
1198 |
1199 | terser-webpack-plugin@5.3.12:
1200 | resolution: {integrity: sha512-jDLYqo7oF8tJIttjXO6jBY5Hk8p3A8W4ttih7cCEq64fQFWmgJ4VqAQjKr7WwIDlmXKEc6QeoRb5ecjZ+2afcg==}
1201 | engines: {node: '>= 10.13.0'}
1202 | peerDependencies:
1203 | '@swc/core': '*'
1204 | esbuild: '*'
1205 | uglify-js: '*'
1206 | webpack: ^5.1.0
1207 | peerDependenciesMeta:
1208 | '@swc/core':
1209 | optional: true
1210 | esbuild:
1211 | optional: true
1212 | uglify-js:
1213 | optional: true
1214 |
1215 | terser@5.36.0:
1216 | resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==}
1217 | engines: {node: '>=10'}
1218 | hasBin: true
1219 |
1220 | thenify-all@1.6.0:
1221 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
1222 | engines: {node: '>=0.8'}
1223 |
1224 | thenify@3.3.1:
1225 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
1226 |
1227 | tinyglobby@0.2.14:
1228 | resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
1229 | engines: {node: '>=12.0.0'}
1230 |
1231 | to-regex-range@5.0.1:
1232 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1233 | engines: {node: '>=8.0'}
1234 |
1235 | ts-interface-checker@0.1.13:
1236 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
1237 |
1238 | tsconfig-paths-webpack-plugin@4.2.0:
1239 | resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==}
1240 | engines: {node: '>=10.13.0'}
1241 |
1242 | tsconfig-paths@4.2.0:
1243 | resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
1244 | engines: {node: '>=6'}
1245 |
1246 | tslib@2.8.1:
1247 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1248 |
1249 | typescript@5.8.3:
1250 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
1251 | engines: {node: '>=14.17'}
1252 | hasBin: true
1253 |
1254 | undici-types@6.21.0:
1255 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1256 |
1257 | update-browserslist-db@1.1.1:
1258 | resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
1259 | hasBin: true
1260 | peerDependencies:
1261 | browserslist: '>= 4.21.0'
1262 |
1263 | util-deprecate@1.0.2:
1264 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
1265 |
1266 | utila@0.4.0:
1267 | resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==}
1268 |
1269 | watchpack@2.4.2:
1270 | resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
1271 | engines: {node: '>=10.13.0'}
1272 |
1273 | webpack-sources@3.2.3:
1274 | resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
1275 | engines: {node: '>=10.13.0'}
1276 |
1277 | webpack@5.99.9:
1278 | resolution: {integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==}
1279 | engines: {node: '>=10.13.0'}
1280 | hasBin: true
1281 | peerDependencies:
1282 | webpack-cli: '*'
1283 | peerDependenciesMeta:
1284 | webpack-cli:
1285 | optional: true
1286 |
1287 | which@2.0.2:
1288 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1289 | engines: {node: '>= 8'}
1290 | hasBin: true
1291 |
1292 | wrap-ansi@7.0.0:
1293 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1294 | engines: {node: '>=10'}
1295 |
1296 | wrap-ansi@8.1.0:
1297 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
1298 | engines: {node: '>=12'}
1299 |
1300 | yaml@2.6.1:
1301 | resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
1302 | engines: {node: '>= 14'}
1303 | hasBin: true
1304 |
1305 | snapshots:
1306 |
1307 | '@alloc/quick-lru@5.2.0': {}
1308 |
1309 | '@ast-grep/napi-darwin-arm64@0.37.0':
1310 | optional: true
1311 |
1312 | '@ast-grep/napi-darwin-x64@0.37.0':
1313 | optional: true
1314 |
1315 | '@ast-grep/napi-linux-arm64-gnu@0.37.0':
1316 | optional: true
1317 |
1318 | '@ast-grep/napi-linux-arm64-musl@0.37.0':
1319 | optional: true
1320 |
1321 | '@ast-grep/napi-linux-x64-gnu@0.37.0':
1322 | optional: true
1323 |
1324 | '@ast-grep/napi-linux-x64-musl@0.37.0':
1325 | optional: true
1326 |
1327 | '@ast-grep/napi-win32-arm64-msvc@0.37.0':
1328 | optional: true
1329 |
1330 | '@ast-grep/napi-win32-ia32-msvc@0.37.0':
1331 | optional: true
1332 |
1333 | '@ast-grep/napi-win32-x64-msvc@0.37.0':
1334 | optional: true
1335 |
1336 | '@ast-grep/napi@0.37.0':
1337 | optionalDependencies:
1338 | '@ast-grep/napi-darwin-arm64': 0.37.0
1339 | '@ast-grep/napi-darwin-x64': 0.37.0
1340 | '@ast-grep/napi-linux-arm64-gnu': 0.37.0
1341 | '@ast-grep/napi-linux-arm64-musl': 0.37.0
1342 | '@ast-grep/napi-linux-x64-gnu': 0.37.0
1343 | '@ast-grep/napi-linux-x64-musl': 0.37.0
1344 | '@ast-grep/napi-win32-arm64-msvc': 0.37.0
1345 | '@ast-grep/napi-win32-ia32-msvc': 0.37.0
1346 | '@ast-grep/napi-win32-x64-msvc': 0.37.0
1347 |
1348 | '@biomejs/biome@1.9.4':
1349 | optionalDependencies:
1350 | '@biomejs/cli-darwin-arm64': 1.9.4
1351 | '@biomejs/cli-darwin-x64': 1.9.4
1352 | '@biomejs/cli-linux-arm64': 1.9.4
1353 | '@biomejs/cli-linux-arm64-musl': 1.9.4
1354 | '@biomejs/cli-linux-x64': 1.9.4
1355 | '@biomejs/cli-linux-x64-musl': 1.9.4
1356 | '@biomejs/cli-win32-arm64': 1.9.4
1357 | '@biomejs/cli-win32-x64': 1.9.4
1358 |
1359 | '@biomejs/cli-darwin-arm64@1.9.4':
1360 | optional: true
1361 |
1362 | '@biomejs/cli-darwin-x64@1.9.4':
1363 | optional: true
1364 |
1365 | '@biomejs/cli-linux-arm64-musl@1.9.4':
1366 | optional: true
1367 |
1368 | '@biomejs/cli-linux-arm64@1.9.4':
1369 | optional: true
1370 |
1371 | '@biomejs/cli-linux-x64-musl@1.9.4':
1372 | optional: true
1373 |
1374 | '@biomejs/cli-linux-x64@1.9.4':
1375 | optional: true
1376 |
1377 | '@biomejs/cli-win32-arm64@1.9.4':
1378 | optional: true
1379 |
1380 | '@biomejs/cli-win32-x64@1.9.4':
1381 | optional: true
1382 |
1383 | '@isaacs/cliui@8.0.2':
1384 | dependencies:
1385 | string-width: 5.1.2
1386 | string-width-cjs: string-width@4.2.3
1387 | strip-ansi: 7.1.0
1388 | strip-ansi-cjs: strip-ansi@6.0.1
1389 | wrap-ansi: 8.1.0
1390 | wrap-ansi-cjs: wrap-ansi@7.0.0
1391 |
1392 | '@jridgewell/gen-mapping@0.3.5':
1393 | dependencies:
1394 | '@jridgewell/set-array': 1.2.1
1395 | '@jridgewell/sourcemap-codec': 1.5.0
1396 | '@jridgewell/trace-mapping': 0.3.25
1397 |
1398 | '@jridgewell/resolve-uri@3.1.2': {}
1399 |
1400 | '@jridgewell/set-array@1.2.1': {}
1401 |
1402 | '@jridgewell/source-map@0.3.6':
1403 | dependencies:
1404 | '@jridgewell/gen-mapping': 0.3.5
1405 | '@jridgewell/trace-mapping': 0.3.25
1406 |
1407 | '@jridgewell/sourcemap-codec@1.5.0': {}
1408 |
1409 | '@jridgewell/trace-mapping@0.3.25':
1410 | dependencies:
1411 | '@jridgewell/resolve-uri': 3.1.2
1412 | '@jridgewell/sourcemap-codec': 1.5.0
1413 |
1414 | '@module-federation/error-codes@0.14.0': {}
1415 |
1416 | '@module-federation/error-codes@0.14.3': {}
1417 |
1418 | '@module-federation/runtime-core@0.14.0':
1419 | dependencies:
1420 | '@module-federation/error-codes': 0.14.0
1421 | '@module-federation/sdk': 0.14.0
1422 |
1423 | '@module-federation/runtime-core@0.14.3':
1424 | dependencies:
1425 | '@module-federation/error-codes': 0.14.3
1426 | '@module-federation/sdk': 0.14.3
1427 |
1428 | '@module-federation/runtime-tools@0.14.0':
1429 | dependencies:
1430 | '@module-federation/runtime': 0.14.0
1431 | '@module-federation/webpack-bundler-runtime': 0.14.0
1432 |
1433 | '@module-federation/runtime-tools@0.14.3':
1434 | dependencies:
1435 | '@module-federation/runtime': 0.14.3
1436 | '@module-federation/webpack-bundler-runtime': 0.14.3
1437 |
1438 | '@module-federation/runtime@0.14.0':
1439 | dependencies:
1440 | '@module-federation/error-codes': 0.14.0
1441 | '@module-federation/runtime-core': 0.14.0
1442 | '@module-federation/sdk': 0.14.0
1443 |
1444 | '@module-federation/runtime@0.14.3':
1445 | dependencies:
1446 | '@module-federation/error-codes': 0.14.3
1447 | '@module-federation/runtime-core': 0.14.3
1448 | '@module-federation/sdk': 0.14.3
1449 |
1450 | '@module-federation/sdk@0.14.0': {}
1451 |
1452 | '@module-federation/sdk@0.14.3': {}
1453 |
1454 | '@module-federation/webpack-bundler-runtime@0.14.0':
1455 | dependencies:
1456 | '@module-federation/runtime': 0.14.0
1457 | '@module-federation/sdk': 0.14.0
1458 |
1459 | '@module-federation/webpack-bundler-runtime@0.14.3':
1460 | dependencies:
1461 | '@module-federation/runtime': 0.14.3
1462 | '@module-federation/sdk': 0.14.3
1463 |
1464 | '@nodelib/fs.scandir@2.1.5':
1465 | dependencies:
1466 | '@nodelib/fs.stat': 2.0.5
1467 | run-parallel: 1.2.0
1468 |
1469 | '@nodelib/fs.stat@2.0.5': {}
1470 |
1471 | '@nodelib/fs.walk@1.2.8':
1472 | dependencies:
1473 | '@nodelib/fs.scandir': 2.1.5
1474 | fastq: 1.17.1
1475 |
1476 | '@pkgjs/parseargs@0.11.0':
1477 | optional: true
1478 |
1479 | '@playwright/test@1.52.0':
1480 | dependencies:
1481 | playwright: 1.52.0
1482 |
1483 | '@rollup/pluginutils@5.1.4':
1484 | dependencies:
1485 | '@types/estree': 1.0.6
1486 | estree-walker: 2.0.2
1487 | picomatch: 4.0.2
1488 |
1489 | '@rsbuild/core@1.3.22':
1490 | dependencies:
1491 | '@rspack/core': 1.3.12(@swc/helpers@0.5.17)
1492 | '@rspack/lite-tapable': 1.0.1
1493 | '@swc/helpers': 0.5.17
1494 | core-js: 3.42.0
1495 | jiti: 2.4.2
1496 |
1497 | '@rsbuild/core@1.4.0-beta.1':
1498 | dependencies:
1499 | '@rspack/core': 1.3.13(@swc/helpers@0.5.17)
1500 | '@rspack/lite-tapable': 1.0.1
1501 | '@swc/helpers': 0.5.17
1502 | core-js: 3.42.0
1503 | jiti: 2.4.2
1504 |
1505 | '@rsbuild/webpack@1.3.2(@rsbuild/core@1.4.0-beta.1)(@rspack/core@1.3.13(@swc/helpers@0.5.17))':
1506 | dependencies:
1507 | '@rsbuild/core': 1.4.0-beta.1
1508 | copy-webpack-plugin: 11.0.0(webpack@5.99.9)
1509 | html-webpack-plugin: 5.6.3(@rspack/core@1.3.13(@swc/helpers@0.5.17))(webpack@5.99.9)
1510 | mini-css-extract-plugin: 2.9.2(webpack@5.99.9)
1511 | picocolors: 1.1.1
1512 | reduce-configs: 1.1.0
1513 | tsconfig-paths-webpack-plugin: 4.2.0
1514 | webpack: 5.99.9
1515 | transitivePeerDependencies:
1516 | - '@rspack/core'
1517 | - '@swc/core'
1518 | - esbuild
1519 | - uglify-js
1520 | - webpack-cli
1521 |
1522 | '@rslib/core@0.9.1(typescript@5.8.3)':
1523 | dependencies:
1524 | '@rsbuild/core': 1.3.22
1525 | rsbuild-plugin-dts: 0.9.1(@rsbuild/core@1.3.22)(typescript@5.8.3)
1526 | tinyglobby: 0.2.14
1527 | optionalDependencies:
1528 | typescript: 5.8.3
1529 |
1530 | '@rspack/binding-darwin-arm64@1.3.12':
1531 | optional: true
1532 |
1533 | '@rspack/binding-darwin-arm64@1.3.13':
1534 | optional: true
1535 |
1536 | '@rspack/binding-darwin-x64@1.3.12':
1537 | optional: true
1538 |
1539 | '@rspack/binding-darwin-x64@1.3.13':
1540 | optional: true
1541 |
1542 | '@rspack/binding-linux-arm64-gnu@1.3.12':
1543 | optional: true
1544 |
1545 | '@rspack/binding-linux-arm64-gnu@1.3.13':
1546 | optional: true
1547 |
1548 | '@rspack/binding-linux-arm64-musl@1.3.12':
1549 | optional: true
1550 |
1551 | '@rspack/binding-linux-arm64-musl@1.3.13':
1552 | optional: true
1553 |
1554 | '@rspack/binding-linux-x64-gnu@1.3.12':
1555 | optional: true
1556 |
1557 | '@rspack/binding-linux-x64-gnu@1.3.13':
1558 | optional: true
1559 |
1560 | '@rspack/binding-linux-x64-musl@1.3.12':
1561 | optional: true
1562 |
1563 | '@rspack/binding-linux-x64-musl@1.3.13':
1564 | optional: true
1565 |
1566 | '@rspack/binding-win32-arm64-msvc@1.3.12':
1567 | optional: true
1568 |
1569 | '@rspack/binding-win32-arm64-msvc@1.3.13':
1570 | optional: true
1571 |
1572 | '@rspack/binding-win32-ia32-msvc@1.3.12':
1573 | optional: true
1574 |
1575 | '@rspack/binding-win32-ia32-msvc@1.3.13':
1576 | optional: true
1577 |
1578 | '@rspack/binding-win32-x64-msvc@1.3.12':
1579 | optional: true
1580 |
1581 | '@rspack/binding-win32-x64-msvc@1.3.13':
1582 | optional: true
1583 |
1584 | '@rspack/binding@1.3.12':
1585 | optionalDependencies:
1586 | '@rspack/binding-darwin-arm64': 1.3.12
1587 | '@rspack/binding-darwin-x64': 1.3.12
1588 | '@rspack/binding-linux-arm64-gnu': 1.3.12
1589 | '@rspack/binding-linux-arm64-musl': 1.3.12
1590 | '@rspack/binding-linux-x64-gnu': 1.3.12
1591 | '@rspack/binding-linux-x64-musl': 1.3.12
1592 | '@rspack/binding-win32-arm64-msvc': 1.3.12
1593 | '@rspack/binding-win32-ia32-msvc': 1.3.12
1594 | '@rspack/binding-win32-x64-msvc': 1.3.12
1595 |
1596 | '@rspack/binding@1.3.13':
1597 | optionalDependencies:
1598 | '@rspack/binding-darwin-arm64': 1.3.13
1599 | '@rspack/binding-darwin-x64': 1.3.13
1600 | '@rspack/binding-linux-arm64-gnu': 1.3.13
1601 | '@rspack/binding-linux-arm64-musl': 1.3.13
1602 | '@rspack/binding-linux-x64-gnu': 1.3.13
1603 | '@rspack/binding-linux-x64-musl': 1.3.13
1604 | '@rspack/binding-win32-arm64-msvc': 1.3.13
1605 | '@rspack/binding-win32-ia32-msvc': 1.3.13
1606 | '@rspack/binding-win32-x64-msvc': 1.3.13
1607 |
1608 | '@rspack/core@1.3.12(@swc/helpers@0.5.17)':
1609 | dependencies:
1610 | '@module-federation/runtime-tools': 0.14.0
1611 | '@rspack/binding': 1.3.12
1612 | '@rspack/lite-tapable': 1.0.1
1613 | caniuse-lite: 1.0.30001721
1614 | optionalDependencies:
1615 | '@swc/helpers': 0.5.17
1616 |
1617 | '@rspack/core@1.3.13(@swc/helpers@0.5.17)':
1618 | dependencies:
1619 | '@module-federation/runtime-tools': 0.14.3
1620 | '@rspack/binding': 1.3.13
1621 | '@rspack/lite-tapable': 1.0.1
1622 | optionalDependencies:
1623 | '@swc/helpers': 0.5.17
1624 |
1625 | '@rspack/lite-tapable@1.0.1': {}
1626 |
1627 | '@swc/helpers@0.5.17':
1628 | dependencies:
1629 | tslib: 2.8.1
1630 |
1631 | '@types/eslint-scope@3.7.7':
1632 | dependencies:
1633 | '@types/eslint': 9.6.1
1634 | '@types/estree': 1.0.6
1635 |
1636 | '@types/eslint@9.6.1':
1637 | dependencies:
1638 | '@types/estree': 1.0.6
1639 | '@types/json-schema': 7.0.15
1640 |
1641 | '@types/estree@1.0.6': {}
1642 |
1643 | '@types/html-minifier-terser@6.1.0': {}
1644 |
1645 | '@types/json-schema@7.0.15': {}
1646 |
1647 | '@types/node@22.15.29':
1648 | dependencies:
1649 | undici-types: 6.21.0
1650 |
1651 | '@types/semver@7.7.0': {}
1652 |
1653 | '@webassemblyjs/ast@1.14.1':
1654 | dependencies:
1655 | '@webassemblyjs/helper-numbers': 1.13.2
1656 | '@webassemblyjs/helper-wasm-bytecode': 1.13.2
1657 |
1658 | '@webassemblyjs/floating-point-hex-parser@1.13.2': {}
1659 |
1660 | '@webassemblyjs/helper-api-error@1.13.2': {}
1661 |
1662 | '@webassemblyjs/helper-buffer@1.14.1': {}
1663 |
1664 | '@webassemblyjs/helper-numbers@1.13.2':
1665 | dependencies:
1666 | '@webassemblyjs/floating-point-hex-parser': 1.13.2
1667 | '@webassemblyjs/helper-api-error': 1.13.2
1668 | '@xtuc/long': 4.2.2
1669 |
1670 | '@webassemblyjs/helper-wasm-bytecode@1.13.2': {}
1671 |
1672 | '@webassemblyjs/helper-wasm-section@1.14.1':
1673 | dependencies:
1674 | '@webassemblyjs/ast': 1.14.1
1675 | '@webassemblyjs/helper-buffer': 1.14.1
1676 | '@webassemblyjs/helper-wasm-bytecode': 1.13.2
1677 | '@webassemblyjs/wasm-gen': 1.14.1
1678 |
1679 | '@webassemblyjs/ieee754@1.13.2':
1680 | dependencies:
1681 | '@xtuc/ieee754': 1.2.0
1682 |
1683 | '@webassemblyjs/leb128@1.13.2':
1684 | dependencies:
1685 | '@xtuc/long': 4.2.2
1686 |
1687 | '@webassemblyjs/utf8@1.13.2': {}
1688 |
1689 | '@webassemblyjs/wasm-edit@1.14.1':
1690 | dependencies:
1691 | '@webassemblyjs/ast': 1.14.1
1692 | '@webassemblyjs/helper-buffer': 1.14.1
1693 | '@webassemblyjs/helper-wasm-bytecode': 1.13.2
1694 | '@webassemblyjs/helper-wasm-section': 1.14.1
1695 | '@webassemblyjs/wasm-gen': 1.14.1
1696 | '@webassemblyjs/wasm-opt': 1.14.1
1697 | '@webassemblyjs/wasm-parser': 1.14.1
1698 | '@webassemblyjs/wast-printer': 1.14.1
1699 |
1700 | '@webassemblyjs/wasm-gen@1.14.1':
1701 | dependencies:
1702 | '@webassemblyjs/ast': 1.14.1
1703 | '@webassemblyjs/helper-wasm-bytecode': 1.13.2
1704 | '@webassemblyjs/ieee754': 1.13.2
1705 | '@webassemblyjs/leb128': 1.13.2
1706 | '@webassemblyjs/utf8': 1.13.2
1707 |
1708 | '@webassemblyjs/wasm-opt@1.14.1':
1709 | dependencies:
1710 | '@webassemblyjs/ast': 1.14.1
1711 | '@webassemblyjs/helper-buffer': 1.14.1
1712 | '@webassemblyjs/wasm-gen': 1.14.1
1713 | '@webassemblyjs/wasm-parser': 1.14.1
1714 |
1715 | '@webassemblyjs/wasm-parser@1.14.1':
1716 | dependencies:
1717 | '@webassemblyjs/ast': 1.14.1
1718 | '@webassemblyjs/helper-api-error': 1.13.2
1719 | '@webassemblyjs/helper-wasm-bytecode': 1.13.2
1720 | '@webassemblyjs/ieee754': 1.13.2
1721 | '@webassemblyjs/leb128': 1.13.2
1722 | '@webassemblyjs/utf8': 1.13.2
1723 |
1724 | '@webassemblyjs/wast-printer@1.14.1':
1725 | dependencies:
1726 | '@webassemblyjs/ast': 1.14.1
1727 | '@xtuc/long': 4.2.2
1728 |
1729 | '@xtuc/ieee754@1.2.0': {}
1730 |
1731 | '@xtuc/long@4.2.2': {}
1732 |
1733 | acorn@8.14.0: {}
1734 |
1735 | ajv-formats@2.1.1(ajv@8.17.1):
1736 | optionalDependencies:
1737 | ajv: 8.17.1
1738 |
1739 | ajv-keywords@5.1.0(ajv@8.17.1):
1740 | dependencies:
1741 | ajv: 8.17.1
1742 | fast-deep-equal: 3.1.3
1743 |
1744 | ajv@8.17.1:
1745 | dependencies:
1746 | fast-deep-equal: 3.1.3
1747 | fast-uri: 3.0.3
1748 | json-schema-traverse: 1.0.0
1749 | require-from-string: 2.0.2
1750 |
1751 | ansi-regex@5.0.1: {}
1752 |
1753 | ansi-regex@6.1.0: {}
1754 |
1755 | ansi-styles@4.3.0:
1756 | dependencies:
1757 | color-convert: 2.0.1
1758 |
1759 | ansi-styles@6.2.1: {}
1760 |
1761 | any-promise@1.3.0: {}
1762 |
1763 | anymatch@3.1.3:
1764 | dependencies:
1765 | normalize-path: 3.0.0
1766 | picomatch: 2.3.1
1767 |
1768 | arg@5.0.2: {}
1769 |
1770 | balanced-match@1.0.2: {}
1771 |
1772 | binary-extensions@2.3.0: {}
1773 |
1774 | boolbase@1.0.0: {}
1775 |
1776 | brace-expansion@2.0.1:
1777 | dependencies:
1778 | balanced-match: 1.0.2
1779 |
1780 | braces@3.0.3:
1781 | dependencies:
1782 | fill-range: 7.1.1
1783 |
1784 | browserslist@4.24.2:
1785 | dependencies:
1786 | caniuse-lite: 1.0.30001716
1787 | electron-to-chromium: 1.5.67
1788 | node-releases: 2.0.18
1789 | update-browserslist-db: 1.1.1(browserslist@4.24.2)
1790 |
1791 | buffer-from@1.1.2: {}
1792 |
1793 | camel-case@4.1.2:
1794 | dependencies:
1795 | pascal-case: 3.1.2
1796 | tslib: 2.8.1
1797 |
1798 | camelcase-css@2.0.1: {}
1799 |
1800 | caniuse-lite@1.0.30001716: {}
1801 |
1802 | caniuse-lite@1.0.30001721: {}
1803 |
1804 | chalk@4.1.2:
1805 | dependencies:
1806 | ansi-styles: 4.3.0
1807 | supports-color: 7.2.0
1808 |
1809 | chokidar@3.6.0:
1810 | dependencies:
1811 | anymatch: 3.1.3
1812 | braces: 3.0.3
1813 | glob-parent: 5.1.2
1814 | is-binary-path: 2.1.0
1815 | is-glob: 4.0.3
1816 | normalize-path: 3.0.0
1817 | readdirp: 3.6.0
1818 | optionalDependencies:
1819 | fsevents: 2.3.3
1820 |
1821 | chrome-trace-event@1.0.4: {}
1822 |
1823 | clean-css@5.3.3:
1824 | dependencies:
1825 | source-map: 0.6.1
1826 |
1827 | color-convert@2.0.1:
1828 | dependencies:
1829 | color-name: 1.1.4
1830 |
1831 | color-name@1.1.4: {}
1832 |
1833 | commander@2.20.3: {}
1834 |
1835 | commander@4.1.1: {}
1836 |
1837 | commander@8.3.0: {}
1838 |
1839 | copy-webpack-plugin@11.0.0(webpack@5.99.9):
1840 | dependencies:
1841 | fast-glob: 3.3.2
1842 | glob-parent: 6.0.2
1843 | globby: 13.2.2
1844 | normalize-path: 3.0.0
1845 | schema-utils: 4.3.0
1846 | serialize-javascript: 6.0.2
1847 | webpack: 5.99.9
1848 |
1849 | core-js@3.42.0: {}
1850 |
1851 | cross-spawn@7.0.6:
1852 | dependencies:
1853 | path-key: 3.1.1
1854 | shebang-command: 2.0.0
1855 | which: 2.0.2
1856 |
1857 | css-select@4.3.0:
1858 | dependencies:
1859 | boolbase: 1.0.0
1860 | css-what: 6.1.0
1861 | domhandler: 4.3.1
1862 | domutils: 2.8.0
1863 | nth-check: 2.1.1
1864 |
1865 | css-what@6.1.0: {}
1866 |
1867 | cssesc@3.0.0: {}
1868 |
1869 | didyoumean@1.2.2: {}
1870 |
1871 | dir-glob@3.0.1:
1872 | dependencies:
1873 | path-type: 4.0.0
1874 |
1875 | dlv@1.1.3: {}
1876 |
1877 | dom-converter@0.2.0:
1878 | dependencies:
1879 | utila: 0.4.0
1880 |
1881 | dom-serializer@1.4.1:
1882 | dependencies:
1883 | domelementtype: 2.3.0
1884 | domhandler: 4.3.1
1885 | entities: 2.2.0
1886 |
1887 | domelementtype@2.3.0: {}
1888 |
1889 | domhandler@4.3.1:
1890 | dependencies:
1891 | domelementtype: 2.3.0
1892 |
1893 | domutils@2.8.0:
1894 | dependencies:
1895 | dom-serializer: 1.4.1
1896 | domelementtype: 2.3.0
1897 | domhandler: 4.3.1
1898 |
1899 | dot-case@3.0.4:
1900 | dependencies:
1901 | no-case: 3.0.4
1902 | tslib: 2.8.1
1903 |
1904 | eastasianwidth@0.2.0: {}
1905 |
1906 | electron-to-chromium@1.5.67: {}
1907 |
1908 | emoji-regex@8.0.0: {}
1909 |
1910 | emoji-regex@9.2.2: {}
1911 |
1912 | enhanced-resolve@5.17.1:
1913 | dependencies:
1914 | graceful-fs: 4.2.11
1915 | tapable: 2.2.1
1916 |
1917 | entities@2.2.0: {}
1918 |
1919 | es-module-lexer@1.5.4: {}
1920 |
1921 | escalade@3.2.0: {}
1922 |
1923 | eslint-scope@5.1.1:
1924 | dependencies:
1925 | esrecurse: 4.3.0
1926 | estraverse: 4.3.0
1927 |
1928 | esrecurse@4.3.0:
1929 | dependencies:
1930 | estraverse: 5.3.0
1931 |
1932 | estraverse@4.3.0: {}
1933 |
1934 | estraverse@5.3.0: {}
1935 |
1936 | estree-walker@2.0.2: {}
1937 |
1938 | events@3.3.0: {}
1939 |
1940 | fast-deep-equal@3.1.3: {}
1941 |
1942 | fast-glob@3.3.2:
1943 | dependencies:
1944 | '@nodelib/fs.stat': 2.0.5
1945 | '@nodelib/fs.walk': 1.2.8
1946 | glob-parent: 5.1.2
1947 | merge2: 1.4.1
1948 | micromatch: 4.0.8
1949 |
1950 | fast-uri@3.0.3: {}
1951 |
1952 | fastq@1.17.1:
1953 | dependencies:
1954 | reusify: 1.0.4
1955 |
1956 | fdir@6.4.4(picomatch@4.0.2):
1957 | optionalDependencies:
1958 | picomatch: 4.0.2
1959 |
1960 | fill-range@7.1.1:
1961 | dependencies:
1962 | to-regex-range: 5.0.1
1963 |
1964 | foreground-child@3.3.0:
1965 | dependencies:
1966 | cross-spawn: 7.0.6
1967 | signal-exit: 4.1.0
1968 |
1969 | fsevents@2.3.2:
1970 | optional: true
1971 |
1972 | fsevents@2.3.3:
1973 | optional: true
1974 |
1975 | function-bind@1.1.2: {}
1976 |
1977 | glob-parent@5.1.2:
1978 | dependencies:
1979 | is-glob: 4.0.3
1980 |
1981 | glob-parent@6.0.2:
1982 | dependencies:
1983 | is-glob: 4.0.3
1984 |
1985 | glob-to-regexp@0.4.1: {}
1986 |
1987 | glob@10.4.5:
1988 | dependencies:
1989 | foreground-child: 3.3.0
1990 | jackspeak: 3.4.3
1991 | minimatch: 9.0.5
1992 | minipass: 7.1.2
1993 | package-json-from-dist: 1.0.1
1994 | path-scurry: 1.11.1
1995 |
1996 | globby@13.2.2:
1997 | dependencies:
1998 | dir-glob: 3.0.1
1999 | fast-glob: 3.3.2
2000 | ignore: 5.3.2
2001 | merge2: 1.4.1
2002 | slash: 4.0.0
2003 |
2004 | graceful-fs@4.2.11: {}
2005 |
2006 | has-flag@4.0.0: {}
2007 |
2008 | hasown@2.0.2:
2009 | dependencies:
2010 | function-bind: 1.1.2
2011 |
2012 | he@1.2.0: {}
2013 |
2014 | html-minifier-terser@6.1.0:
2015 | dependencies:
2016 | camel-case: 4.1.2
2017 | clean-css: 5.3.3
2018 | commander: 8.3.0
2019 | he: 1.2.0
2020 | param-case: 3.0.4
2021 | relateurl: 0.2.7
2022 | terser: 5.36.0
2023 |
2024 | html-webpack-plugin@5.6.3(@rspack/core@1.3.13(@swc/helpers@0.5.17))(webpack@5.99.9):
2025 | dependencies:
2026 | '@types/html-minifier-terser': 6.1.0
2027 | html-minifier-terser: 6.1.0
2028 | lodash: 4.17.21
2029 | pretty-error: 4.0.0
2030 | tapable: 2.2.1
2031 | optionalDependencies:
2032 | '@rspack/core': 1.3.13(@swc/helpers@0.5.17)
2033 | webpack: 5.99.9
2034 |
2035 | htmlparser2@6.1.0:
2036 | dependencies:
2037 | domelementtype: 2.3.0
2038 | domhandler: 4.3.1
2039 | domutils: 2.8.0
2040 | entities: 2.2.0
2041 |
2042 | ignore@5.3.2: {}
2043 |
2044 | is-binary-path@2.1.0:
2045 | dependencies:
2046 | binary-extensions: 2.3.0
2047 |
2048 | is-core-module@2.15.1:
2049 | dependencies:
2050 | hasown: 2.0.2
2051 |
2052 | is-extglob@2.1.1: {}
2053 |
2054 | is-fullwidth-code-point@3.0.0: {}
2055 |
2056 | is-glob@4.0.3:
2057 | dependencies:
2058 | is-extglob: 2.1.1
2059 |
2060 | is-number@7.0.0: {}
2061 |
2062 | isexe@2.0.0: {}
2063 |
2064 | jackspeak@3.4.3:
2065 | dependencies:
2066 | '@isaacs/cliui': 8.0.2
2067 | optionalDependencies:
2068 | '@pkgjs/parseargs': 0.11.0
2069 |
2070 | jest-worker@27.5.1:
2071 | dependencies:
2072 | '@types/node': 22.15.29
2073 | merge-stream: 2.0.0
2074 | supports-color: 8.1.1
2075 |
2076 | jiti@1.21.6: {}
2077 |
2078 | jiti@2.4.2: {}
2079 |
2080 | json-parse-even-better-errors@2.3.1: {}
2081 |
2082 | json-schema-traverse@1.0.0: {}
2083 |
2084 | json5@2.2.3: {}
2085 |
2086 | lilconfig@3.1.3: {}
2087 |
2088 | lines-and-columns@1.2.4: {}
2089 |
2090 | loader-runner@4.3.0: {}
2091 |
2092 | lodash@4.17.21: {}
2093 |
2094 | lower-case@2.0.2:
2095 | dependencies:
2096 | tslib: 2.8.1
2097 |
2098 | lru-cache@10.4.3: {}
2099 |
2100 | magic-string@0.30.17:
2101 | dependencies:
2102 | '@jridgewell/sourcemap-codec': 1.5.0
2103 |
2104 | merge-stream@2.0.0: {}
2105 |
2106 | merge2@1.4.1: {}
2107 |
2108 | micromatch@4.0.8:
2109 | dependencies:
2110 | braces: 3.0.3
2111 | picomatch: 2.3.1
2112 |
2113 | mime-db@1.52.0: {}
2114 |
2115 | mime-types@2.1.35:
2116 | dependencies:
2117 | mime-db: 1.52.0
2118 |
2119 | mini-css-extract-plugin@2.9.2(webpack@5.99.9):
2120 | dependencies:
2121 | schema-utils: 4.3.0
2122 | tapable: 2.2.1
2123 | webpack: 5.99.9
2124 |
2125 | minimatch@9.0.5:
2126 | dependencies:
2127 | brace-expansion: 2.0.1
2128 |
2129 | minimist@1.2.8: {}
2130 |
2131 | minipass@7.1.2: {}
2132 |
2133 | mz@2.7.0:
2134 | dependencies:
2135 | any-promise: 1.3.0
2136 | object-assign: 4.1.1
2137 | thenify-all: 1.6.0
2138 |
2139 | nanoid@3.3.11: {}
2140 |
2141 | neo-async@2.6.2: {}
2142 |
2143 | no-case@3.0.4:
2144 | dependencies:
2145 | lower-case: 2.0.2
2146 | tslib: 2.8.1
2147 |
2148 | node-releases@2.0.18: {}
2149 |
2150 | normalize-path@3.0.0: {}
2151 |
2152 | nth-check@2.1.1:
2153 | dependencies:
2154 | boolbase: 1.0.0
2155 |
2156 | object-assign@4.1.1: {}
2157 |
2158 | object-hash@3.0.0: {}
2159 |
2160 | package-json-from-dist@1.0.1: {}
2161 |
2162 | param-case@3.0.4:
2163 | dependencies:
2164 | dot-case: 3.0.4
2165 | tslib: 2.8.1
2166 |
2167 | pascal-case@3.1.2:
2168 | dependencies:
2169 | no-case: 3.0.4
2170 | tslib: 2.8.1
2171 |
2172 | path-key@3.1.1: {}
2173 |
2174 | path-parse@1.0.7: {}
2175 |
2176 | path-scurry@1.11.1:
2177 | dependencies:
2178 | lru-cache: 10.4.3
2179 | minipass: 7.1.2
2180 |
2181 | path-type@4.0.0: {}
2182 |
2183 | picocolors@1.1.1: {}
2184 |
2185 | picomatch@2.3.1: {}
2186 |
2187 | picomatch@4.0.2: {}
2188 |
2189 | pify@2.3.0: {}
2190 |
2191 | pirates@4.0.6: {}
2192 |
2193 | playwright-core@1.52.0: {}
2194 |
2195 | playwright@1.52.0:
2196 | dependencies:
2197 | playwright-core: 1.52.0
2198 | optionalDependencies:
2199 | fsevents: 2.3.2
2200 |
2201 | postcss-import@15.1.0(postcss@8.5.4):
2202 | dependencies:
2203 | postcss: 8.5.4
2204 | postcss-value-parser: 4.2.0
2205 | read-cache: 1.0.0
2206 | resolve: 1.22.8
2207 |
2208 | postcss-js@4.0.1(postcss@8.5.4):
2209 | dependencies:
2210 | camelcase-css: 2.0.1
2211 | postcss: 8.5.4
2212 |
2213 | postcss-load-config@4.0.2(postcss@8.5.4):
2214 | dependencies:
2215 | lilconfig: 3.1.3
2216 | yaml: 2.6.1
2217 | optionalDependencies:
2218 | postcss: 8.5.4
2219 |
2220 | postcss-nested@6.2.0(postcss@8.5.4):
2221 | dependencies:
2222 | postcss: 8.5.4
2223 | postcss-selector-parser: 6.1.2
2224 |
2225 | postcss-selector-parser@6.1.2:
2226 | dependencies:
2227 | cssesc: 3.0.0
2228 | util-deprecate: 1.0.2
2229 |
2230 | postcss-value-parser@4.2.0: {}
2231 |
2232 | postcss@8.5.4:
2233 | dependencies:
2234 | nanoid: 3.3.11
2235 | picocolors: 1.1.1
2236 | source-map-js: 1.2.1
2237 |
2238 | pretty-error@4.0.0:
2239 | dependencies:
2240 | lodash: 4.17.21
2241 | renderkid: 3.0.0
2242 |
2243 | queue-microtask@1.2.3: {}
2244 |
2245 | randombytes@2.1.0:
2246 | dependencies:
2247 | safe-buffer: 5.2.1
2248 |
2249 | read-cache@1.0.0:
2250 | dependencies:
2251 | pify: 2.3.0
2252 |
2253 | readdirp@3.6.0:
2254 | dependencies:
2255 | picomatch: 2.3.1
2256 |
2257 | reduce-configs@1.1.0: {}
2258 |
2259 | relateurl@0.2.7: {}
2260 |
2261 | renderkid@3.0.0:
2262 | dependencies:
2263 | css-select: 4.3.0
2264 | dom-converter: 0.2.0
2265 | htmlparser2: 6.1.0
2266 | lodash: 4.17.21
2267 | strip-ansi: 6.0.1
2268 |
2269 | require-from-string@2.0.2: {}
2270 |
2271 | resolve@1.22.8:
2272 | dependencies:
2273 | is-core-module: 2.15.1
2274 | path-parse: 1.0.7
2275 | supports-preserve-symlinks-flag: 1.0.0
2276 |
2277 | reusify@1.0.4: {}
2278 |
2279 | rsbuild-plugin-dts@0.9.1(@rsbuild/core@1.3.22)(typescript@5.8.3):
2280 | dependencies:
2281 | '@ast-grep/napi': 0.37.0
2282 | '@rsbuild/core': 1.3.22
2283 | magic-string: 0.30.17
2284 | picocolors: 1.1.1
2285 | tinyglobby: 0.2.14
2286 | tsconfig-paths: 4.2.0
2287 | optionalDependencies:
2288 | typescript: 5.8.3
2289 |
2290 | run-parallel@1.2.0:
2291 | dependencies:
2292 | queue-microtask: 1.2.3
2293 |
2294 | safe-buffer@5.2.1: {}
2295 |
2296 | schema-utils@4.3.0:
2297 | dependencies:
2298 | '@types/json-schema': 7.0.15
2299 | ajv: 8.17.1
2300 | ajv-formats: 2.1.1(ajv@8.17.1)
2301 | ajv-keywords: 5.1.0(ajv@8.17.1)
2302 |
2303 | schema-utils@4.3.2:
2304 | dependencies:
2305 | '@types/json-schema': 7.0.15
2306 | ajv: 8.17.1
2307 | ajv-formats: 2.1.1(ajv@8.17.1)
2308 | ajv-keywords: 5.1.0(ajv@8.17.1)
2309 |
2310 | semver@7.7.2: {}
2311 |
2312 | serialize-javascript@6.0.2:
2313 | dependencies:
2314 | randombytes: 2.1.0
2315 |
2316 | shebang-command@2.0.0:
2317 | dependencies:
2318 | shebang-regex: 3.0.0
2319 |
2320 | shebang-regex@3.0.0: {}
2321 |
2322 | signal-exit@4.1.0: {}
2323 |
2324 | simple-git-hooks@2.13.0: {}
2325 |
2326 | slash@4.0.0: {}
2327 |
2328 | source-map-js@1.2.1: {}
2329 |
2330 | source-map-support@0.5.21:
2331 | dependencies:
2332 | buffer-from: 1.1.2
2333 | source-map: 0.6.1
2334 |
2335 | source-map@0.6.1: {}
2336 |
2337 | string-width@4.2.3:
2338 | dependencies:
2339 | emoji-regex: 8.0.0
2340 | is-fullwidth-code-point: 3.0.0
2341 | strip-ansi: 6.0.1
2342 |
2343 | string-width@5.1.2:
2344 | dependencies:
2345 | eastasianwidth: 0.2.0
2346 | emoji-regex: 9.2.2
2347 | strip-ansi: 7.1.0
2348 |
2349 | strip-ansi@6.0.1:
2350 | dependencies:
2351 | ansi-regex: 5.0.1
2352 |
2353 | strip-ansi@7.1.0:
2354 | dependencies:
2355 | ansi-regex: 6.1.0
2356 |
2357 | strip-bom@3.0.0: {}
2358 |
2359 | sucrase@3.35.0:
2360 | dependencies:
2361 | '@jridgewell/gen-mapping': 0.3.5
2362 | commander: 4.1.1
2363 | glob: 10.4.5
2364 | lines-and-columns: 1.2.4
2365 | mz: 2.7.0
2366 | pirates: 4.0.6
2367 | ts-interface-checker: 0.1.13
2368 |
2369 | supports-color@7.2.0:
2370 | dependencies:
2371 | has-flag: 4.0.0
2372 |
2373 | supports-color@8.1.1:
2374 | dependencies:
2375 | has-flag: 4.0.0
2376 |
2377 | supports-preserve-symlinks-flag@1.0.0: {}
2378 |
2379 | tailwindcss@3.4.17:
2380 | dependencies:
2381 | '@alloc/quick-lru': 5.2.0
2382 | arg: 5.0.2
2383 | chokidar: 3.6.0
2384 | didyoumean: 1.2.2
2385 | dlv: 1.1.3
2386 | fast-glob: 3.3.2
2387 | glob-parent: 6.0.2
2388 | is-glob: 4.0.3
2389 | jiti: 1.21.6
2390 | lilconfig: 3.1.3
2391 | micromatch: 4.0.8
2392 | normalize-path: 3.0.0
2393 | object-hash: 3.0.0
2394 | picocolors: 1.1.1
2395 | postcss: 8.5.4
2396 | postcss-import: 15.1.0(postcss@8.5.4)
2397 | postcss-js: 4.0.1(postcss@8.5.4)
2398 | postcss-load-config: 4.0.2(postcss@8.5.4)
2399 | postcss-nested: 6.2.0(postcss@8.5.4)
2400 | postcss-selector-parser: 6.1.2
2401 | resolve: 1.22.8
2402 | sucrase: 3.35.0
2403 | transitivePeerDependencies:
2404 | - ts-node
2405 |
2406 | tapable@2.2.1: {}
2407 |
2408 | terser-webpack-plugin@5.3.12(webpack@5.99.9):
2409 | dependencies:
2410 | '@jridgewell/trace-mapping': 0.3.25
2411 | jest-worker: 27.5.1
2412 | schema-utils: 4.3.2
2413 | serialize-javascript: 6.0.2
2414 | terser: 5.36.0
2415 | webpack: 5.99.9
2416 |
2417 | terser@5.36.0:
2418 | dependencies:
2419 | '@jridgewell/source-map': 0.3.6
2420 | acorn: 8.14.0
2421 | commander: 2.20.3
2422 | source-map-support: 0.5.21
2423 |
2424 | thenify-all@1.6.0:
2425 | dependencies:
2426 | thenify: 3.3.1
2427 |
2428 | thenify@3.3.1:
2429 | dependencies:
2430 | any-promise: 1.3.0
2431 |
2432 | tinyglobby@0.2.14:
2433 | dependencies:
2434 | fdir: 6.4.4(picomatch@4.0.2)
2435 | picomatch: 4.0.2
2436 |
2437 | to-regex-range@5.0.1:
2438 | dependencies:
2439 | is-number: 7.0.0
2440 |
2441 | ts-interface-checker@0.1.13: {}
2442 |
2443 | tsconfig-paths-webpack-plugin@4.2.0:
2444 | dependencies:
2445 | chalk: 4.1.2
2446 | enhanced-resolve: 5.17.1
2447 | tapable: 2.2.1
2448 | tsconfig-paths: 4.2.0
2449 |
2450 | tsconfig-paths@4.2.0:
2451 | dependencies:
2452 | json5: 2.2.3
2453 | minimist: 1.2.8
2454 | strip-bom: 3.0.0
2455 |
2456 | tslib@2.8.1: {}
2457 |
2458 | typescript@5.8.3: {}
2459 |
2460 | undici-types@6.21.0: {}
2461 |
2462 | update-browserslist-db@1.1.1(browserslist@4.24.2):
2463 | dependencies:
2464 | browserslist: 4.24.2
2465 | escalade: 3.2.0
2466 | picocolors: 1.1.1
2467 |
2468 | util-deprecate@1.0.2: {}
2469 |
2470 | utila@0.4.0: {}
2471 |
2472 | watchpack@2.4.2:
2473 | dependencies:
2474 | glob-to-regexp: 0.4.1
2475 | graceful-fs: 4.2.11
2476 |
2477 | webpack-sources@3.2.3: {}
2478 |
2479 | webpack@5.99.9:
2480 | dependencies:
2481 | '@types/eslint-scope': 3.7.7
2482 | '@types/estree': 1.0.6
2483 | '@types/json-schema': 7.0.15
2484 | '@webassemblyjs/ast': 1.14.1
2485 | '@webassemblyjs/wasm-edit': 1.14.1
2486 | '@webassemblyjs/wasm-parser': 1.14.1
2487 | acorn: 8.14.0
2488 | browserslist: 4.24.2
2489 | chrome-trace-event: 1.0.4
2490 | enhanced-resolve: 5.17.1
2491 | es-module-lexer: 1.5.4
2492 | eslint-scope: 5.1.1
2493 | events: 3.3.0
2494 | glob-to-regexp: 0.4.1
2495 | graceful-fs: 4.2.11
2496 | json-parse-even-better-errors: 2.3.1
2497 | loader-runner: 4.3.0
2498 | mime-types: 2.1.35
2499 | neo-async: 2.6.2
2500 | schema-utils: 4.3.2
2501 | tapable: 2.2.1
2502 | terser-webpack-plugin: 5.3.12(webpack@5.99.9)
2503 | watchpack: 2.4.2
2504 | webpack-sources: 3.2.3
2505 | transitivePeerDependencies:
2506 | - '@swc/core'
2507 | - esbuild
2508 | - uglify-js
2509 |
2510 | which@2.0.2:
2511 | dependencies:
2512 | isexe: 2.0.0
2513 |
2514 | wrap-ansi@7.0.0:
2515 | dependencies:
2516 | ansi-styles: 4.3.0
2517 | string-width: 4.2.3
2518 | strip-ansi: 6.0.1
2519 |
2520 | wrap-ansi@8.1.0:
2521 | dependencies:
2522 | ansi-styles: 6.2.1
2523 | string-width: 5.1.2
2524 | strip-ansi: 7.1.0
2525 |
2526 | yaml@2.6.1: {}
2527 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'playground'
3 |
--------------------------------------------------------------------------------
/rslib.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@rslib/core';
2 |
3 | export default defineConfig({
4 | lib: [
5 | { format: 'esm', syntax: 'es2021', dts: true },
6 | { format: 'cjs', syntax: 'es2021' },
7 | ],
8 | });
9 |
--------------------------------------------------------------------------------
/src/Set.prototype.isSubsetOf.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * See: {@link https://github.com/tc39/proposal-set-methods | Set Methods for JavaScript}
3 | */
4 | export function isSubsetOf(a: ReadonlySet, b: ReadonlySet): boolean {
5 | // Node.js v22 will have native implementation.
6 | if (typeof a.isSubsetOf === 'function') {
7 | return a.isSubsetOf(b);
8 | }
9 |
10 | if (a.size > b.size) {
11 | return false;
12 | }
13 |
14 | for (const item of a) {
15 | if (!b.has(item)) {
16 | return false;
17 | }
18 | }
19 | return true;
20 | }
21 |
--------------------------------------------------------------------------------
/src/TailwindCSSRspackPlugin.ts:
--------------------------------------------------------------------------------
1 | import { existsSync } from 'node:fs';
2 | import { mkdir, mkdtemp, readFile, writeFile } from 'node:fs/promises';
3 | import { createRequire } from 'node:module';
4 | import { tmpdir } from 'node:os';
5 | import path from 'node:path';
6 | import { pathToFileURL } from 'node:url';
7 |
8 | import { createFilter } from '@rollup/pluginutils';
9 | import type { PostCSSLoaderOptions, Rspack } from '@rsbuild/core';
10 | import type { Processor } from 'postcss';
11 |
12 | import { isSubsetOf } from './Set.prototype.isSubsetOf.js';
13 |
14 | /**
15 | * The options for {@link TailwindRspackPlugin}.
16 | *
17 | * @public
18 | */
19 | interface TailwindRspackPluginOptions {
20 | /**
21 | * The path to the configuration of Tailwind CSS.
22 | *
23 | * @example
24 | *
25 | * Use absolute path:
26 | *
27 | * ```js
28 | * // rspack.config.js
29 | * import path from 'node:path'
30 | * import { fileURLToPath } from 'node:url'
31 | *
32 | * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
33 | *
34 | * const __dirname = path.dirname(fileURLToPath(import.meta.url))
35 | *
36 | * export default {
37 | * plugins: [
38 | * new TailwindRspackPlugin({
39 | * config: path.resolve(__dirname, './config/tailwind.config.js'),
40 | * }),
41 | * ],
42 | * }
43 | * ```
44 | *
45 | * @example
46 | *
47 | * Use relative path:
48 | *
49 | * ```js
50 | * // rspack.config.js
51 | * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
52 | *
53 | * export default {
54 | * plugins: [
55 | * new TailwindRspackPlugin({
56 | * config: './config/tailwind.config.js',
57 | * }),
58 | * ],
59 | * }
60 | * ```
61 | */
62 | config: string;
63 |
64 | /**
65 | * The modules to be excluded.
66 | *
67 | * If {@link include} is omitted or empty,
68 | * all modules that do not match any of the {@link exclude} patterns will be included.
69 | * Otherwise, only modules that match one or more of the {@link include} patterns
70 | * and do not match any of the {@link exclude} patterns will be included.
71 | *
72 | * @example
73 | *
74 | * ```js
75 | * // rspack.config.js
76 | * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
77 | *
78 | * export default {
79 | * plugins: [
80 | * new TailwindRspackPlugin({
81 | * exclude: [
82 | * './src/store/**',
83 | * /[\\/]node_modules[\\/]/,
84 | * ],
85 | * }),
86 | * ],
87 | * }
88 | * ```
89 | */
90 | exclude?: FilterPattern | undefined;
91 |
92 | /**
93 | * The modules to be included using `picomatch` patterns.
94 | *
95 | * If {@link include} is omitted or empty,
96 | * all modules that do not match any of the {@link exclude} patterns will be included.
97 | * Otherwise, only modules that match one or more of the {@link include} patterns
98 | * and do not match any of the {@link exclude} patterns will be included.
99 | *
100 | * @example
101 | *
102 | * ```js
103 | * // rspack.config.js
104 | * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
105 | *
106 | * export default {
107 | * plugins: [
108 | * new TailwindRspackPlugin({
109 | * include: [
110 | * /\.[jt]sx?/,
111 | * ],
112 | * }),
113 | * ],
114 | * }
115 | * ```
116 | */
117 | include?: FilterPattern | undefined;
118 |
119 | /**
120 | * The postcss options to be applied.
121 | *
122 | * @example
123 | *
124 | * Use `cssnano`:
125 | *
126 | * ```js
127 | * // rspack.config.js
128 | * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
129 | *
130 | * export default {
131 | * plugins: [
132 | * new TailwindRspackPlugin({
133 | * postcssOptions: {
134 | * plugins: {
135 | * cssnano: process.env['NODE_ENV'] === 'production' ? {} : false,
136 | * },
137 | * },
138 | * }),
139 | * ],
140 | * }
141 | * ```
142 | */
143 | postcssOptions: Exclude<
144 | PostCSSLoaderOptions['postcssOptions'],
145 | (loaderContext: Rspack.LoaderContext) => void
146 | >;
147 | }
148 |
149 | // From `@rollup/pluginutils`
150 | /**
151 | * A valid `picomatch` glob pattern, or array of patterns.
152 | */
153 | export type FilterPattern =
154 | | ReadonlyArray
155 | | string
156 | | RegExp
157 | | null;
158 |
159 | /**
160 | * The Rspack plugin for Tailwind integration.
161 | *
162 | * @public
163 | */
164 | class TailwindRspackPlugin {
165 | constructor(private readonly options: TailwindRspackPluginOptions) {}
166 |
167 | /**
168 | * The entry point of a Rspack plugin.
169 | * @param compiler - the Rspack compiler
170 | */
171 | apply(compiler: Rspack.Compiler): void {
172 | new TailwindRspackPluginImpl(compiler, this.options);
173 | }
174 | }
175 |
176 | export { TailwindRspackPlugin };
177 | export type { TailwindRspackPluginOptions };
178 |
179 | class TailwindRspackPluginImpl {
180 | name = 'TailwindRspackPlugin';
181 |
182 | postcssProcessorCache = new Map<
183 | /** entryName */ string,
184 | [entryModules: ReadonlySet, Processor]
185 | >();
186 |
187 | constructor(
188 | private compiler: Rspack.Compiler,
189 | private options: TailwindRspackPluginOptions,
190 | ) {
191 | const filter = createFilter(options.include, options.exclude, {
192 | // biome-ignore lint/style/noNonNullAssertion: context should exist
193 | resolve: compiler.options.context!,
194 | });
195 |
196 | compiler.hooks.thisCompilation.tap(this.name, (compilation) => {
197 | compilation.hooks.processAssets.tapPromise(this.name, async () => {
198 | await Promise.all(
199 | [...compilation.entrypoints.entries()].map(
200 | async ([entryName, entrypoint]) => {
201 | const cssFiles = entrypoint
202 | .getFiles()
203 | .filter((file) => file.endsWith('.css'))
204 | .map((file) => compilation.getAsset(file))
205 | .filter((file) => !!file);
206 |
207 | if (cssFiles.length === 0) {
208 | // Ignore entrypoint without CSS files.
209 | return;
210 | }
211 |
212 | const cache = this.postcssProcessorCache.get(entryName);
213 | if (compiler.modifiedFiles?.size && cache) {
214 | const [cachedEntryModules, cachedPostcssProcessor] = cache;
215 | if (isSubsetOf(compiler.modifiedFiles, cachedEntryModules)) {
216 | await this.#transformCSSAssets(
217 | compilation,
218 | cachedPostcssProcessor,
219 | cssFiles,
220 | );
221 | return;
222 | }
223 | }
224 |
225 | // collect all the modules corresponding to specific entry
226 | const entryModules = new Set();
227 |
228 | for (const chunk of entrypoint.chunks) {
229 | const modules =
230 | compilation.chunkGraph.getChunkModulesIterable(chunk);
231 | for (const module of modules) {
232 | collectModules(module, entryModules);
233 | }
234 | }
235 |
236 | if (compiler.modifiedFiles && cache) {
237 | const [cachedEntryModules, cachedPostcssProcessor] = cache;
238 | if (isSubsetOf(entryModules, cachedEntryModules)) {
239 | await this.#transformCSSAssets(
240 | compilation,
241 | cachedPostcssProcessor,
242 | cssFiles,
243 | );
244 | return;
245 | }
246 | }
247 |
248 | const [
249 | { default: postcss },
250 | { default: tailwindcss },
251 | configPath,
252 | ] = await Promise.all([
253 | import('postcss'),
254 | import('tailwindcss'),
255 | this.#prepareTailwindConfig(
256 | entryName,
257 | Array.from(entryModules).filter(filter),
258 | ),
259 | ]);
260 |
261 | const processor = postcss([
262 | // We use a config path to avoid performance issue of TailwindCSS
263 | // See: https://github.com/tailwindlabs/tailwindcss/issues/14229
264 | tailwindcss({
265 | config: configPath,
266 | }),
267 | ...(options.postcssOptions?.plugins ?? []),
268 | ]);
269 |
270 | this.postcssProcessorCache.set(entryName, [
271 | entryModules,
272 | processor,
273 | ]);
274 |
275 | await this.#transformCSSAssets(compilation, processor, cssFiles);
276 | },
277 | ),
278 | );
279 | });
280 | });
281 | }
282 |
283 | async #transformCSSAssets(
284 | compilation: Rspack.Compilation,
285 | postcssProcessor: Processor,
286 | cssFiles: Array,
287 | ) {
288 | const { RawSource } = this.compiler.webpack.sources;
289 |
290 | // iterate all css asset in entry and inject entry modules into tailwind content
291 | await Promise.all(
292 | cssFiles.map(async (asset) => {
293 | const content = asset.source.source();
294 | // transform .css which contains tailwind mixin
295 | // FIXME: add custom postcss config
296 | const transformResult = await postcssProcessor.process(content, {
297 | from: asset.name,
298 | ...this.options.postcssOptions,
299 | });
300 | // FIXME: avoid `updateAsset` when no change is found.
301 | // FIXME: add sourcemap support
302 | compilation.updateAsset(asset.name, new RawSource(transformResult.css));
303 | }),
304 | );
305 | }
306 |
307 | async ensureTempDir(entryName: string): Promise {
308 | const prefix = path.join(tmpdir(), entryName);
309 | await mkdir(path.dirname(prefix), { recursive: true });
310 | return await mkdtemp(prefix);
311 | }
312 |
313 | async #prepareTailwindConfig(
314 | entryName: string,
315 | entryModules: Array,
316 | ): Promise {
317 | const userConfig = path.isAbsolute(this.options.config)
318 | ? this.options.config
319 | : // biome-ignore lint/style/noNonNullAssertion: should have context
320 | path.resolve(this.compiler.options.context!, this.options.config);
321 |
322 | const outputDir = DEBUG
323 | ? path.resolve(
324 | // biome-ignore lint/style/noNonNullAssertion: should have `output.path`
325 | this.compiler.options.output.path!,
326 | '.rsbuild',
327 | entryName,
328 | )
329 | : await this.ensureTempDir(entryName);
330 |
331 | if (DEBUG) {
332 | await mkdir(outputDir, { recursive: true });
333 | }
334 |
335 | const [configName, configContent] = await this.#generateTailwindConfig(
336 | userConfig,
337 | entryModules,
338 | );
339 | const configPath = path.resolve(outputDir, configName);
340 |
341 | await writeFile(configPath, configContent);
342 |
343 | return configPath;
344 | }
345 |
346 | async #resolveTailwindCSSVersion(): Promise {
347 | const require = createRequire(import.meta.url);
348 | const pkgPath = require.resolve('tailwindcss/package.json', {
349 | paths: [this.compiler.context],
350 | });
351 |
352 | const content = await readFile(pkgPath, 'utf-8');
353 |
354 | const { version } = JSON.parse(content) as { version: string };
355 |
356 | return version;
357 | }
358 |
359 | async #generateTailwindConfig(
360 | userConfig: string,
361 | entryModules: string[],
362 | ): Promise<['tailwind.config.mjs' | 'tailwind.config.cjs', string]> {
363 | const version = await this.#resolveTailwindCSSVersion();
364 |
365 | const { default: satisfies } = await import(
366 | 'semver/functions/satisfies.js'
367 | );
368 |
369 | const content = JSON.stringify(entryModules);
370 | if (satisfies(version, '^3.3.0')) {
371 | // Tailwind CSS support using ESM configuration in v3.3.0
372 | // See:
373 | // - https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.3.0
374 | // - https://github.com/tailwindlabs/tailwindcss/pull/10785
375 | // - https://github.com/rspack-contrib/rsbuild-plugin-tailwindcss/issues/18
376 | //
377 | // In this case, we provide an ESM configuration to support both ESM and CJS.
378 | return [
379 | 'tailwind.config.mjs',
380 | existsSync(userConfig)
381 | ? `\
382 | import config from '${pathToFileURL(userConfig)}'
383 | export default {
384 | ...config,
385 | content: ${content}
386 | }`
387 | : `\
388 | export default {
389 | content: ${content}
390 | }`,
391 | ];
392 | }
393 |
394 | // Otherwise, we provide an CJS configuration since TailwindCSS would always use `require`.
395 | return [
396 | 'tailwind.config.cjs',
397 | existsSync(userConfig)
398 | ? `\
399 | const config = require(${JSON.stringify(userConfig)})
400 | module.exports = {
401 | ...config,
402 | content: ${content}
403 | }`
404 | : `\
405 | module.exports = {
406 | content: ${content}
407 | }`,
408 | ];
409 | }
410 | }
411 |
412 | function collectModules(
413 | module: Rspack.Module | Rspack.ConcatenatedModule | Rspack.NormalModule,
414 | entryModules: Set,
415 | ): void {
416 | if ('modules' in module && module.modules) {
417 | for (const innerModule of module.modules) {
418 | collectModules(innerModule, entryModules);
419 | }
420 | } else if ('resource' in module && module.resource) {
421 | // The value of `module.resource` maybe one of them:
422 | // 1. /w/a.js
423 | // 2. /w/a.js?component
424 |
425 | const resource: string =
426 | // rspack doesn't have the property `module.resourceResolveData.path` now.
427 | module.resource.split('?')[0];
428 | entryModules.add(resource);
429 | }
430 | }
431 |
432 | const DEBUG = (function isDebug() {
433 | if (!process.env.DEBUG) {
434 | return false;
435 | }
436 |
437 | const values = process.env.DEBUG.toLocaleLowerCase().split(',');
438 | return ['rsbuild', 'rsbuild:tailwind', 'rsbuild:*', '*'].some((key) =>
439 | values.includes(key),
440 | );
441 | })();
442 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | PostCSSLoaderOptions,
3 | RsbuildPlugin,
4 | Rspack,
5 | } from '@rsbuild/core';
6 |
7 | import { TailwindRspackPlugin } from './TailwindCSSRspackPlugin.js';
8 | import type { FilterPattern } from './TailwindCSSRspackPlugin.js';
9 |
10 | export type { FilterPattern };
11 |
12 | export interface PluginTailwindCSSOptions {
13 | /**
14 | * The path to the configuration of Tailwind CSS.
15 | *
16 | * @remarks
17 | *
18 | * The default value is `tailwind.config.js`.
19 | *
20 | * @example
21 | *
22 | * Use relative path:
23 | *
24 | * ```js
25 | * // rsbuild.config.ts
26 | * import { pluginTailwindCSS } from '@byted-lynx/plugin-tailwindcss'
27 | *
28 | * export default {
29 | * plugins: [
30 | * pluginTailwindCSS({
31 | * config: './config/tailwind.config.js',
32 | * }),
33 | * ],
34 | * }
35 | * ```
36 | *
37 | * @example
38 | *
39 | * Use absolute path:
40 | *
41 | * ```js
42 | * // rsbuild.config.ts
43 | * import path from 'node:path'
44 | * import { fileURLToPath } from 'node:url'
45 | *
46 | * import { pluginTailwindCSS } from 'rsbuild-plugin-tailwindcss'
47 | *
48 | * const __dirname = path.dirname(fileURLToPath(import.meta.url))
49 | *
50 | * export default {
51 | * plugins: [
52 | * pluginTailwindCSS({
53 | * config: path.resolve(__dirname, './config/tailwind.config.js'),
54 | * }),
55 | * ],
56 | * }
57 | * ```
58 | */
59 | config?: string;
60 |
61 | /**
62 | * The modules to be excluded using `picomatch` patterns.
63 | *
64 | * If {@link include} is omitted or empty,
65 | * all modules that do not match any of the {@link exclude} patterns will be included.
66 | * Otherwise, only modules that match one or more of the {@link include} patterns
67 | * and do not match any of the {@link exclude} patterns will be included.
68 | *
69 | * @example
70 | *
71 | * ```js
72 | * // rsbuild.config.ts
73 | * import { pluginTailwindCSS } from '@byted-lynx/plugin-tailwindcss'
74 | *
75 | * export default {
76 | * plugins: [
77 | * pluginTailwindCSS({
78 | * exclude: [
79 | * './src/store/**',
80 | * /[\\/]node_modules[\\/]/,
81 | * ],
82 | * }),
83 | * ],
84 | * }
85 | * ```
86 | */
87 | exclude?: FilterPattern | undefined;
88 |
89 | /**
90 | * The modules to be included using `picomatch` patterns.
91 | *
92 | * If {@link include} is omitted or empty,
93 | * all modules that do not match any of the {@link exclude} patterns will be included.
94 | * Otherwise, only modules that match one or more of the {@link include} patterns
95 | * and do not match any of the {@link exclude} patterns will be included.
96 | *
97 | * @example
98 | *
99 | * ```js
100 | * // rsbuild.config.ts
101 | * import { pluginTailwindCSS } from '@byted-lynx/plugin-tailwindcss'
102 | *
103 | * export default {
104 | * plugins: [
105 | * pluginTailwindCSS({
106 | * include: [
107 | * /\.[jt]sx?/,
108 | * ],
109 | * }),
110 | * ],
111 | * }
112 | * ```
113 | */
114 | include?: FilterPattern | undefined;
115 | }
116 |
117 | export const pluginTailwindCSS = (
118 | options: PluginTailwindCSSOptions = {},
119 | ): RsbuildPlugin => ({
120 | name: 'rsbuild:tailwindcss',
121 |
122 | setup(api) {
123 | let postcssOptions: Exclude<
124 | PostCSSLoaderOptions['postcssOptions'],
125 | (loaderContext: Rspack.LoaderContext) => void
126 | >;
127 |
128 | api.modifyRsbuildConfig({
129 | order: 'post',
130 | handler(config, { mergeRsbuildConfig }) {
131 | return mergeRsbuildConfig(config, {
132 | tools: {
133 | postcss(config) {
134 | if (typeof config.postcssOptions === 'function') {
135 | throw new Error(
136 | 'pluginTailwindCSS does not support using `tools.postcss` as function',
137 | );
138 | }
139 | if (config.postcssOptions) {
140 | // Remove `tailwindcss` from `postcssOptions`
141 | // to avoid `@tailwind` being transformed by `postcss-loader`.
142 | config.postcssOptions.plugins =
143 | config.postcssOptions.plugins?.filter(
144 | (p) =>
145 | 'postcssPlugin' in p && p.postcssPlugin !== 'tailwindcss',
146 | ) ?? [];
147 | postcssOptions = config.postcssOptions;
148 | }
149 | },
150 | },
151 | });
152 | },
153 | });
154 |
155 | api.modifyBundlerChain({
156 | order: 'post',
157 | handler(chain) {
158 | chain.plugin('tailwindcss').use(TailwindRspackPlugin, [
159 | {
160 | config: options.config ?? 'tailwind.config.js',
161 | include: options.include,
162 | exclude: options.exclude,
163 | postcssOptions,
164 | },
165 | ]);
166 | },
167 | });
168 | },
169 | });
170 |
171 | export { TailwindRspackPlugin } from './TailwindCSSRspackPlugin.js';
172 |
--------------------------------------------------------------------------------
/test/basic/index.test.ts:
--------------------------------------------------------------------------------
1 | import { existsSync } from 'node:fs';
2 | import { dirname, resolve } from 'node:path';
3 | import { fileURLToPath } from 'node:url';
4 | import { expect, test } from '@playwright/test';
5 | import { createRsbuild } from '@rsbuild/core';
6 | import { pluginTailwindCSS } from '../../src';
7 | import { getRandomPort } from '../helper';
8 |
9 | const __dirname = dirname(fileURLToPath(import.meta.url));
10 |
11 | test('should dev with tailwind utilities', async ({ page }) => {
12 | const rsbuild = await createRsbuild({
13 | cwd: __dirname,
14 | rsbuildConfig: {
15 | plugins: [pluginTailwindCSS()],
16 | server: {
17 | port: getRandomPort(),
18 | },
19 | },
20 | });
21 |
22 | const { server, urls } = await rsbuild.startDevServer();
23 |
24 | await page.goto(urls[0]);
25 |
26 | const display = await page.evaluate(() => {
27 | const el = document.getElementById('test');
28 |
29 | if (!el) {
30 | throw new Error('#test not found');
31 | }
32 |
33 | return window.getComputedStyle(el).getPropertyValue('display');
34 | });
35 |
36 | expect(display).toBe('flex');
37 |
38 | await server.close();
39 | });
40 |
41 | test('should build with tailwind utilities', async ({ page }) => {
42 | const rsbuild = await createRsbuild({
43 | cwd: __dirname,
44 | rsbuildConfig: {
45 | plugins: [pluginTailwindCSS()],
46 | server: {
47 | port: getRandomPort(),
48 | },
49 | },
50 | });
51 |
52 | await rsbuild.build();
53 | const { server, urls } = await rsbuild.preview();
54 |
55 | await page.goto(urls[0]);
56 |
57 | const display = await page.evaluate(() => {
58 | const el = document.getElementById('test');
59 |
60 | if (!el) {
61 | throw new Error('#test not found');
62 | }
63 |
64 | return window.getComputedStyle(el).getPropertyValue('display');
65 | });
66 |
67 | expect(display).toBe('flex');
68 |
69 | await server.close();
70 | });
71 |
72 | test('should not generate tailwind.config.js in dist/', async () => {
73 | const rsbuild = await createRsbuild({
74 | cwd: __dirname,
75 | rsbuildConfig: {
76 | plugins: [pluginTailwindCSS()],
77 | },
78 | });
79 |
80 | await rsbuild.build();
81 |
82 | expect(existsSync(resolve(__dirname, './dist/.rsbuild'))).toBeFalsy();
83 | });
84 |
85 | test('should dev with nested entry', async ({ page }) => {
86 | const rsbuild = await createRsbuild({
87 | cwd: __dirname,
88 | rsbuildConfig: {
89 | source: {
90 | entry: {
91 | 'nested/output/folder/bundle': resolve(__dirname, './src/index.js'),
92 | },
93 | },
94 | plugins: [pluginTailwindCSS()],
95 | server: {
96 | port: getRandomPort(),
97 | },
98 | },
99 | });
100 |
101 | const { server, urls } = await rsbuild.startDevServer();
102 |
103 | await page.goto(`${urls[0]}/nested/output/folder/bundle`);
104 |
105 | const display = await page.evaluate(() => {
106 | const el = document.getElementById('test');
107 | if (!el) {
108 | throw new Error('#test not found');
109 | }
110 |
111 | return window.getComputedStyle(el).getPropertyValue('display');
112 | });
113 |
114 | expect(display).toBe('flex');
115 |
116 | await server.close();
117 | });
118 |
--------------------------------------------------------------------------------
/test/basic/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/cjs/config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs"
3 | }
4 |
--------------------------------------------------------------------------------
/test/cjs/config/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {};
3 |
--------------------------------------------------------------------------------
/test/cjs/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname, resolve } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 | import { pluginTailwindCSS } from '../../src';
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with relative config', async ({ page }) => {
11 | const rsbuild = await createRsbuild({
12 | cwd: __dirname,
13 | rsbuildConfig: {
14 | plugins: [
15 | pluginTailwindCSS({
16 | config: './config/tailwind.config.js',
17 | }),
18 | ],
19 | server: {
20 | port: getRandomPort(),
21 | },
22 | },
23 | });
24 |
25 | await rsbuild.build();
26 | const { server, urls } = await rsbuild.preview();
27 |
28 | await page.goto(urls[0]);
29 |
30 | const display = await page.evaluate(() => {
31 | const el = document.getElementById('test');
32 |
33 | if (!el) {
34 | throw new Error('#test not found');
35 | }
36 |
37 | return window.getComputedStyle(el).getPropertyValue('display');
38 | });
39 |
40 | expect(display).toBe('flex');
41 |
42 | await server.close();
43 | });
44 |
45 | test('should build with absolute config', async ({ page }) => {
46 | const rsbuild = await createRsbuild({
47 | cwd: __dirname,
48 | rsbuildConfig: {
49 | plugins: [
50 | pluginTailwindCSS({
51 | config: resolve(__dirname, './config/tailwind.config.js'),
52 | }),
53 | ],
54 | server: {
55 | port: getRandomPort(),
56 | },
57 | },
58 | });
59 |
60 | await rsbuild.build();
61 | const { server, urls } = await rsbuild.preview();
62 |
63 | await page.goto(urls[0]);
64 |
65 | const display = await page.evaluate(() => {
66 | const el = document.getElementById('test');
67 |
68 | if (!el) {
69 | throw new Error('#test not found');
70 | }
71 |
72 | return window.getComputedStyle(el).getPropertyValue('display');
73 | });
74 |
75 | expect(display).toBe('flex');
76 |
77 | await server.close();
78 | });
79 |
80 | test('should build without tailwind.config.js', async ({ page }) => {
81 | const rsbuild = await createRsbuild({
82 | cwd: __dirname,
83 | rsbuildConfig: {
84 | server: {
85 | port: getRandomPort(),
86 | },
87 | plugins: [pluginTailwindCSS()],
88 | },
89 | });
90 |
91 | await rsbuild.build();
92 | const { server, urls } = await rsbuild.preview();
93 |
94 | await page.goto(urls[0]);
95 |
96 | const display = await page.evaluate(() => {
97 | const el = document.getElementById('test');
98 |
99 | if (!el) {
100 | throw new Error('#test not found');
101 | }
102 |
103 | return window.getComputedStyle(el).getPropertyValue('display');
104 | });
105 |
106 | expect(display).toBe('flex');
107 |
108 | await server.close();
109 | });
110 |
--------------------------------------------------------------------------------
/test/cjs/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/config/config/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {};
3 |
--------------------------------------------------------------------------------
/test/config/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname, resolve } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 | import { pluginTailwindCSS } from '../../src';
6 | import { supportESM, getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with relative config', async ({ page }) => {
11 | test.skip(
12 | !supportESM(),
13 | 'Skip since the tailwindcss version does not support ESM configuration',
14 | );
15 |
16 | const rsbuild = await createRsbuild({
17 | cwd: __dirname,
18 | rsbuildConfig: {
19 | plugins: [
20 | pluginTailwindCSS({
21 | config: './config/tailwind.config.js',
22 | }),
23 | ],
24 | server: {
25 | port: getRandomPort(),
26 | },
27 | },
28 | });
29 |
30 | await rsbuild.build();
31 | const { server, urls } = await rsbuild.preview();
32 |
33 | await page.goto(urls[0]);
34 |
35 | const display = await page.evaluate(() => {
36 | const el = document.getElementById('test');
37 |
38 | if (!el) {
39 | throw new Error('#test not found');
40 | }
41 |
42 | return window.getComputedStyle(el).getPropertyValue('display');
43 | });
44 |
45 | expect(display).toBe('flex');
46 |
47 | await server.close();
48 | });
49 |
50 | test('should build with absolute config', async ({ page }) => {
51 | test.skip(
52 | !supportESM(),
53 | 'Skip since the tailwindcss version does not support ESM configuration',
54 | );
55 |
56 | const rsbuild = await createRsbuild({
57 | cwd: __dirname,
58 | rsbuildConfig: {
59 | plugins: [
60 | pluginTailwindCSS({
61 | config: resolve(__dirname, './config/tailwind.config.js'),
62 | }),
63 | ],
64 | server: {
65 | port: getRandomPort(),
66 | },
67 | },
68 | });
69 |
70 | await rsbuild.build();
71 | const { server, urls } = await rsbuild.preview();
72 |
73 | await page.goto(urls[0]);
74 |
75 | const display = await page.evaluate(() => {
76 | const el = document.getElementById('test');
77 |
78 | if (!el) {
79 | throw new Error('#test not found');
80 | }
81 |
82 | return window.getComputedStyle(el).getPropertyValue('display');
83 | });
84 |
85 | expect(display).toBe('flex');
86 |
87 | await server.close();
88 | });
89 |
90 | test('should build without tailwind.config.js', async ({ page }) => {
91 | const rsbuild = await createRsbuild({
92 | cwd: __dirname,
93 | rsbuildConfig: {
94 | plugins: [pluginTailwindCSS()],
95 | server: {
96 | port: getRandomPort(),
97 | },
98 | },
99 | });
100 |
101 | await rsbuild.build();
102 | const { server, urls } = await rsbuild.preview();
103 |
104 | await page.goto(urls[0]);
105 |
106 | const display = await page.evaluate(() => {
107 | const el = document.getElementById('test');
108 |
109 | if (!el) {
110 | throw new Error('#test not found');
111 | }
112 |
113 | return window.getComputedStyle(el).getPropertyValue('display');
114 | });
115 |
116 | expect(display).toBe('flex');
117 |
118 | await server.close();
119 | });
120 |
--------------------------------------------------------------------------------
/test/config/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/exclude-include/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 |
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with included and excluded modules', async ({ page }) => {
11 | const { pluginTailwindCSS } = await import('../../src');
12 | const rsbuild = await createRsbuild({
13 | cwd: __dirname,
14 | rsbuildConfig: {
15 | plugins: [
16 | pluginTailwindCSS({
17 | include: './src/*.{js,jsx}',
18 | exclude: './src/exclude.js',
19 | }),
20 | ],
21 | server: {
22 | port: getRandomPort(),
23 | },
24 | },
25 | });
26 |
27 | await rsbuild.build();
28 | const { server, urls } = await rsbuild.preview();
29 |
30 | await page.goto(urls[0]);
31 |
32 | const display = await page.evaluate(() => {
33 | const el = document.getElementById('test');
34 |
35 | if (!el) {
36 | throw new Error('#test not found');
37 | }
38 |
39 | return window.getComputedStyle(el).getPropertyValue('display');
40 | });
41 |
42 | expect(display).toBe('flex');
43 |
44 | // Exclude
45 | {
46 | const textAlign = await page.evaluate(() => {
47 | const el = document.getElementById('exclude');
48 |
49 | if (!el) {
50 | throw new Error('#exclude not found');
51 | }
52 |
53 | return window.getComputedStyle(el).getPropertyValue('text-align');
54 | });
55 |
56 | expect(textAlign).not.toBe('center');
57 |
58 | // The `not-exclude.js` imported by `exclude.js` should not be excluded.
59 | const paddingTop = await page.evaluate(() => {
60 | const el = document.getElementById('not-exclude');
61 |
62 | if (!el) {
63 | throw new Error('#not-exclude not found');
64 | }
65 |
66 | return window.getComputedStyle(el).getPropertyValue('padding-top');
67 | });
68 |
69 | expect(paddingTop).toBe('16px');
70 | }
71 |
72 | // Include
73 | {
74 | const textAlign = await page.evaluate(() => {
75 | const el = document.getElementById('not-include');
76 |
77 | if (!el) {
78 | throw new Error('#not-include not found');
79 | }
80 |
81 | return window.getComputedStyle(el).getPropertyValue('text-align');
82 | });
83 |
84 | expect(textAlign).not.toBe('center');
85 |
86 | // The `include.js` imported by `not-include.ts` should be included.
87 | const paddingTop = await page.evaluate(() => {
88 | const el = document.getElementById('include');
89 |
90 | if (!el) {
91 | throw new Error('#include not found');
92 | }
93 |
94 | return window.getComputedStyle(el).getPropertyValue('padding-top');
95 | });
96 |
97 | expect(paddingTop).toBe('16px');
98 | }
99 | await server.close();
100 | });
101 |
--------------------------------------------------------------------------------
/test/exclude-include/src/exclude.js:
--------------------------------------------------------------------------------
1 | // The `not-exclude.js` imported by `exclude.js` should not be excluded.
2 | import './not-exclude.js';
3 |
4 | function className() {
5 | return 'text-center';
6 | }
7 |
8 | const root = document.getElementById('root');
9 | const element = document.createElement('div');
10 | element.id = 'exclude';
11 | element.className = className();
12 | root.appendChild(element);
13 |
--------------------------------------------------------------------------------
/test/exclude-include/src/include.jsx:
--------------------------------------------------------------------------------
1 | function className() {
2 | return 'pt-4';
3 | }
4 |
5 | const root = document.getElementById('root');
6 | const element = document.createElement('div');
7 | element.id = 'include';
8 | element.className = className();
9 | root.appendChild(element);
10 |
--------------------------------------------------------------------------------
/test/exclude-include/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | import './exclude.js';
4 | import './not-include.ts';
5 |
6 | function className() {
7 | return 'flex';
8 | }
9 |
10 | const root = document.getElementById('root');
11 | const element = document.createElement('div');
12 | element.id = 'test';
13 | element.className = className();
14 | root.appendChild(element);
15 |
--------------------------------------------------------------------------------
/test/exclude-include/src/not-exclude.js:
--------------------------------------------------------------------------------
1 | function className() {
2 | return 'pt-4';
3 | }
4 |
5 | const root = document.getElementById('root');
6 | const element = document.createElement('div');
7 | element.id = 'not-exclude';
8 | element.className = className();
9 | root.appendChild(element);
10 |
--------------------------------------------------------------------------------
/test/exclude-include/src/not-include.ts:
--------------------------------------------------------------------------------
1 | // The `include.jsx` imported by `not-include.ts` should not be excluded.
2 | import './include.jsx';
3 |
4 | function className() {
5 | return 'text-center';
6 | }
7 |
8 | const root = document.getElementById('root');
9 | const element = document.createElement('div');
10 | element.id = 'not-include';
11 | element.className = className();
12 | root?.appendChild(element);
13 |
--------------------------------------------------------------------------------
/test/exclude/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 |
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with excluded modules', async ({ page }) => {
11 | const { pluginTailwindCSS } = await import('../../src');
12 | const rsbuild = await createRsbuild({
13 | cwd: __dirname,
14 | rsbuildConfig: {
15 | plugins: [
16 | pluginTailwindCSS({
17 | exclude: ['./src/exclude.js'],
18 | }),
19 | ],
20 | server: {
21 | port: getRandomPort(),
22 | },
23 | },
24 | });
25 |
26 | await rsbuild.build();
27 | const { server, urls } = await rsbuild.preview();
28 |
29 | await page.goto(urls[0]);
30 |
31 | const display = await page.evaluate(() => {
32 | const el = document.getElementById('test');
33 |
34 | if (!el) {
35 | throw new Error('#test not found');
36 | }
37 |
38 | return window.getComputedStyle(el).getPropertyValue('display');
39 | });
40 |
41 | expect(display).toBe('flex');
42 |
43 | const textAlign = await page.evaluate(() => {
44 | const el = document.getElementById('exclude');
45 |
46 | if (!el) {
47 | throw new Error('#exclude not found');
48 | }
49 |
50 | return window.getComputedStyle(el).getPropertyValue('text-align');
51 | });
52 |
53 | expect(textAlign).not.toBe('center');
54 |
55 | // The `not-exclude.js` imported by `exclude.js` should not be excluded.
56 | const paddingTop = await page.evaluate(() => {
57 | const el = document.getElementById('not-exclude');
58 |
59 | if (!el) {
60 | throw new Error('#not-exclude not found');
61 | }
62 |
63 | return window.getComputedStyle(el).getPropertyValue('padding-top');
64 | });
65 |
66 | expect(paddingTop).toBe('16px');
67 |
68 | await server.close();
69 | });
70 |
--------------------------------------------------------------------------------
/test/exclude/src/exclude.js:
--------------------------------------------------------------------------------
1 | // The `not-exclude.js` imported by `exclude.js` should not be excluded.
2 | import './not-exclude.js';
3 |
4 | function className() {
5 | return 'text-center';
6 | }
7 |
8 | const root = document.getElementById('root');
9 | const element = document.createElement('div');
10 | element.id = 'exclude';
11 | element.className = className();
12 | root.appendChild(element);
13 |
--------------------------------------------------------------------------------
/test/exclude/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | import './exclude.js';
4 |
5 | function className() {
6 | return 'flex';
7 | }
8 |
9 | const root = document.getElementById('root');
10 | const element = document.createElement('div');
11 | element.id = 'test';
12 | element.className = className();
13 | root.appendChild(element);
14 |
--------------------------------------------------------------------------------
/test/exclude/src/not-exclude.js:
--------------------------------------------------------------------------------
1 | function className() {
2 | return 'pt-4';
3 | }
4 |
5 | const root = document.getElementById('root');
6 | const element = document.createElement('div');
7 | element.id = 'not-exclude';
8 | element.className = className();
9 | root.appendChild(element);
10 |
--------------------------------------------------------------------------------
/test/helper.ts:
--------------------------------------------------------------------------------
1 | import satisfies from 'semver/functions/satisfies.js';
2 | import pkg from 'tailwindcss/package.json' with { type: 'json' };
3 |
4 | const portMap = new Map();
5 |
6 | export function getRandomPort(
7 | defaultPort = Math.ceil(Math.random() * 30000) + 15000,
8 | ) {
9 | let port = defaultPort;
10 | while (true) {
11 | if (!portMap.get(port)) {
12 | portMap.set(port, 1);
13 | return port;
14 | }
15 | port++;
16 | }
17 | }
18 |
19 | export function supportESM(): boolean {
20 | // Tailwind CSS support using ESM configuration in v3.3.0
21 | // See:
22 | // - https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.3.0
23 | // - https://github.com/tailwindlabs/tailwindcss/pull/10785
24 | // - https://github.com/rspack-contrib/rsbuild-plugin-tailwindcss/issues/18
25 | return satisfies(pkg.version, '^3.3.0');
26 | }
27 |
--------------------------------------------------------------------------------
/test/include/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 |
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with included modules', async ({ page }) => {
11 | const { pluginTailwindCSS } = await import('../../src');
12 | const rsbuild = await createRsbuild({
13 | cwd: __dirname,
14 | rsbuildConfig: {
15 | plugins: [
16 | pluginTailwindCSS({
17 | include: './src/*.{js,jsx}',
18 | }),
19 | ],
20 | server: {
21 | port: getRandomPort(),
22 | },
23 | },
24 | });
25 |
26 | await rsbuild.build();
27 | const { server, urls } = await rsbuild.preview();
28 |
29 | await page.goto(urls[0]);
30 |
31 | const display = await page.evaluate(() => {
32 | const el = document.getElementById('test');
33 |
34 | if (!el) {
35 | throw new Error('#test not found');
36 | }
37 |
38 | return window.getComputedStyle(el).getPropertyValue('display');
39 | });
40 |
41 | expect(display).toBe('flex');
42 |
43 | const textAlign = await page.evaluate(() => {
44 | const el = document.getElementById('not-include');
45 |
46 | if (!el) {
47 | throw new Error('#not-include not found');
48 | }
49 |
50 | return window.getComputedStyle(el).getPropertyValue('text-align');
51 | });
52 |
53 | expect(textAlign).not.toBe('center');
54 |
55 | // The `include.js` imported by `not-include.ts` should be included.
56 | const paddingTop = await page.evaluate(() => {
57 | const el = document.getElementById('include');
58 |
59 | if (!el) {
60 | throw new Error('#include not found');
61 | }
62 |
63 | return window.getComputedStyle(el).getPropertyValue('padding-top');
64 | });
65 |
66 | expect(paddingTop).toBe('16px');
67 |
68 | await server.close();
69 | });
70 |
--------------------------------------------------------------------------------
/test/include/src/include.jsx:
--------------------------------------------------------------------------------
1 | function className() {
2 | return 'pt-4';
3 | }
4 |
5 | const root = document.getElementById('root');
6 | const element = document.createElement('div');
7 | element.id = 'include';
8 | element.className = className();
9 | root.appendChild(element);
10 |
--------------------------------------------------------------------------------
/test/include/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | import './not-include.ts';
4 |
5 | function className() {
6 | return 'flex';
7 | }
8 |
9 | const root = document.getElementById('root');
10 | const element = document.createElement('div');
11 | element.id = 'test';
12 | element.className = className();
13 | root.appendChild(element);
14 |
--------------------------------------------------------------------------------
/test/include/src/not-include.ts:
--------------------------------------------------------------------------------
1 | // The `include.jsx` imported by `not-include.ts` should not be excluded.
2 | import './include.jsx';
3 |
4 | function className() {
5 | return 'text-center';
6 | }
7 |
8 | const root = document.getElementById('root');
9 | const element = document.createElement('div');
10 | element.id = 'not-include';
11 | element.className = className();
12 | root?.appendChild(element);
13 |
--------------------------------------------------------------------------------
/test/isSubsetOf.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from '@playwright/test';
2 |
3 | import { isSubsetOf } from '../src/Set.prototype.isSubsetOf';
4 |
5 | test.describe('Set.prototype.isSubsetOf', () => {
6 | test('subsets', () => {
7 | const set1 = new Set([1, 2, 3]);
8 | const set2 = new Set([4, 5, 6]);
9 | const set3 = new Set([1, 2, 3, 4, 5, 6]);
10 |
11 | expect(isSubsetOf(set1, set2)).toBe(false);
12 | expect(isSubsetOf(set2, set1)).toBe(false);
13 | expect(isSubsetOf(set1, set3)).toBe(true);
14 | expect(isSubsetOf(set2, set3)).toBe(true);
15 | });
16 |
17 | test('empty sets', () => {
18 | const s1 = new Set([]);
19 | const s2 = new Set([1, 2]);
20 |
21 | expect(isSubsetOf(s1, s2)).toBe(true);
22 |
23 | const s3 = new Set([1, 2]);
24 | const s4 = new Set([]);
25 |
26 | expect(isSubsetOf(s3, s4)).toBe(false);
27 |
28 | const s5 = new Set([]);
29 | const s6 = new Set([]);
30 |
31 | expect(isSubsetOf(s5, s6)).toBe(true);
32 | });
33 |
34 | test('self', () => {
35 | const s1 = new Set([1, 2]);
36 |
37 | expect(isSubsetOf(s1, s1)).toBe(true);
38 | });
39 |
40 | test('same', () => {
41 | const s1 = new Set([1, 2]);
42 | const s2 = new Set([1, 2]);
43 |
44 | expect(isSubsetOf(s1, s2)).toBe(true);
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/test/multi-entries/a.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/multi-entries/b.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'w-8';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/multi-entries/c.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'px-4';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/multi-entries/d.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'z-20';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/multi-entries/e.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'justify-end';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/multi-entries/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 |
4 | import test, { expect } from '@playwright/test';
5 | import { createRsbuild } from '@rsbuild/core';
6 |
7 | import { pluginTailwindCSS } from '../../src';
8 | import { getRandomPort } from '../helper';
9 |
10 | const __dirname = dirname(fileURLToPath(import.meta.url));
11 |
12 | test('should dev with tailwind utilities in multiple entries', async ({
13 | page,
14 | }) => {
15 | const rsbuild = await createRsbuild({
16 | cwd: __dirname,
17 | rsbuildConfig: {
18 | dev: {
19 | writeToDisk: true,
20 | },
21 | source: {
22 | entry: {
23 | a: './a.js',
24 | b: './b.js',
25 | c: './c.js',
26 | d: './d.js',
27 | e: './e.js',
28 | },
29 | },
30 | plugins: [pluginTailwindCSS()],
31 | server: {
32 | port: getRandomPort(),
33 | },
34 | },
35 | });
36 |
37 | const { server, urls } = await rsbuild.startDevServer();
38 |
39 | await page.goto(`${urls[0]}/a`);
40 | let style = await getStyle();
41 | expect(style.display).toBe('flex'); // flex
42 | expect(style.width).not.toBe('32px'); // w-8
43 | expect(style.paddingLeft).not.toBe('0'); // px-4
44 | expect(style.paddingRight).not.toBe('0'); // px-4
45 | expect(style.zIndex).not.toBe('20'); // z-20
46 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
47 |
48 | await page.goto(`${urls[0]}/b`);
49 | style = await getStyle();
50 | expect(style.display).not.toBe('flex'); // flex
51 | expect(style.width).toBe('32px'); // w-8
52 | expect(style.paddingLeft).not.toBe('0'); // px-4
53 | expect(style.paddingRight).not.toBe('0'); // px-4
54 | expect(style.zIndex).not.toBe('20'); // z-20
55 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
56 |
57 | await page.goto(`${urls[0]}/c`);
58 | style = await getStyle();
59 | expect(style.display).not.toBe('flex'); // flex
60 | expect(style.width).not.toBe('32px'); // w-8
61 | expect(style.paddingLeft).toBe('16px'); // px-4
62 | expect(style.paddingRight).toBe('16px'); // px-4
63 | expect(style.zIndex).not.toBe('20'); // z-20
64 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
65 |
66 | await page.goto(`${urls[0]}/d`);
67 | style = await getStyle();
68 | expect(style.display).not.toBe('flex'); // flex
69 | expect(style.width).not.toBe('32px'); // w-8
70 | expect(style.paddingLeft).not.toBe('0'); // px-4
71 | expect(style.paddingRight).not.toBe('0'); // px-4
72 | expect(style.zIndex).toBe('20'); // z-20
73 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
74 |
75 | await page.goto(`${urls[0]}/e`);
76 | style = await getStyle();
77 | expect(style.display).not.toBe('flex'); // flex
78 | expect(style.width).not.toBe('32px'); // w-8
79 | expect(style.paddingLeft).not.toBe('0'); // px-4
80 | expect(style.paddingRight).not.toBe('0'); // px-4
81 | expect(style.zIndex).not.toBe('20'); // z-20
82 | expect(style.justifyContent).toBe('flex-end'); // justify-end
83 |
84 | await server.close();
85 |
86 | async function getStyle() {
87 | return await page.evaluate(() => {
88 | const el = document.getElementById('test');
89 |
90 | if (!el) {
91 | throw new Error('#test not found');
92 | }
93 |
94 | return window.getComputedStyle(el);
95 | });
96 | }
97 | });
98 |
99 | test('should build with tailwind utilities in multiple entries', async ({
100 | page,
101 | }) => {
102 | const rsbuild = await createRsbuild({
103 | cwd: __dirname,
104 | rsbuildConfig: {
105 | source: {
106 | entry: {
107 | a: './a.js',
108 | b: './b.js',
109 | c: './c.js',
110 | d: './d.js',
111 | e: './e.js',
112 | },
113 | },
114 | plugins: [pluginTailwindCSS()],
115 | server: {
116 | port: getRandomPort(),
117 | },
118 | },
119 | });
120 |
121 | await rsbuild.build();
122 | const { server, urls } = await rsbuild.preview();
123 |
124 | await page.goto(`${urls[0]}/a`);
125 | let style = await getStyle();
126 | expect(style.display).toBe('flex'); // flex
127 | expect(style.width).not.toBe('32px'); // w-8
128 | expect(style.paddingLeft).not.toBe('0'); // px-4
129 | expect(style.paddingRight).not.toBe('0'); // px-4
130 | expect(style.zIndex).not.toBe('20'); // z-20
131 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
132 |
133 | await page.goto(`${urls[0]}/b`);
134 | style = await getStyle();
135 | expect(style.display).not.toBe('flex'); // flex
136 | expect(style.width).toBe('32px'); // w-8
137 | expect(style.paddingLeft).not.toBe('0'); // px-4
138 | expect(style.paddingRight).not.toBe('0'); // px-4
139 | expect(style.zIndex).not.toBe('20'); // z-20
140 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
141 |
142 | await page.goto(`${urls[0]}/c`);
143 | style = await getStyle();
144 | expect(style.display).not.toBe('flex'); // flex
145 | expect(style.width).not.toBe('32px'); // w-8
146 | expect(style.paddingLeft).toBe('16px'); // px-4
147 | expect(style.paddingRight).toBe('16px'); // px-4
148 | expect(style.zIndex).not.toBe('20'); // z-20
149 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
150 |
151 | await page.goto(`${urls[0]}/d`);
152 | style = await getStyle();
153 | expect(style.display).not.toBe('flex'); // flex
154 | expect(style.width).not.toBe('32px'); // w-8
155 | expect(style.paddingLeft).not.toBe('0'); // px-4
156 | expect(style.paddingRight).not.toBe('0'); // px-4
157 | expect(style.zIndex).toBe('20'); // z-20
158 | expect(style.justifyContent).not.toBe('flex-end'); // justify-end
159 |
160 | await page.goto(`${urls[0]}/e`);
161 | style = await getStyle();
162 | expect(style.display).not.toBe('flex'); // flex
163 | expect(style.width).not.toBe('32px'); // w-8
164 | expect(style.paddingLeft).not.toBe('0'); // px-4
165 | expect(style.paddingRight).not.toBe('0'); // px-4
166 | expect(style.zIndex).not.toBe('20'); // z-20
167 | expect(style.justifyContent).toBe('flex-end'); // justify-end
168 |
169 | await server.close();
170 |
171 | async function getStyle() {
172 | return await page.evaluate(() => {
173 | const el = document.getElementById('test');
174 |
175 | if (!el) {
176 | throw new Error('#test not found');
177 | }
178 |
179 | return window.getComputedStyle(el);
180 | });
181 | }
182 | });
183 |
--------------------------------------------------------------------------------
/test/postcss-config/flex-to-grid.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @returns {import('postcss').AcceptedPlugin}
3 | */
4 | export default function () {
5 | return {
6 | postcssPlugin: 'flex-to-grid',
7 | Declaration: {
8 | display(decl) {
9 | if (decl.value === 'flex') {
10 | decl.value = 'grid';
11 | }
12 | },
13 | },
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/test/postcss-config/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 | import { pluginTailwindCSS } from '../../src';
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with postcss.config.js', async ({ page }) => {
11 | const rsbuild = await createRsbuild({
12 | cwd: __dirname,
13 | rsbuildConfig: {
14 | plugins: [pluginTailwindCSS()],
15 | server: {
16 | port: getRandomPort(),
17 | },
18 | },
19 | });
20 |
21 | await rsbuild.build();
22 | const { server, urls } = await rsbuild.preview();
23 |
24 | await page.goto(urls[0]);
25 |
26 | const display = await page.evaluate(() => {
27 | const el = document.getElementById('test');
28 |
29 | if (!el) {
30 | throw new Error('#test not found');
31 | }
32 |
33 | return window.getComputedStyle(el).getPropertyValue('display');
34 | });
35 |
36 | expect(display).toBe('grid');
37 |
38 | await server.close();
39 | });
40 |
--------------------------------------------------------------------------------
/test/postcss-config/postcss.config.js:
--------------------------------------------------------------------------------
1 | import tailwindcss from 'tailwindcss';
2 | import flexToGrid from './flex-to-grid';
3 |
4 | export default {
5 | plugins: [tailwindcss(), flexToGrid()],
6 | };
7 |
--------------------------------------------------------------------------------
/test/postcss-config/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/tools-postcss/flex-to-grid.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @returns {import('postcss').AcceptedPlugin}
3 | */
4 | export default function () {
5 | return {
6 | postcssPlugin: 'flex-to-grid',
7 | Declaration: {
8 | display(decl) {
9 | if (decl.value === 'flex') {
10 | decl.value = 'grid';
11 | }
12 | },
13 | },
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/test/tools-postcss/index.test.ts:
--------------------------------------------------------------------------------
1 | import { dirname } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { expect, test } from '@playwright/test';
4 | import { createRsbuild } from '@rsbuild/core';
5 | import { pluginTailwindCSS } from '../../src';
6 | import { getRandomPort } from '../helper';
7 |
8 | const __dirname = dirname(fileURLToPath(import.meta.url));
9 |
10 | test('should build with tools.postcss with tailwindcss', async ({ page }) => {
11 | const { default: tailwindcss } = await import('tailwindcss');
12 | const rsbuild = await createRsbuild({
13 | cwd: __dirname,
14 | rsbuildConfig: {
15 | plugins: [pluginTailwindCSS()],
16 | tools: {
17 | postcss: {
18 | postcssOptions: {
19 | plugins: [tailwindcss()],
20 | },
21 | },
22 | },
23 | server: {
24 | port: getRandomPort(),
25 | },
26 | },
27 | });
28 |
29 | await rsbuild.build();
30 | const { server, urls } = await rsbuild.preview();
31 |
32 | await page.goto(urls[0]);
33 |
34 | const display = await page.evaluate(() => {
35 | const el = document.getElementById('test');
36 |
37 | if (!el) {
38 | throw new Error('#test not found');
39 | }
40 |
41 | return window.getComputedStyle(el).getPropertyValue('display');
42 | });
43 |
44 | expect(display).toBe('flex');
45 |
46 | await server.close();
47 | });
48 |
49 | test('should build with tools.postcss with custom plugin', async ({ page }) => {
50 | const { default: tailwindcss } = await import('tailwindcss');
51 | const { default: flexToGrid } = await import('./flex-to-grid.js');
52 | const rsbuild = await createRsbuild({
53 | cwd: __dirname,
54 | rsbuildConfig: {
55 | plugins: [pluginTailwindCSS()],
56 | tools: {
57 | postcss: {
58 | postcssOptions: {
59 | plugins: [flexToGrid()],
60 | },
61 | },
62 | },
63 | server: {
64 | port: getRandomPort(),
65 | },
66 | },
67 | });
68 |
69 | await rsbuild.build();
70 | const { server, urls } = await rsbuild.preview();
71 |
72 | await page.goto(urls[0]);
73 |
74 | const display = await page.evaluate(() => {
75 | const el = document.getElementById('test');
76 |
77 | if (!el) {
78 | throw new Error('#test not found');
79 | }
80 |
81 | return window.getComputedStyle(el).getPropertyValue('display');
82 | });
83 |
84 | expect(display).toBe('grid');
85 |
86 | await server.close();
87 | });
88 |
--------------------------------------------------------------------------------
/test/tools-postcss/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/test/with-resource-query/index.test.ts:
--------------------------------------------------------------------------------
1 | import { existsSync } from 'node:fs';
2 | import { dirname, resolve } from 'node:path';
3 | import { fileURLToPath } from 'node:url';
4 | import { expect, test } from '@playwright/test';
5 | import { createRsbuild } from '@rsbuild/core';
6 | import { webpackProvider } from '@rsbuild/webpack';
7 | import { pluginTailwindCSS } from '../../src';
8 | import { getRandomPort } from '../helper';
9 |
10 | const __dirname = dirname(fileURLToPath(import.meta.url));
11 |
12 | test('should dev with resource query on rspack', async ({ page }) => {
13 | const rsbuild = await createRsbuild({
14 | cwd: __dirname,
15 | rsbuildConfig: {
16 | source: {
17 | entry: {
18 | index: resolve(__dirname, './src/index.js?entry'),
19 | },
20 | },
21 | plugins: [pluginTailwindCSS()],
22 | server: {
23 | port: getRandomPort(),
24 | },
25 | },
26 | });
27 |
28 | const { server, urls } = await rsbuild.startDevServer();
29 |
30 | await page.goto(urls[0]);
31 |
32 | const display = await page.evaluate(() => {
33 | const el = document.getElementById('test');
34 |
35 | if (!el) {
36 | throw new Error('#test not found');
37 | }
38 |
39 | return window.getComputedStyle(el).getPropertyValue('display');
40 | });
41 |
42 | expect(display).toBe('flex');
43 |
44 | await server.close();
45 | });
46 |
47 | test('should build with resource query on rspack', async ({ page }) => {
48 | const rsbuild = await createRsbuild({
49 | cwd: __dirname,
50 | rsbuildConfig: {
51 | source: {
52 | entry: {
53 | index: resolve(__dirname, './src/index.js?entry'),
54 | },
55 | },
56 | server: {
57 | port: getRandomPort(),
58 | },
59 | plugins: [pluginTailwindCSS()],
60 | },
61 | });
62 |
63 | await rsbuild.build();
64 | const { server, urls } = await rsbuild.preview();
65 |
66 | await page.goto(urls[0]);
67 |
68 | const display = await page.evaluate(() => {
69 | const el = document.getElementById('test');
70 |
71 | if (!el) {
72 | throw new Error('#test not found');
73 | }
74 |
75 | return window.getComputedStyle(el).getPropertyValue('display');
76 | });
77 |
78 | expect(display).toBe('flex');
79 |
80 | await server.close();
81 | });
82 |
83 | test('should dev with resource query on webpack', async ({ page }) => {
84 | const rsbuild = await createRsbuild({
85 | cwd: __dirname,
86 | rsbuildConfig: {
87 | provider: webpackProvider,
88 | source: {
89 | entry: {
90 | index: resolve(__dirname, './src/index.js?entry'),
91 | },
92 | },
93 | plugins: [pluginTailwindCSS()],
94 | server: {
95 | port: getRandomPort(),
96 | },
97 | },
98 | });
99 |
100 | const { server, urls } = await rsbuild.startDevServer();
101 |
102 | await page.goto(urls[0]);
103 |
104 | const display = await page.evaluate(() => {
105 | const el = document.getElementById('test');
106 |
107 | if (!el) {
108 | throw new Error('#test not found');
109 | }
110 |
111 | return window.getComputedStyle(el).getPropertyValue('display');
112 | });
113 |
114 | expect(display).toBe('flex');
115 |
116 | await server.close();
117 | });
118 |
119 | test('should build with resource query on webpack', async ({ page }) => {
120 | const rsbuild = await createRsbuild({
121 | cwd: __dirname,
122 | rsbuildConfig: {
123 | source: {
124 | entry: {
125 | index: resolve(__dirname, './src/index.js?entry'),
126 | },
127 | },
128 | server: {
129 | port: getRandomPort(),
130 | },
131 | provider: webpackProvider,
132 | plugins: [pluginTailwindCSS()],
133 | },
134 | });
135 |
136 | await rsbuild.build();
137 | const { server, urls } = await rsbuild.preview();
138 |
139 | await page.goto(urls[0]);
140 |
141 | const display = await page.evaluate(() => {
142 | const el = document.getElementById('test');
143 |
144 | if (!el) {
145 | throw new Error('#test not found');
146 | }
147 |
148 | return window.getComputedStyle(el).getPropertyValue('display');
149 | });
150 |
151 | expect(display).toBe('flex');
152 |
153 | await server.close();
154 | });
155 |
--------------------------------------------------------------------------------
/test/with-resource-query/src/index.js:
--------------------------------------------------------------------------------
1 | import 'tailwindcss/utilities.css';
2 |
3 | function className() {
4 | return 'flex';
5 | }
6 |
7 | const root = document.getElementById('root');
8 | const element = document.createElement('div');
9 | element.id = 'test';
10 | element.className = className();
11 | root.appendChild(element);
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "baseUrl": "./",
5 | "target": "ES2021",
6 | "lib": ["DOM", "ES2021", "ESNext.Collection"],
7 | "module": "Node16",
8 | "moduleResolution": "Node16",
9 | "strict": true,
10 | "declaration": true,
11 | "isolatedModules": true,
12 | "isolatedDeclarations": true,
13 | "esModuleInterop": true,
14 | "skipLibCheck": true,
15 | "exactOptionalPropertyTypes": true,
16 | "resolveJsonModule": true
17 | },
18 | "include": ["src"]
19 | }
20 |
--------------------------------------------------------------------------------