You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/02/25 18:00:25 UTC
(superset) 01/01: feat(docs): add filterable UI Components table and improve build performance
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch feat/docs-component-index-and-build-perf
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 5b6f116cb4c7487474e83414a8692f25d6f3ca7f
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Wed Feb 25 09:58:02 2026 -0800
feat(docs): add filterable UI Components table and improve build performance
- Add interactive ComponentIndex table with stats cards, search, category
filters, and sortable columns (modeled after DatabaseIndex)
- Consolidate extension components into main generator, eliminating the
separate generate-extension-components job
- Enable Docusaurus Faster (Rspack bundler, SWC, SSG worker threads,
persistent cache) for significantly improved build performance
- Add smart generator caching (generate-if-changed.mjs) that skips
unchanged generators in ~45ms, making `yarn start` as fast as
`yarn start:quick` when no source files have changed
- Inline per-page database data in generated MDX to reduce webpack
module graph size during SSR
- Remove unused babel.config.js (SWC handles transpilation)
- Remove redundant webpack filesystem cache (Rspack handles caching)
- Remove DEBUG=docusaurus:* from build script
Co-Authored-By: Claude Sonnet 4.6 <no...@anthropic.com>
---
docs/.gitignore | 3 +
docs/developer_portal/extensions/development.md | 2 +-
docs/developer_portal/extensions/overview.md | 4 +
docs/docs/api.mdx | 36 +-
docs/docusaurus.config.ts | 10 +
docs/package.json | 11 +-
docs/scripts/generate-database-docs.mjs | 8 +-
docs/scripts/generate-extension-components.mjs | 31 +-
docs/scripts/generate-if-changed.mjs | 306 ++++++++++++++++
docs/scripts/generate-superset-components.mjs | 211 +++++++++--
docs/sidebarTutorials.js | 11 -
docs/src/components/databases/DatabaseIndex.tsx | 1 +
.../components/ui-components/ComponentIndex.tsx | 262 ++++++++++++++
.../components/ui-components/index.ts} | 15 +-
.../ui-components/types.ts} | 37 +-
docs/src/data/databases.json | 2 +-
docs/src/types/apache-superset-core/index.d.ts | 4 +-
docs/src/webpack.extend.ts | 6 -
docs/tsconfig.json | 2 +-
docs/yarn.lock | 395 ++++++++++++++++++++-
20 files changed, 1236 insertions(+), 121 deletions(-)
diff --git a/docs/.gitignore b/docs/.gitignore
index 37df51ce524..ca7a95ebf9c 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -44,3 +44,6 @@ developer_portal/extensions/components/
# Note: src/data/databases.json is COMMITTED (not ignored) to preserve feature diagnostics
# that require Flask context to generate. Update it locally with: npm run gen-db-docs
+
+# Generated component metadata JSON (regenerated by generate-superset-components.mjs)
+static/data/components.json
diff --git a/docs/developer_portal/extensions/development.md b/docs/developer_portal/extensions/development.md
index a6c143a3796..80cf193ecb0 100644
--- a/docs/developer_portal/extensions/development.md
+++ b/docs/developer_portal/extensions/development.md
@@ -299,7 +299,7 @@ InteractiveMyComponent.argTypes = {
When the docs site is built (`yarn start` or `yarn build` in the `docs/` directory):
-1. The `generate-extension-components` script scans all stories in `superset-core`
+1. The `generate-superset-components` script scans all stories (including `superset-core`)
2. For each story, it generates an MDX page with:
- Component description
- **Live interactive example** with controls extracted from `argTypes`
diff --git a/docs/developer_portal/extensions/overview.md b/docs/developer_portal/extensions/overview.md
index 175fa9701ca..be8628836d8 100644
--- a/docs/developer_portal/extensions/overview.md
+++ b/docs/developer_portal/extensions/overview.md
@@ -41,6 +41,10 @@ Extensions can provide:
- **REST API Endpoints**: Backend services under the `/api/v1/extensions/` namespace
- **MCP Tools and Prompts**: AI agent capabilities for enhanced user assistance
+## UI Components for Extensions
+
+Extension developers have access to pre-built UI components via `@apache-superset/core/ui`. Browse all available components on the [UI Components](/docs/components/) page and filter by **Extension Compatible** to see components available to extensions.
+
## Next Steps
- **[Quick Start](./quick-start)** - Build your first extension with a complete walkthrough
diff --git a/docs/docs/api.mdx b/docs/docs/api.mdx
index ff563805a8e..09f3843087f 100644
--- a/docs/docs/api.mdx
+++ b/docs/docs/api.mdx
@@ -68,14 +68,14 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| `POST` | [Create a new dashboard](./api/create-a-new-dashboard) | `/api/v1/dashboard/` |
| `GET` | [Get metadata information about this API resource (dashboard--info)](./api/get-metadata-information-about-this-api-resource-dashboard-info) | `/api/v1/dashboard/_info` |
| `GET` | [Get a dashboard detail information](./api/get-a-dashboard-detail-information) | `/api/v1/dashboard/{id_or_slug}` |
-| `GET` | [Get a dashboard's chart definitions.](./api/get-a-dashboards-chart-definitions) | `/api/v1/dashboard/{id_or_slug}/charts` |
+| `GET` | [Get a dashboard's chart definitions.](./api/get-a-dashboard-s-chart-definitions) | `/api/v1/dashboard/{id_or_slug}/charts` |
| `POST` | [Create a copy of an existing dashboard](./api/create-a-copy-of-an-existing-dashboard) | `/api/v1/dashboard/{id_or_slug}/copy/` |
-| `GET` | [Get dashboard's datasets](./api/get-dashboards-datasets) | `/api/v1/dashboard/{id_or_slug}/datasets` |
-| `DELETE` | [Delete a dashboard's embedded configuration](./api/delete-a-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
-| `GET` | [Get the dashboard's embedded configuration](./api/get-the-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
-| `POST` | [Set a dashboard's embedded configuration](./api/set-a-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
+| `GET` | [Get dashboard's datasets](./api/get-dashboard-s-datasets) | `/api/v1/dashboard/{id_or_slug}/datasets` |
+| `DELETE` | [Delete a dashboard's embedded configuration](./api/delete-a-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
+| `GET` | [Get the dashboard's embedded configuration](./api/get-the-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
+| `POST` | [Set a dashboard's embedded configuration](./api/set-a-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` |
| `PUT` | [Update dashboard by id_or_slug embedded](./api/update-dashboard-by-id-or-slug-embedded) | `/api/v1/dashboard/{id_or_slug}/embedded` |
-| `GET` | [Get dashboard's tabs](./api/get-dashboards-tabs) | `/api/v1/dashboard/{id_or_slug}/tabs` |
+| `GET` | [Get dashboard's tabs](./api/get-dashboard-s-tabs) | `/api/v1/dashboard/{id_or_slug}/tabs` |
| `DELETE` | [Delete a dashboard](./api/delete-a-dashboard) | `/api/v1/dashboard/{pk}` |
| `PUT` | [Update a dashboard](./api/update-a-dashboard) | `/api/v1/dashboard/{pk}` |
| `POST` | [Compute and cache a screenshot (dashboard-pk-cache-dashboard-screenshot)](./api/compute-and-cache-a-screenshot-dashboard-pk-cache-dashboard-screenshot) | `/api/v1/dashboard/{pk}/cache_dashboard_screenshot/` |
@@ -84,7 +84,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| `POST` | [Mark the dashboard as favorite for the current user](./api/mark-the-dashboard-as-favorite-for-the-current-user) | `/api/v1/dashboard/{pk}/favorites/` |
| `PUT` | [Update native filters configuration for a dashboard.](./api/update-native-filters-configuration-for-a-dashboard) | `/api/v1/dashboard/{pk}/filters` |
| `GET` | [Get a computed screenshot from cache (dashboard-pk-screenshot-digest)](./api/get-a-computed-screenshot-from-cache-dashboard-pk-screenshot-digest) | `/api/v1/dashboard/{pk}/screenshot/{digest}/` |
-| `GET` | [Get dashboard's thumbnail](./api/get-dashboards-thumbnail) | `/api/v1/dashboard/{pk}/thumbnail/{digest}/` |
+| `GET` | [Get dashboard's thumbnail](./api/get-dashboard-s-thumbnail) | `/api/v1/dashboard/{pk}/thumbnail/{digest}/` |
| `GET` | [Download multiple dashboards as YAML files](./api/download-multiple-dashboards-as-yaml-files) | `/api/v1/dashboard/export/` |
| `GET` | [Check favorited dashboards for current user](./api/check-favorited-dashboards-for-current-user) | `/api/v1/dashboard/favorite_status/` |
| `POST` | [Import dashboard(s) with associated charts/datasets/databases](./api/import-dashboard-s-with-associated-charts-datasets-databases) | `/api/v1/dashboard/import/` |
@@ -177,7 +177,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| `GET` | [Get names of databases currently available](./api/get-names-of-databases-currently-available) | `/api/v1/database/available/` |
| `GET` | [Download database(s) and associated dataset(s) as a zip file](./api/download-database-s-and-associated-dataset-s-as-a-zip-file) | `/api/v1/database/export/` |
| `POST` | [Import database(s) with associated datasets](./api/import-database-s-with-associated-datasets) | `/api/v1/database/import/` |
-| `GET` | [Receive personal access tokens from OAuth2](./api/receive-personal-access-tokens-from-o-auth-2) | `/api/v1/database/oauth2/` |
+| `GET` | [Receive personal access tokens from OAuth2](./api/receive-personal-access-tokens-from-oauth2) | `/api/v1/database/oauth2/` |
| `GET` | [Get related fields data (database-related-column-name)](./api/get-related-fields-data-database-related-column-name) | `/api/v1/database/related/{column_name}` |
| `POST` | [Test a database connection](./api/test-a-database-connection) | `/api/v1/database/test_connection/` |
| `POST` | [Upload a file and returns file metadata](./api/upload-a-file-and-returns-file-metadata) | `/api/v1/database/upload_metadata/` |
@@ -201,7 +201,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
-| `GET` | [Get the bootstrap data for SqlLab page](./api/get-the-bootstrap-data-for-sql-lab-page) | `/api/v1/sqllab/` |
+| `GET` | [Get the bootstrap data for SqlLab page](./api/get-the-bootstrap-data-for-sqllab-page) | `/api/v1/sqllab/` |
| `POST` | [Estimate the SQL query execution cost](./api/estimate-the-sql-query-execution-cost) | `/api/v1/sqllab/estimate/` |
| `POST` | [Execute a SQL query](./api/execute-a-sql-query) | `/api/v1/sqllab/execute/` |
| `GET` | [Export the SQL query results to a CSV](./api/export-the-sql-query-results-to-a-csv) | `/api/v1/sqllab/export/{client_id}/` |
@@ -249,7 +249,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
-| `GET` | [Return an AdvancedDataTypeResponse](./api/return-an-advanced-data-type-response) | `/api/v1/advanced_data_type/convert` |
+| `GET` | [Return an AdvancedDataTypeResponse](./api/return-an-advanceddatatyperesponse) | `/api/v1/advanced_data_type/convert` |
| `GET` | [Return a list of available advanced data types](./api/return-a-list-of-available-advanced-data-types) | `/api/v1/advanced_data_type/types` |
</details>
@@ -324,8 +324,8 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
-| `POST` | [Create a new dashboard's permanent link](./api/create-a-new-dashboards-permanent-link) | `/api/v1/dashboard/{pk}/permalink` |
-| `GET` | [Get dashboard's permanent link state](./api/get-dashboards-permanent-link-state) | `/api/v1/dashboard/permalink/{key}` |
+| `POST` | [Create a new dashboard's permanent link](./api/create-a-new-dashboard-s-permanent-link) | `/api/v1/dashboard/{pk}/permalink` |
+| `GET` | [Get dashboard's permanent link state](./api/get-dashboard-s-permanent-link-state) | `/api/v1/dashboard/permalink/{key}` |
</details>
@@ -335,7 +335,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | [Create a new permanent link (explore-permalink)](./api/create-a-new-permanent-link-explore-permalink) | `/api/v1/explore/permalink` |
-| `GET` | [Get chart's permanent link state](./api/get-charts-permanent-link-state) | `/api/v1/explore/permalink/{key}` |
+| `GET` | [Get chart's permanent link state](./api/get-chart-s-permanent-link-state) | `/api/v1/explore/permalink/{key}` |
</details>
@@ -345,7 +345,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | [Create a new permanent link (sqllab-permalink)](./api/create-a-new-permanent-link-sqllab-permalink) | `/api/v1/sqllab/permalink` |
-| `GET` | [Get permanent link state for SQLLab editor.](./api/get-permanent-link-state-for-sql-lab-editor) | `/api/v1/sqllab/permalink/{key}` |
+| `GET` | [Get permanent link state for SQLLab editor.](./api/get-permanent-link-state-for-sqllab-editor) | `/api/v1/sqllab/permalink/{key}` |
</details>
@@ -363,10 +363,10 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
| Method | Endpoint | Description |
|--------|----------|-------------|
-| `POST` | [Create a dashboard's filter state](./api/create-a-dashboards-filter-state) | `/api/v1/dashboard/{pk}/filter_state` |
-| `DELETE` | [Delete a dashboard's filter state value](./api/delete-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
-| `GET` | [Get a dashboard's filter state value](./api/get-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
-| `PUT` | [Update a dashboard's filter state value](./api/update-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
+| `POST` | [Create a dashboard's filter state](./api/create-a-dashboard-s-filter-state) | `/api/v1/dashboard/{pk}/filter_state` |
+| `DELETE` | [Delete a dashboard's filter state value](./api/delete-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
+| `GET` | [Get a dashboard's filter state value](./api/get-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
+| `PUT` | [Update a dashboard's filter state value](./api/update-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` |
</details>
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 336b44d0edd..2af419a98f5 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -166,6 +166,16 @@ if (!versionsConfig.developer_portal.disabled && !versionsConfig.developer_porta
}
const config: Config = {
+ future: {
+ v4: {
+ // Required by experimental_faster.ssgWorkerThreads
+ removeLegacyPostBuildHeadAttribute: true,
+ // Disabled: CSS cascade layers change specificity and cause antd
+ // styles (from Storybook component pages) to override theme styles
+ useCssCascadeLayers: false,
+ },
+ experimental_faster: true,
+ },
title: 'Superset',
tagline:
'Apache Superset is a modern data exploration and visualization platform',
diff --git a/docs/package.json b/docs/package.json
index 484432a7666..9af70da940d 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -6,10 +6,12 @@
"scripts": {
"docusaurus": "docusaurus",
"_init": "cat src/intro_header.txt ../README.md > docs/intro.md",
- "start": "yarn run _init && yarn run generate:all && NODE_OPTIONS='--max-old-space-size=8192' NODE_ENV=development docusaurus start",
+ "start": "yarn run _init && yarn run generate:smart && NODE_OPTIONS='--max-old-space-size=8192' NODE_ENV=development docusaurus start",
"start:quick": "yarn run _init && NODE_OPTIONS='--max-old-space-size=8192' NODE_ENV=development docusaurus start",
+ "start:full": "yarn run _init && yarn run generate:all && NODE_OPTIONS='--max-old-space-size=8192' NODE_ENV=development docusaurus start",
"stop": "pkill -f 'docusaurus start' || pkill -f 'docusaurus serve' || echo 'No docusaurus server running'",
- "build": "yarn run _init && yarn run generate:all && NODE_OPTIONS='--max-old-space-size=8192' DEBUG=docusaurus:* docusaurus build",
+ "build": "yarn run _init && yarn run generate:smart && NODE_OPTIONS='--max-old-space-size=8192' docusaurus build",
+ "build:full": "yarn run _init && yarn run generate:all && NODE_OPTIONS='--max-old-space-size=8192' docusaurus build",
"generate:api-docs": "python3 scripts/fix-openapi-spec.py && docusaurus gen-api-docs superset && node scripts/convert-api-sidebar.mjs && node scripts/generate-api-index.mjs && node scripts/generate-api-tag-pages.mjs",
"clean:api-docs": "docusaurus clean-api-docs superset",
"swizzle": "docusaurus swizzle",
@@ -19,11 +21,11 @@
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "yarn run generate:all && tsc",
- "generate:extension-components": "node scripts/generate-extension-components.mjs",
"generate:superset-components": "node scripts/generate-superset-components.mjs",
"generate:database-docs": "node scripts/generate-database-docs.mjs",
"gen-db-docs": "node scripts/generate-database-docs.mjs",
- "generate:all": "yarn run generate:extension-components & yarn run generate:superset-components & yarn run generate:database-docs & wait && yarn run generate:api-docs",
+ "generate:smart": "node scripts/generate-if-changed.mjs",
+ "generate:all": "node scripts/generate-if-changed.mjs --force",
"lint:db-metadata": "python3 ../superset/db_engine_specs/lint_metadata.py",
"lint:db-metadata:report": "python3 ../superset/db_engine_specs/lint_metadata.py --markdown -o ../superset/db_engine_specs/METADATA_STATUS.md",
"update:readme-db-logos": "node scripts/generate-database-docs.mjs --update-readme",
@@ -40,6 +42,7 @@
"dependencies": {
"@ant-design/icons": "^6.1.0",
"@docusaurus/core": "3.9.2",
+ "@docusaurus/faster": "^3.9.2",
"@docusaurus/plugin-client-redirects": "3.9.2",
"@docusaurus/preset-classic": "3.9.2",
"@docusaurus/theme-live-codeblock": "^3.9.2",
diff --git a/docs/scripts/generate-database-docs.mjs b/docs/scripts/generate-database-docs.mjs
index 912569294ee..bc412571448 100644
--- a/docs/scripts/generate-database-docs.mjs
+++ b/docs/scripts/generate-database-docs.mjs
@@ -460,6 +460,9 @@ function generateDatabaseMDX(name, db) {
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"');
+ // Inline the database data directly to avoid importing the full databases.json
+ const inlineData = JSON.stringify(db);
+
return `---
title: ${name}
sidebar_label: ${name}
@@ -487,9 +490,10 @@ under the License.
*/}
import { DatabasePage } from '@site/src/components/databases';
-import databaseData from '@site/src/data/databases.json';
-<DatabasePage name="${name}" database={databaseData.databases["${name}"]} />
+export const databaseInfo = ${inlineData};
+
+<DatabasePage name="${name}" database={databaseInfo} />
`;
}
diff --git a/docs/scripts/generate-extension-components.mjs b/docs/scripts/generate-extension-components.mjs
index c7bed4901c1..efc60b5d863 100644
--- a/docs/scripts/generate-extension-components.mjs
+++ b/docs/scripts/generate-extension-components.mjs
@@ -634,30 +634,9 @@ async function main() {
console.log(`\nFound ${components.length} extension-compatible components\n`);
- // Ensure output directory exists
- if (!fs.existsSync(OUTPUT_DIR)) {
- fs.mkdirSync(OUTPUT_DIR, { recursive: true });
- console.log(`Created directory: ${OUTPUT_DIR}\n`);
- }
-
- // Generate MDX files
- for (const component of components) {
- // Read the story content for extracting args/controls
- const storyContent = fs.readFileSync(component.filePath, 'utf-8');
- const mdxContent = generateMDX(component, storyContent);
- const outputPath = path.join(
- OUTPUT_DIR,
- `${component.componentName.toLowerCase()}.mdx`
- );
- fs.writeFileSync(outputPath, mdxContent);
- console.log(` Generated: ${path.relative(DOCS_DIR, outputPath)}`);
- }
-
- // Generate index page
- const indexContent = generateIndexMDX(components);
- const indexPath = path.join(OUTPUT_DIR, 'index.mdx');
- fs.writeFileSync(indexPath, indexContent);
- console.log(` Generated: ${path.relative(DOCS_DIR, indexPath)}`);
+ // MDX generation is handled by generate-superset-components.mjs
+ // which consolidates all components (including extension) under UI Components.
+ console.log(' Skipping MDX generation (handled by generate-superset-components.mjs)');
// Generate type declarations
if (!fs.existsSync(TYPES_OUTPUT_DIR)) {
@@ -667,9 +646,9 @@ async function main() {
fs.writeFileSync(TYPES_OUTPUT_PATH, typesContent);
console.log(` Generated: ${path.relative(DOCS_DIR, TYPES_OUTPUT_PATH)}`);
- console.log('\nDone! Extension component documentation generated.');
+ console.log('\nDone! Extension component type declarations generated.');
console.log(
- `\nGenerated ${components.length + 2} files (${components.length + 1} MDX + 1 type declaration)`
+ `\nGenerated 1 type declaration file for ${components.length} components.`
);
}
diff --git a/docs/scripts/generate-if-changed.mjs b/docs/scripts/generate-if-changed.mjs
new file mode 100644
index 00000000000..b26fea53c60
--- /dev/null
+++ b/docs/scripts/generate-if-changed.mjs
@@ -0,0 +1,306 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Smart generator wrapper: only runs generators whose input files have changed.
+ *
+ * Computes a hash of each generator's input files (stories, engine specs,
+ * openapi.json, and the generator scripts themselves). Compares against a
+ * stored cache. Skips generators whose inputs and outputs are unchanged.
+ *
+ * Usage:
+ * node scripts/generate-if-changed.mjs # smart mode (default)
+ * node scripts/generate-if-changed.mjs --force # force regenerate all
+ */
+
+import { createHash } from 'crypto';
+import { execSync, spawn } from 'child_process';
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+const DOCS_DIR = path.resolve(__dirname, '..');
+const ROOT_DIR = path.resolve(DOCS_DIR, '..');
+const CACHE_FILE = path.join(DOCS_DIR, '.docusaurus', 'generator-hashes.json');
+
+const FORCE = process.argv.includes('--force');
+
+// Ensure local node_modules/.bin is on PATH (needed for docusaurus CLI)
+const localBin = path.join(DOCS_DIR, 'node_modules', '.bin');
+process.env.PATH = `${localBin}${path.delimiter}${process.env.PATH}`;
+
+// ---------------------------------------------------------------------------
+// Generator definitions
+// ---------------------------------------------------------------------------
+
+const GENERATORS = [
+ {
+ name: 'superset-components',
+ command: 'node scripts/generate-superset-components.mjs',
+ inputs: [
+ {
+ type: 'glob',
+ base: path.join(ROOT_DIR, 'superset-frontend/packages/superset-ui-core/src/components'),
+ pattern: '**/*.stories.tsx',
+ },
+ {
+ type: 'glob',
+ base: path.join(ROOT_DIR, 'superset-frontend/packages/superset-core/src'),
+ pattern: '**/*.stories.tsx',
+ },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/generate-superset-components.mjs') },
+ { type: 'file', path: path.join(DOCS_DIR, 'src/components/StorybookWrapper.jsx') },
+ ],
+ outputs: [
+ path.join(DOCS_DIR, 'developer_portal/components/index.mdx'),
+ path.join(DOCS_DIR, 'static/data/components.json'),
+ path.join(DOCS_DIR, 'src/types/apache-superset-core/index.d.ts'),
+ ],
+ },
+ {
+ name: 'database-docs',
+ command: 'node scripts/generate-database-docs.mjs',
+ inputs: [
+ {
+ type: 'glob',
+ base: path.join(ROOT_DIR, 'superset/db_engine_specs'),
+ pattern: '**/*.py',
+ },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/generate-database-docs.mjs') },
+ ],
+ outputs: [
+ path.join(DOCS_DIR, 'src/data/databases.json'),
+ path.join(DOCS_DIR, 'docs/databases/supported'),
+ ],
+ },
+ {
+ name: 'api-docs',
+ command:
+ 'python3 scripts/fix-openapi-spec.py && docusaurus gen-api-docs superset && node scripts/convert-api-sidebar.mjs && node scripts/generate-api-index.mjs && node scripts/generate-api-tag-pages.mjs',
+ inputs: [
+ { type: 'file', path: path.join(DOCS_DIR, 'static/resources/openapi.json') },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/fix-openapi-spec.py') },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/convert-api-sidebar.mjs') },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/generate-api-index.mjs') },
+ { type: 'file', path: path.join(DOCS_DIR, 'scripts/generate-api-tag-pages.mjs') },
+ ],
+ outputs: [
+ path.join(DOCS_DIR, 'docs/api.mdx'),
+ ],
+ },
+];
+
+// ---------------------------------------------------------------------------
+// Hashing utilities
+// ---------------------------------------------------------------------------
+
+function walkDir(dir, pattern) {
+ const results = [];
+ if (!fs.existsSync(dir)) return results;
+
+ const regex = globToRegex(pattern);
+ function walk(currentDir) {
+ for (const entry of fs.readdirSync(currentDir, { withFileTypes: true })) {
+ const fullPath = path.join(currentDir, entry.name);
+ if (entry.isDirectory()) {
+ if (entry.name === 'node_modules' || entry.name === '__pycache__') continue;
+ walk(fullPath);
+ } else {
+ const relativePath = path.relative(dir, fullPath);
+ if (regex.test(relativePath)) {
+ results.push(fullPath);
+ }
+ }
+ }
+ }
+ walk(dir);
+ return results.sort();
+}
+
+function globToRegex(pattern) {
+ // Simple glob-to-regex: ** matches any path, * matches anything except /
+ const escaped = pattern
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
+ .replace(/\*\*/g, '<<<GLOBSTAR>>>')
+ .replace(/\*/g, '[^/]*')
+ .replace(/<<<GLOBSTAR>>>/g, '.*');
+ return new RegExp(`^${escaped}$`);
+}
+
+function hashFile(filePath) {
+ if (!fs.existsSync(filePath)) return 'missing';
+ const stat = fs.statSync(filePath);
+ // Use mtime + size for speed (avoids reading file contents)
+ return `${stat.mtimeMs}:${stat.size}`;
+}
+
+function computeInputHash(inputs) {
+ const hash = createHash('md5');
+ for (const input of inputs) {
+ if (input.type === 'file') {
+ hash.update(`file:${input.path}:${hashFile(input.path)}\n`);
+ } else if (input.type === 'glob') {
+ const files = walkDir(input.base, input.pattern);
+ hash.update(`glob:${input.base}:${input.pattern}:count=${files.length}\n`);
+ for (const file of files) {
+ hash.update(` ${path.relative(input.base, file)}:${hashFile(file)}\n`);
+ }
+ }
+ }
+ return hash.digest('hex');
+}
+
+function outputsExist(outputs) {
+ return outputs.every((p) => fs.existsSync(p));
+}
+
+// ---------------------------------------------------------------------------
+// Cache management
+// ---------------------------------------------------------------------------
+
+function loadCache() {
+ try {
+ if (fs.existsSync(CACHE_FILE)) {
+ return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
+ }
+ } catch {
+ // Corrupted cache — start fresh
+ }
+ return {};
+}
+
+function saveCache(cache) {
+ const dir = path.dirname(CACHE_FILE);
+ if (!fs.existsSync(dir)) {
+ fs.mkdirSync(dir, { recursive: true });
+ }
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
+}
+
+// ---------------------------------------------------------------------------
+// Main
+// ---------------------------------------------------------------------------
+
+async function main() {
+ const cache = loadCache();
+ const updatedCache = { ...cache };
+ let skipped = 0;
+ let ran = 0;
+
+ // First pass: determine which generators need to run
+ // Run independent generators (extension-components, superset-components,
+ // database-docs) in parallel, then api-docs sequentially (it depends on
+ // docusaurus CLI being available, not on other generators).
+
+ const independent = GENERATORS.filter((g) => g.name !== 'api-docs');
+ const sequential = GENERATORS.filter((g) => g.name === 'api-docs');
+
+ // Check and run independent generators in parallel
+ const parallelPromises = independent.map((gen) => {
+ const currentHash = computeInputHash(gen.inputs);
+ const cachedHash = cache[gen.name];
+ const hasOutputs = outputsExist(gen.outputs);
+
+ if (!FORCE && currentHash === cachedHash && hasOutputs) {
+ console.log(` ✓ ${gen.name} — no changes, skipping`);
+ skipped++;
+ return Promise.resolve();
+ }
+
+ const reason = FORCE
+ ? 'forced'
+ : !hasOutputs
+ ? 'output missing'
+ : 'inputs changed';
+ console.log(` ↻ ${gen.name} — ${reason}, regenerating...`);
+ ran++;
+
+ return new Promise((resolve, reject) => {
+ const child = spawn('sh', ['-c', gen.command], {
+ cwd: DOCS_DIR,
+ stdio: 'inherit',
+ env: process.env,
+ });
+ child.on('close', (code) => {
+ if (code === 0) {
+ updatedCache[gen.name] = currentHash;
+ resolve();
+ } else {
+ console.error(` ✗ ${gen.name} failed (exit ${code})`);
+ reject(new Error(`${gen.name} failed with exit code ${code}`));
+ }
+ });
+ child.on('error', (err) => {
+ console.error(` ✗ ${gen.name} failed to start`);
+ reject(err);
+ });
+ });
+ });
+
+ await Promise.all(parallelPromises);
+
+ // Run sequential generators (api-docs)
+ for (const gen of sequential) {
+ const currentHash = computeInputHash(gen.inputs);
+ const cachedHash = cache[gen.name];
+ const hasOutputs = outputsExist(gen.outputs);
+
+ if (!FORCE && currentHash === cachedHash && hasOutputs) {
+ console.log(` ✓ ${gen.name} — no changes, skipping`);
+ skipped++;
+ continue;
+ }
+
+ const reason = FORCE
+ ? 'forced'
+ : !hasOutputs
+ ? 'output missing'
+ : 'inputs changed';
+ console.log(` ↻ ${gen.name} — ${reason}, regenerating...`);
+ ran++;
+
+ try {
+ execSync(gen.command, {
+ cwd: DOCS_DIR,
+ stdio: 'inherit',
+ timeout: 300_000,
+ });
+ updatedCache[gen.name] = currentHash;
+ } catch (err) {
+ console.error(` ✗ ${gen.name} failed`);
+ throw err;
+ }
+ }
+
+ saveCache(updatedCache);
+
+ if (ran === 0) {
+ console.log(`\nAll ${skipped} generators up-to-date — nothing to do!\n`);
+ } else {
+ console.log(`\nDone: ${ran} regenerated, ${skipped} skipped.\n`);
+ }
+}
+
+console.log('Checking generators for changes...\n');
+main().catch((err) => {
+ console.error(err);
+ process.exit(1);
+});
diff --git a/docs/scripts/generate-superset-components.mjs b/docs/scripts/generate-superset-components.mjs
index a85a49bef0a..c34324323ed 100644
--- a/docs/scripts/generate-superset-components.mjs
+++ b/docs/scripts/generate-superset-components.mjs
@@ -59,6 +59,9 @@ const __dirname = path.dirname(__filename);
const ROOT_DIR = path.resolve(__dirname, '../..');
const DOCS_DIR = path.resolve(__dirname, '..');
const OUTPUT_DIR = path.join(DOCS_DIR, 'developer_portal/components');
+const JSON_OUTPUT_PATH = path.join(DOCS_DIR, 'static/data/components.json');
+const TYPES_OUTPUT_DIR = path.join(DOCS_DIR, 'src/types/apache-superset-core');
+const TYPES_OUTPUT_PATH = path.join(TYPES_OUTPUT_DIR, 'index.d.ts');
const FRONTEND_DIR = path.join(ROOT_DIR, 'superset-frontend');
// Source configurations with import paths and categories
@@ -146,6 +149,16 @@ const SOURCES = [
enabled: false, // Requires specific setup
skipComponents: new Set([]),
},
+ {
+ name: 'Extension Components',
+ path: 'packages/superset-core/src',
+ importPrefix: '@apache-superset/core/ui',
+ docImportPrefix: '@apache-superset/core/ui',
+ category: 'extension',
+ enabled: true,
+ extensionCompatible: true,
+ skipComponents: new Set([]),
+ },
];
// Category mapping from story title prefixes to output directories
@@ -156,7 +169,7 @@ const CATEGORY_MAP = {
'Legacy Chart Plugins/': 'legacy-charts',
'Core Packages/': 'core-packages',
'Others/': 'utilities',
- 'Extension Components/': 'extension', // Skip - handled by other script
+ 'Extension Components/': 'extension',
'Superset App/': 'app',
};
@@ -334,6 +347,7 @@ function parseStoryFile(filePath, sourceConfig) {
sourceConfig,
resolvedImportPath,
isDefaultExport,
+ extensionCompatible: Boolean(sourceConfig.extensionCompatible),
};
}
@@ -1141,6 +1155,7 @@ Help improve it by [editing the story file](https://github.com/apache/superset/e
const CATEGORY_LABELS = {
ui: { title: 'Core Components', sidebarLabel: 'Core Components', description: 'Buttons, inputs, modals, selects, and other fundamental UI elements.' },
'design-system': { title: 'Layout Components', sidebarLabel: 'Layout Components', description: 'Grid, Layout, Table, Flex, Space, and container components for page structure.' },
+ extension: { title: 'Extension Components', sidebarLabel: 'Extension Components', description: 'Components available to extension developers via @apache-superset/core/ui.' },
};
/**
@@ -1195,19 +1210,6 @@ ${componentList}
* Generate main overview page
*/
function generateOverviewIndex(categories) {
- const categoryList = Object.entries(categories)
- .filter(([, components]) => components.length > 0)
- .map(([cat, components]) => {
- const labels = CATEGORY_LABELS[cat] || {
- title: cat.charAt(0).toUpperCase() + cat.slice(1).replace(/-/g, ' '),
- };
- const desc = labels.description ? ` ${labels.description}` : '';
- return `### [${labels.title}](./${cat}/)\n${components.length} components —${desc}\n`;
- })
- .join('\n');
-
- const totalComponents = Object.values(categories).reduce((sum, c) => sum + c.length, 0);
-
return `---
title: UI Components Overview
sidebar_label: Overview
@@ -1233,7 +1235,16 @@ sidebar_position: 0
under the License.
-->
-# Superset Design System
+import { ComponentIndex } from '@site/src/components/ui-components';
+import componentData from '@site/static/data/components.json';
+
+# UI Components
+
+<ComponentIndex data={componentData} />
+
+---
+
+## Design System
A design system is a complete set of standards intended to manage design at scale using reusable components and patterns.
@@ -1245,14 +1256,6 @@ The Superset Design System uses [Atomic Design](https://bradfrost.com/blog/post/
<img src="/img/atomic-design.png" alt="Atoms = Foundations, Molecules = Components, Organisms = Patterns, Templates = Templates, Pages / Screens = Features" style={{maxWidth: '100%'}} />
----
-
-## Component Library
-
-Interactive documentation for Superset's UI component library. **${totalComponents} components** documented across ${Object.keys(categories).filter(k => categories[k].length > 0).length} categories.
-
-${categoryList}
-
## Usage
All components are exported from \`@superset-ui/core/components\`:
@@ -1332,6 +1335,123 @@ ${sections}
`;
}
+/**
+ * Build metadata for a component (for JSON output)
+ */
+function buildComponentMetadata(component, storyContent) {
+ const { componentName, description, category, sourceConfig, resolvedImportPath, extensionCompatible } = component;
+ const { args, controls, gallery, liveExample } = extractArgsAndControls(storyContent, componentName);
+ const labels = CATEGORY_LABELS[category] || {
+ title: category.charAt(0).toUpperCase() + category.slice(1).replace(/-/g, ' '),
+ };
+
+ return {
+ name: componentName,
+ category,
+ categoryLabel: labels.title || category,
+ description: description || '',
+ importPath: resolvedImportPath || sourceConfig.importPrefix,
+ package: sourceConfig.docImportPrefix,
+ extensionCompatible: Boolean(extensionCompatible),
+ propsCount: Object.keys(args).length,
+ controlsCount: controls.length,
+ hasGallery: Boolean(gallery && gallery.sizes && gallery.styles),
+ hasLiveExample: Boolean(liveExample),
+ docPath: `developer_portal/components/${category}/${componentName.toLowerCase()}`,
+ storyFile: component.relativePath,
+ };
+}
+
+/**
+ * Extract type and component export declarations from a component source file.
+ * Used to generate .d.ts type declarations for extension-compatible components.
+ */
+function extractComponentTypes(componentPath) {
+ if (!fs.existsSync(componentPath)) return null;
+ const content = fs.readFileSync(componentPath, 'utf-8');
+
+ const types = [];
+ for (const match of content.matchAll(/export\s+type\s+(\w+)\s*=\s*([^;]+);/g)) {
+ types.push({ name: match[1], definition: match[2].trim() });
+ }
+
+ const components = [];
+ for (const match of content.matchAll(/export\s+const\s+(\w+)\s*[=:]/g)) {
+ components.push(match[1]);
+ }
+
+ return { types, components };
+}
+
+/**
+ * Generate TypeScript type declarations for extension-compatible components.
+ * Produces a .d.ts file that downstream consumers can reference.
+ */
+function generateExtensionTypeDeclarations(extensionComponents) {
+ const imports = new Set();
+ const typeDeclarations = [];
+ const componentDeclarations = [];
+
+ for (const comp of extensionComponents) {
+ const componentDir = path.dirname(comp.filePath);
+ const componentFile = path.join(componentDir, 'index.tsx');
+ const extracted = extractComponentTypes(componentFile);
+ if (!extracted) continue;
+
+ for (const type of extracted.types) {
+ if (type.definition.includes('AntdAlertProps') || type.definition.includes('AlertProps')) {
+ imports.add("import type { AlertProps as AntdAlertProps } from 'antd/es/alert';");
+ }
+ if (type.definition.includes('PropsWithChildren') || type.definition.includes('FC')) {
+ imports.add("import type { PropsWithChildren, FC } from 'react';");
+ }
+ typeDeclarations.push(`export type ${type.name} = ${type.definition};`);
+ }
+
+ for (const name of extracted.components) {
+ const propsType = `${name}Props`;
+ const hasPropsType = extracted.types.some(t => t.name === propsType);
+ componentDeclarations.push(
+ hasPropsType
+ ? `export const ${name}: FC<${propsType}>;`
+ : `export const ${name}: FC<Record<string, unknown>>;`
+ );
+ }
+ }
+
+ return `/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Type declarations for @apache-superset/core/ui
+ *
+ * AUTO-GENERATED by scripts/generate-superset-components.mjs
+ * Do not edit manually - regenerate by running: yarn generate:superset-components
+ */
+${Array.from(imports).join('\n')}
+
+${typeDeclarations.join('\n')}
+
+${componentDeclarations.join('\n')}
+`;
+}
+
/**
* Main function
*/
@@ -1396,6 +1516,51 @@ async function main() {
console.log(` ✓ ${category}/index`);
}
+ // Build JSON metadata for all components
+ console.log('\nBuilding component metadata JSON...');
+ const componentMetadata = [];
+ for (const component of components) {
+ const storyContent = fs.readFileSync(component.filePath, 'utf-8');
+ componentMetadata.push(buildComponentMetadata(component, storyContent));
+ }
+
+ // Build statistics
+ const byCategory = {};
+ for (const comp of componentMetadata) {
+ if (!byCategory[comp.category]) byCategory[comp.category] = 0;
+ byCategory[comp.category]++;
+ }
+ const jsonData = {
+ generated: new Date().toISOString(),
+ statistics: {
+ totalComponents: componentMetadata.length,
+ byCategory,
+ extensionCompatible: componentMetadata.filter(c => c.extensionCompatible).length,
+ withGallery: componentMetadata.filter(c => c.hasGallery).length,
+ withLiveExample: componentMetadata.filter(c => c.hasLiveExample).length,
+ },
+ components: componentMetadata,
+ };
+
+ // Ensure data directory exists and write JSON
+ const jsonDir = path.dirname(JSON_OUTPUT_PATH);
+ if (!fs.existsSync(jsonDir)) {
+ fs.mkdirSync(jsonDir, { recursive: true });
+ }
+ fs.writeFileSync(JSON_OUTPUT_PATH, JSON.stringify(jsonData, null, 2));
+ console.log(` ✓ components.json (${componentMetadata.length} components)`);
+
+ // Generate type declarations for extension-compatible components
+ const extensionComponents = components.filter(c => c.extensionCompatible);
+ if (extensionComponents.length > 0) {
+ if (!fs.existsSync(TYPES_OUTPUT_DIR)) {
+ fs.mkdirSync(TYPES_OUTPUT_DIR, { recursive: true });
+ }
+ const typesContent = generateExtensionTypeDeclarations(extensionComponents);
+ fs.writeFileSync(TYPES_OUTPUT_PATH, typesContent);
+ console.log(` ✓ extension types (${extensionComponents.length} components)`);
+ }
+
// Generate main overview
const overviewContent = generateOverviewIndex(categories);
const overviewPath = path.join(OUTPUT_DIR, 'index.mdx');
diff --git a/docs/sidebarTutorials.js b/docs/sidebarTutorials.js
index b786478c0b1..e8c87d58534 100644
--- a/docs/sidebarTutorials.js
+++ b/docs/sidebarTutorials.js
@@ -74,17 +74,6 @@ const sidebars = {
'extensions/architecture',
'extensions/dependencies',
'extensions/contribution-types',
- {
- type: 'category',
- label: 'Components',
- collapsed: true,
- items: [
- {
- type: 'autogenerated',
- dirName: 'extensions/components',
- },
- ],
- },
{
type: 'category',
label: 'Extension Points',
diff --git a/docs/src/components/databases/DatabaseIndex.tsx b/docs/src/components/databases/DatabaseIndex.tsx
index 26f71522dfc..91c58964a31 100644
--- a/docs/src/components/databases/DatabaseIndex.tsx
+++ b/docs/src/components/databases/DatabaseIndex.tsx
@@ -496,6 +496,7 @@ const DatabaseIndex: React.FC<DatabaseIndexProps> = ({ data }) => {
return (
<div className="database-index">
+ {/* Statistics Cards */}
{/* Statistics Cards */}
<Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
<Col xs={12} sm={6}>
diff --git a/docs/src/components/ui-components/ComponentIndex.tsx b/docs/src/components/ui-components/ComponentIndex.tsx
new file mode 100644
index 00000000000..180a67ea2db
--- /dev/null
+++ b/docs/src/components/ui-components/ComponentIndex.tsx
@@ -0,0 +1,262 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React, { useState, useMemo } from 'react';
+import { Card, Row, Col, Statistic, Table, Tag, Input, Select } from 'antd';
+import {
+ AppstoreOutlined,
+ ApiOutlined,
+ PictureOutlined,
+ PlayCircleOutlined,
+ SearchOutlined,
+} from '@ant-design/icons';
+import type { ComponentData, ComponentEntry } from './types';
+
+interface ComponentIndexProps {
+ data: ComponentData;
+}
+
+const CATEGORY_COLORS: Record<string, string> = {
+ ui: 'blue',
+ 'design-system': 'green',
+ extension: 'purple',
+};
+
+const CATEGORY_LABELS: Record<string, string> = {
+ ui: 'Core',
+ 'design-system': 'Layout',
+ extension: 'Extension',
+};
+
+const ComponentIndex: React.FC<ComponentIndexProps> = ({ data }) => {
+ const [searchText, setSearchText] = useState('');
+ const [categoryFilter, setCategoryFilter] = useState<string | null>(null);
+
+ const { statistics, components } = data;
+
+ const filteredComponents = useMemo(() => {
+ return components
+ .filter((comp) => {
+ const matchesSearch =
+ !searchText ||
+ comp.name.toLowerCase().includes(searchText.toLowerCase()) ||
+ comp.description.toLowerCase().includes(searchText.toLowerCase()) ||
+ comp.package.toLowerCase().includes(searchText.toLowerCase());
+ const matchesCategory =
+ !categoryFilter || comp.category === categoryFilter;
+ return matchesSearch && matchesCategory;
+ })
+ .sort((a, b) => a.name.localeCompare(b.name));
+ }, [components, searchText, categoryFilter]);
+
+ const { categories, categoryCounts } = useMemo(() => {
+ const counts: Record<string, number> = {};
+ components.forEach((comp) => {
+ counts[comp.category] = (counts[comp.category] || 0) + 1;
+ });
+ return {
+ categories: Object.keys(counts).sort(),
+ categoryCounts: counts,
+ };
+ }, [components]);
+
+ const columns = [
+ {
+ title: 'Component',
+ dataIndex: 'name',
+ key: 'name',
+ sorter: (a: ComponentEntry, b: ComponentEntry) =>
+ a.name.localeCompare(b.name),
+ defaultSortOrder: 'ascend' as const,
+ render: (name: string, record: ComponentEntry) => (
+ <div>
+ <a href={`/${record.docPath}`}>
+ <strong>{name}</strong>
+ </a>
+ {record.description && (
+ <div style={{ fontSize: '12px', color: '#666' }}>
+ {record.description.slice(0, 100)}
+ {record.description.length > 100 ? '...' : ''}
+ </div>
+ )}
+ </div>
+ ),
+ },
+ {
+ title: 'Category',
+ dataIndex: 'category',
+ key: 'category',
+ width: 120,
+ filters: categories.map((cat) => ({
+ text: CATEGORY_LABELS[cat] || cat,
+ value: cat,
+ })),
+ onFilter: (value: React.Key | boolean, record: ComponentEntry) =>
+ record.category === value,
+ render: (cat: string) => (
+ <Tag color={CATEGORY_COLORS[cat] || 'default'}>
+ {CATEGORY_LABELS[cat] || cat}
+ </Tag>
+ ),
+ },
+ {
+ title: 'Package',
+ dataIndex: 'package',
+ key: 'package',
+ width: 220,
+ render: (pkg: string) => (
+ <code style={{ fontSize: '12px' }}>{pkg}</code>
+ ),
+ },
+ {
+ title: 'Tags',
+ key: 'tags',
+ width: 280,
+ filters: [
+ { text: 'Extension Compatible', value: 'extension' },
+ { text: 'Gallery', value: 'gallery' },
+ { text: 'Live Demo', value: 'demo' },
+ ],
+ onFilter: (value: React.Key | boolean, record: ComponentEntry) => {
+ switch (value) {
+ case 'extension':
+ return record.extensionCompatible;
+ case 'gallery':
+ return record.hasGallery;
+ case 'demo':
+ return record.hasLiveExample;
+ default:
+ return true;
+ }
+ },
+ render: (_: unknown, record: ComponentEntry) => (
+ <div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap' }}>
+ {record.extensionCompatible && (
+ <Tag color="purple">Extension Compatible</Tag>
+ )}
+ {record.hasGallery && <Tag color="cyan">Gallery</Tag>}
+ {record.hasLiveExample && <Tag color="green">Demo</Tag>}
+ </div>
+ ),
+ },
+ {
+ title: 'Props',
+ dataIndex: 'propsCount',
+ key: 'propsCount',
+ width: 80,
+ sorter: (a: ComponentEntry, b: ComponentEntry) =>
+ a.propsCount - b.propsCount,
+ render: (count: number) => (
+ <span style={{ color: count > 0 ? '#1890ff' : '#999' }}>{count}</span>
+ ),
+ },
+ ];
+
+ return (
+ <div className="component-index">
+ <Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
+ <Col xs={12} sm={6}>
+ <Card>
+ <Statistic
+ title="Total Components"
+ value={statistics.totalComponents}
+ prefix={<AppstoreOutlined />}
+ />
+ </Card>
+ </Col>
+ <Col xs={12} sm={6}>
+ <Card>
+ <Statistic
+ title="Extension Compatible"
+ value={statistics.extensionCompatible}
+ prefix={<ApiOutlined />}
+ />
+ </Card>
+ </Col>
+ <Col xs={12} sm={6}>
+ <Card>
+ <Statistic
+ title="With Gallery"
+ value={statistics.withGallery}
+ prefix={<PictureOutlined />}
+ />
+ </Card>
+ </Col>
+ <Col xs={12} sm={6}>
+ <Card>
+ <Statistic
+ title="With Live Demo"
+ value={statistics.withLiveExample}
+ prefix={<PlayCircleOutlined />}
+ />
+ </Card>
+ </Col>
+ </Row>
+
+ <Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
+ <Col xs={24} sm={12}>
+ <Input
+ placeholder="Search components..."
+ prefix={<SearchOutlined />}
+ value={searchText}
+ onChange={(e) => setSearchText(e.target.value)}
+ allowClear
+ />
+ </Col>
+ <Col xs={24} sm={12}>
+ <Select
+ placeholder="Filter by category"
+ style={{ width: '100%' }}
+ value={categoryFilter}
+ onChange={setCategoryFilter}
+ allowClear
+ options={categories.map((cat) => ({
+ label: (
+ <span>
+ <Tag
+ color={CATEGORY_COLORS[cat] || 'default'}
+ style={{ marginRight: 8 }}
+ >
+ {categoryCounts[cat] || 0}
+ </Tag>
+ {CATEGORY_LABELS[cat] || cat}
+ </span>
+ ),
+ value: cat,
+ }))}
+ />
+ </Col>
+ </Row>
+
+ <Table
+ dataSource={filteredComponents}
+ columns={columns}
+ rowKey="name"
+ pagination={{
+ defaultPageSize: 20,
+ showSizeChanger: true,
+ showTotal: (total) => `${total} components`,
+ }}
+ size="middle"
+ />
+ </div>
+ );
+};
+
+export default ComponentIndex;
diff --git a/docs/babel.config.js b/docs/src/components/ui-components/index.ts
similarity index 75%
rename from docs/babel.config.js
rename to docs/src/components/ui-components/index.ts
index 61032e678a4..2081775d7dc 100644
--- a/docs/babel.config.js
+++ b/docs/src/components/ui-components/index.ts
@@ -1,4 +1,3 @@
-/* eslint-env node */
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -18,15 +17,5 @@
* under the License.
*/
-module.exports = {
- presets: [
- [
- require.resolve('@docusaurus/core/lib/babel/preset'),
- {
- runtime: 'automatic',
- importSource: '@emotion/react',
- },
- ],
- ],
- plugins: ['@emotion/babel-plugin'],
-};
+export { default as ComponentIndex } from './ComponentIndex';
+export * from './types';
diff --git a/docs/src/types/apache-superset-core/index.d.ts b/docs/src/components/ui-components/types.ts
similarity index 55%
copy from docs/src/types/apache-superset-core/index.d.ts
copy to docs/src/components/ui-components/types.ts
index 5650b85bb2c..f4fb082b065 100644
--- a/docs/src/types/apache-superset-core/index.d.ts
+++ b/docs/src/components/ui-components/types.ts
@@ -17,15 +17,32 @@
* under the License.
*/
-/**
- * Type declarations for @apache-superset/core/ui
- *
- * AUTO-GENERATED by scripts/generate-extension-components.mjs
- * Do not edit manually - regenerate by running: yarn generate:extension-components
- */
-import type { AlertProps as AntdAlertProps } from 'antd/es/alert';
-import type { PropsWithChildren, FC } from 'react';
+export interface ComponentEntry {
+ name: string;
+ category: string;
+ categoryLabel: string;
+ description: string;
+ importPath: string;
+ package: string;
+ extensionCompatible: boolean;
+ propsCount: number;
+ controlsCount: number;
+ hasGallery: boolean;
+ hasLiveExample: boolean;
+ docPath: string;
+ storyFile: string;
+}
-export type AlertProps = PropsWithChildren<Omit<AntdAlertProps, 'children'>>;
+export interface ComponentStatistics {
+ totalComponents: number;
+ byCategory: Record<string, number>;
+ extensionCompatible: number;
+ withGallery: number;
+ withLiveExample: number;
+}
-export const Alert: FC<AlertProps>;
+export interface ComponentData {
+ generated: string;
+ statistics: ComponentStatistics;
+ components: ComponentEntry[];
+}
diff --git a/docs/src/data/databases.json b/docs/src/data/databases.json
index 67cfdc3aebd..38914dd7868 100644
--- a/docs/src/data/databases.json
+++ b/docs/src/data/databases.json
@@ -1,5 +1,5 @@
{
- "generated": "2026-02-16T04:47:37.257Z",
+ "generated": "2026-02-24T20:28:17.222Z",
"statistics": {
"totalDatabases": 72,
"withDocumentation": 72,
diff --git a/docs/src/types/apache-superset-core/index.d.ts b/docs/src/types/apache-superset-core/index.d.ts
index 5650b85bb2c..6e3a121e1b6 100644
--- a/docs/src/types/apache-superset-core/index.d.ts
+++ b/docs/src/types/apache-superset-core/index.d.ts
@@ -20,8 +20,8 @@
/**
* Type declarations for @apache-superset/core/ui
*
- * AUTO-GENERATED by scripts/generate-extension-components.mjs
- * Do not edit manually - regenerate by running: yarn generate:extension-components
+ * AUTO-GENERATED by scripts/generate-superset-components.mjs
+ * Do not edit manually - regenerate by running: yarn generate:superset-components
*/
import type { AlertProps as AntdAlertProps } from 'antd/es/alert';
import type { PropsWithChildren, FC } from 'react';
diff --git a/docs/src/webpack.extend.ts b/docs/src/webpack.extend.ts
index e3079ee7e73..f32d9d9847d 100644
--- a/docs/src/webpack.extend.ts
+++ b/docs/src/webpack.extend.ts
@@ -101,12 +101,6 @@ export default function webpackExtendPlugin(): Plugin<void> {
return {
devtool: isDev ? false : config.devtool,
- cache: {
- type: 'filesystem',
- buildDependencies: {
- config: [__filename],
- },
- },
...(isDev && {
optimization: {
...config.optimization,
diff --git a/docs/tsconfig.json b/docs/tsconfig.json
index b29d41ca6de..f4a3a433d87 100644
--- a/docs/tsconfig.json
+++ b/docs/tsconfig.json
@@ -14,7 +14,7 @@
"paths": {
"@superset-ui/core": ["../superset-frontend/packages/superset-ui-core/src"],
"@superset-ui/core/*": ["../superset-frontend/packages/superset-ui-core/src/*"],
- // Types for @apache-superset/core/ui are auto-generated by scripts/generate-extension-components.mjs
+ // Types for @apache-superset/core/ui are auto-generated by scripts/generate-superset-components.mjs
// Runtime resolution uses webpack alias pointing to actual source (see src/webpack.extend.ts)
// Using /ui path matches the established pattern used throughout the Superset codebase
"@apache-superset/core/ui": ["./src/types/apache-superset-core"],
diff --git a/docs/yarn.lock b/docs/yarn.lock
index a232ce5c2bb..03860481598 100644
--- a/docs/yarn.lock
+++ b/docs/yarn.lock
@@ -1695,6 +1695,21 @@
postcss-sort-media-queries "^5.2.0"
tslib "^2.6.0"
+"@docusaurus/faster@^3.9.2":
+ version "3.9.2"
+ resolved "https://registry.yarnpkg.com/@docusaurus/faster/-/faster-3.9.2.tgz#47b69f39ed935fdcc8dc03896274fca29056e962"
+ integrity sha512-DEVIwhbrZZ4ir31X+qQNEQqDWkgCJUV6kiPPAd2MGTY8n5/n0c4B8qA5k1ipF2izwH00JEf0h6Daaut71zzkyw==
+ dependencies:
+ "@docusaurus/types" "3.9.2"
+ "@rspack/core" "^1.5.0"
+ "@swc/core" "^1.7.39"
+ "@swc/html" "^1.13.5"
+ browserslist "^4.24.2"
+ lightningcss "^1.27.0"
+ swc-loader "^0.2.6"
+ tslib "^2.6.0"
+ webpack "^5.95.0"
+
"@docusaurus/logger@3.9.2":
version "3.9.2"
resolved "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz"
@@ -2104,6 +2119,28 @@
utility-types "^3.10.0"
webpack "^5.88.1"
+"@emnapi/core@^1.5.0":
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.8.1.tgz#fd9efe721a616288345ffee17a1f26ac5dd01349"
+ integrity sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==
+ dependencies:
+ "@emnapi/wasi-threads" "1.1.0"
+ tslib "^2.4.0"
+
+"@emnapi/runtime@^1.5.0":
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.8.1.tgz#550fa7e3c0d49c5fb175a116e8cd70614f9a22a5"
+ integrity sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==
+ dependencies:
+ tslib "^2.4.0"
+
+"@emnapi/wasi-threads@1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf"
+ integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==
+ dependencies:
+ tslib "^2.4.0"
+
"@emotion/babel-plugin@^11.13.5":
version "11.13.5"
resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz"
@@ -2679,6 +2716,58 @@
dependencies:
langium "3.3.1"
+"@module-federation/error-codes@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/error-codes/-/error-codes-0.22.0.tgz#31ccc990dc240d73912ba7bd001f7e35ac751992"
+ integrity sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==
+
+"@module-federation/runtime-core@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz#7321ec792bb7d1d22bee6162ec43564b769d2a3c"
+ integrity sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==
+ dependencies:
+ "@module-federation/error-codes" "0.22.0"
+ "@module-federation/sdk" "0.22.0"
+
+"@module-federation/runtime-tools@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz#36f2a7cb267af208a9d1a237fe9a71b4bf31431e"
+ integrity sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==
+ dependencies:
+ "@module-federation/runtime" "0.22.0"
+ "@module-federation/webpack-bundler-runtime" "0.22.0"
+
+"@module-federation/runtime@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/runtime/-/runtime-0.22.0.tgz#f789c9ef40d846d110711c8221ecc0ad938d43d8"
+ integrity sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==
+ dependencies:
+ "@module-federation/error-codes" "0.22.0"
+ "@module-federation/runtime-core" "0.22.0"
+ "@module-federation/sdk" "0.22.0"
+
+"@module-federation/sdk@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/sdk/-/sdk-0.22.0.tgz#6ad4c1de85a900c3c80ff26cb87cce253e3a2770"
+ integrity sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==
+
+"@module-federation/webpack-bundler-runtime@0.22.0":
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz#dcbe8f972d722fe278e6a7c21988d4bee53d401d"
+ integrity sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==
+ dependencies:
+ "@module-federation/runtime" "0.22.0"
+ "@module-federation/sdk" "0.22.0"
+
+"@napi-rs/wasm-runtime@1.0.7":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz#dcfea99a75f06209a235f3d941e3460a51e9b14c"
+ integrity sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==
+ dependencies:
+ "@emnapi/core" "^1.5.0"
+ "@emnapi/runtime" "^1.5.0"
+ "@tybys/wasm-util" "^0.10.1"
+
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
@@ -3273,6 +3362,88 @@
redux-thunk "^3.1.0"
reselect "^5.1.0"
+"@rspack/binding-darwin-arm64@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.6.tgz#10144f3841be88ea25c71a537df6b038ae84a87a"
+ integrity sha512-NZ9AWtB1COLUX1tA9HQQvWpTy07NSFfKBU8A6ylWd5KH8AePZztpNgLLAVPTuNO4CZXYpwcoclf8jG/luJcQdQ==
+
+"@rspack/binding-darwin-x64@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.6.tgz#70588e30e1fdcd3149e09fe6798eb95609ad814b"
+ integrity sha512-J2g6xk8ZS7uc024dNTGTHxoFzFovAZIRixUG7PiciLKTMP78svbSSWrmW6N8oAsAkzYfJWwQpVgWfFNRHvYxSw==
+
+"@rspack/binding-linux-arm64-gnu@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.6.tgz#322e7fe54fccefd57603d4730130bef311b8dd60"
+ integrity sha512-eQfcsaxhFrv5FmtaA7+O1F9/2yFDNIoPZzV/ZvqvFz5bBXVc4FAm/1fVpBg8Po/kX1h0chBc7Xkpry3cabFW8w==
+
+"@rspack/binding-linux-arm64-musl@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.6.tgz#4444dfe045323f341c7c82fdb7dce5809fea51c1"
+ integrity sha512-DfQXKiyPIl7i1yECHy4eAkSmlUzzsSAbOjgMuKn7pudsWf483jg0UUYutNgXSlBjc/QSUp7906Cg8oty9OfwPA==
+
+"@rspack/binding-linux-x64-gnu@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.6.tgz#c31bf72789c71eeee75cd3cb06d6a6e5449e1bd1"
+ integrity sha512-NdA+2X3lk2GGrMMnTGyYTzM3pn+zNjaqXqlgKmFBXvjfZqzSsKq3pdD1KHZCd5QHN+Fwvoszj0JFsquEVhE1og==
+
+"@rspack/binding-linux-x64-musl@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.6.tgz#20f8ad786d581af7a7c2802220b533ce531fb4c6"
+ integrity sha512-rEy6MHKob02t/77YNgr6dREyJ0e0tv1X6Xsg8Z5E7rPXead06zefUbfazj4RELYySWnM38ovZyJAkPx/gOn3VA==
+
+"@rspack/binding-wasm32-wasi@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.6.tgz#76ae0f9f584a054e109b83ec02516ce75dcff8e6"
+ integrity sha512-YupOrz0daSG+YBbCIgpDgzfMM38YpChv+afZpaxx5Ml7xPeAZIIdgWmLHnQ2rts73N2M1NspAiBwV00Xx0N4Vg==
+ dependencies:
+ "@napi-rs/wasm-runtime" "1.0.7"
+
+"@rspack/binding-win32-arm64-msvc@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.6.tgz#4e7f70338dfcc8efa3a67d72064562eb9f0662cb"
+ integrity sha512-INj7aVXjBvlZ84kEhSK4kJ484ub0i+BzgnjDWOWM1K+eFYDZjLdAsQSS3fGGXwVc3qKbPIssFfnftATDMTEJHQ==
+
+"@rspack/binding-win32-ia32-msvc@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.6.tgz#efeb807c624536361467dfec0898705213fbd997"
+ integrity sha512-lXGvC+z67UMcw58In12h8zCa9IyYRmuptUBMItQJzu+M278aMuD1nETyGLL7e4+OZ2lvrnnBIcjXN1hfw2yRzw==
+
+"@rspack/binding-win32-x64-msvc@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.6.tgz#48014313c224e9fce31d02134c81525a7cb7f891"
+ integrity sha512-zeUxEc0ZaPpmaYlCeWcjSJUPuRRySiSHN23oJ2Xyw0jsQ01Qm4OScPdr0RhEOFuK/UE+ANyRtDo4zJsY52Hadw==
+
+"@rspack/binding@1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/binding/-/binding-1.7.6.tgz#d61b241c0dbb4e395f7753de74a2fe760891d4f2"
+ integrity sha512-/NrEcfo8Gx22hLGysanrV6gHMuqZSxToSci/3M4kzEQtF5cPjfOv5pqeLK/+B6cr56ul/OmE96cCdWcXeVnFjQ==
+ optionalDependencies:
+ "@rspack/binding-darwin-arm64" "1.7.6"
+ "@rspack/binding-darwin-x64" "1.7.6"
+ "@rspack/binding-linux-arm64-gnu" "1.7.6"
+ "@rspack/binding-linux-arm64-musl" "1.7.6"
+ "@rspack/binding-linux-x64-gnu" "1.7.6"
+ "@rspack/binding-linux-x64-musl" "1.7.6"
+ "@rspack/binding-wasm32-wasi" "1.7.6"
+ "@rspack/binding-win32-arm64-msvc" "1.7.6"
+ "@rspack/binding-win32-ia32-msvc" "1.7.6"
+ "@rspack/binding-win32-x64-msvc" "1.7.6"
+
+"@rspack/core@^1.5.0":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@rspack/core/-/core-1.7.6.tgz#d43a1c4103248cbe4011902906c6d7427b80f3a6"
+ integrity sha512-Iax6UhrfZqJajA778c1d5DBFbSIqPOSrI34kpNIiNpWd8Jq7mFIa+Z60SQb5ZQDZuUxcCZikjz5BxinFjTkg7Q==
+ dependencies:
+ "@module-federation/runtime-tools" "0.22.0"
+ "@rspack/binding" "1.7.6"
+ "@rspack/lite-tapable" "1.1.0"
+
+"@rspack/lite-tapable@1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz#3cfdafeed01078e116bd4f191b684c8b484de425"
+ integrity sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==
+
"@saucelabs/theme-github-codeblock@^0.3.0":
version "0.3.0"
resolved "https://registry.npmjs.org/@saucelabs/theme-github-codeblock/-/theme-github-codeblock-0.3.0.tgz"
@@ -4047,51 +4218,101 @@
resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz"
integrity sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==
+"@swc/core-darwin-arm64@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.13.tgz#f60ff48cb93066b83405074015eb6373ea0cdd77"
+ integrity sha512-ztXusRuC5NV2w+a6pDhX13CGioMLq8CjX5P4XgVJ21ocqz9t19288Do0y8LklplDtwcEhYGTNdMbkmUT7+lDTg==
+
"@swc/core-darwin-x64@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz#31381b6560bbd8b8ca6a0755262df321e28c039d"
integrity sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==
+"@swc/core-darwin-x64@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.13.tgz#3838c08653ac53a6508cdc34bfa191281da4ed26"
+ integrity sha512-cVifxQUKhaE7qcO/y9Mq6PEhoyvN9tSLzCnnFZ4EIabFHBuLtDDO6a+vLveOy98hAs5Qu1+bb5Nv0oa1Pihe3Q==
+
"@swc/core-linux-arm-gnueabihf@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz#ea7831776f7d8a548db4a8a5f38ef37faf5c0c66"
integrity sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==
+"@swc/core-linux-arm-gnueabihf@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.13.tgz#9308b156fae3fe5d12684b86af31ada4255066fc"
+ integrity sha512-t+xxEzZ48enl/wGGy7SRYd7kImWQ/+wvVFD7g5JZo234g6/QnIgZ+YdfIyjHB+ZJI3F7a2IQHS7RNjxF29UkWw==
+
"@swc/core-linux-arm64-gnu@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz#c99a5843115ef57cbefd40b93c99cb130d6db12f"
integrity sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==
+"@swc/core-linux-arm64-gnu@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.13.tgz#b150d6091e2bb3cf97dc9712a711d3ba025811a9"
+ integrity sha512-VndeGvKmTXFn6AGwjy0Kg8i7HccOCE7Jt/vmZwRxGtOfNZM1RLYRQ7MfDLo6T0h1Bq6eYzps3L5Ma4zBmjOnOg==
+
"@swc/core-linux-arm64-musl@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz#9a7831f558b2ff504d3d6eaaf6a4c84e5232284b"
integrity sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==
+"@swc/core-linux-arm64-musl@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.13.tgz#35dd5382554096118ecd1db2928e1f71b56aa41a"
+ integrity sha512-SmZ9m+XqCB35NddHCctvHFLqPZDAs5j8IgD36GoutufDJmeq2VNfgk5rQoqNqKmAK3Y7iFdEmI76QoHIWiCLyw==
+
"@swc/core-linux-x64-gnu@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz#4a1fce9b9abedde04459fefe5da9dd9e405a2ae8"
integrity sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==
+"@swc/core-linux-x64-gnu@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.13.tgz#03f89bbdce8f07a1bc02a3ef1c93a5b4e81aef2e"
+ integrity sha512-5rij+vB9a29aNkHq72EXI2ihDZPszJb4zlApJY4aCC/q6utgqFA6CkrfTfIb+O8hxtG3zP5KERETz8mfFK6A0A==
+
"@swc/core-linux-x64-musl@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz#0865f23b1cc532d9d77e743a83279e074edbee25"
integrity sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==
+"@swc/core-linux-x64-musl@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.13.tgz#27ae66914125bf35724e43bb06b856afed39770c"
+ integrity sha512-OlSlaOK9JplQ5qn07WiBLibkOw7iml2++ojEXhhR3rbWrNEKCD7sd8+6wSavsInyFdw4PhLA+Hy6YyDBIE23Yw==
+
"@swc/core-win32-arm64-msvc@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz#73eda8b54c94046728f5983e5516223ad1009c59"
integrity sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==
+"@swc/core-win32-arm64-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.13.tgz#39776831949a53754d8f62e4730ac9430d1671f3"
+ integrity sha512-zwQii5YVdsfG8Ti9gIKgBKZg8qMkRZxl+OlYWUT5D93Jl4NuNBRausP20tfEkQdAPSRrMCSUZBM6FhW7izAZRg==
+
"@swc/core-win32-ia32-msvc@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz#0df41547974ba9f26ba3e903e803ff523c15650b"
integrity sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==
+"@swc/core-win32-ia32-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.13.tgz#995c45c9fd86d9959bc1a7275c4e60ac4efcc12f"
+ integrity sha512-hYXvyVVntqRlYoAIDwNzkS3tL2ijP3rxyWQMNKaxcCxxkCDto/w3meOK/OB6rbQSkNw0qTUcBfU9k+T0ptYdfQ==
+
"@swc/core-win32-x64-msvc@1.15.11":
version "1.15.11"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz#f6f97500472c0ea4ab756c383c5d97896075f95c"
integrity sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==
+"@swc/core-win32-x64-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.13.tgz#b329aec8bb5e84bab49c8f250ebb27f6c27dc213"
+ integrity sha512-XTzKs7c/vYCcjmcwawnQvlHHNS1naJEAzcBckMI5OJlnrcgW8UtcX9NHFYvNjGtXuKv0/9KvqL4fuahdvlNGKw==
+
"@swc/core@^1.15.11":
version "1.15.11"
resolved "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz"
@@ -4111,11 +4332,98 @@
"@swc/core-win32-ia32-msvc" "1.15.11"
"@swc/core-win32-x64-msvc" "1.15.11"
+"@swc/core@^1.7.39":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.15.13.tgz#19b4117a76576f46b28199ac2f75cad5bc9cdde4"
+ integrity sha512-0l1gl/72PErwUZuavcRpRAQN9uSst+Nk++niC5IX6lmMWpXoScYx3oq/narT64/sKv/eRiPTaAjBFGDEQiWJIw==
+ dependencies:
+ "@swc/counter" "^0.1.3"
+ "@swc/types" "^0.1.25"
+ optionalDependencies:
+ "@swc/core-darwin-arm64" "1.15.13"
+ "@swc/core-darwin-x64" "1.15.13"
+ "@swc/core-linux-arm-gnueabihf" "1.15.13"
+ "@swc/core-linux-arm64-gnu" "1.15.13"
+ "@swc/core-linux-arm64-musl" "1.15.13"
+ "@swc/core-linux-x64-gnu" "1.15.13"
+ "@swc/core-linux-x64-musl" "1.15.13"
+ "@swc/core-win32-arm64-msvc" "1.15.13"
+ "@swc/core-win32-ia32-msvc" "1.15.13"
+ "@swc/core-win32-x64-msvc" "1.15.13"
+
"@swc/counter@^0.1.3":
version "0.1.3"
resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz"
integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
+"@swc/html-darwin-arm64@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-darwin-arm64/-/html-darwin-arm64-1.15.13.tgz#6cb94e0a6685df46a48c7168e4d1a048ddcdeceb"
+ integrity sha512-w/fTkqqkx9haSbws8YhhW/Bp7ZkxCJ6lns5YYZMHdZI2KJL4WEHl6GhGzgzavOXaO8LBouiUwucc2bYPgsfI/w==
+
+"@swc/html-darwin-x64@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-darwin-x64/-/html-darwin-x64-1.15.13.tgz#c9402ec555c7681370fc978f4f6cc12a19e6e9ba"
+ integrity sha512-yYb8jq+R+FlM8DlFLt5zmm0G5zdF4UUrHjafETmNj3J05itOzcOO9kI7icZ6DUwCROYbfejG7AwkSooYOV5+kA==
+
+"@swc/html-linux-arm-gnueabihf@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.15.13.tgz#b10aa1b05ccf12610d145833a500aa83e4de6920"
+ integrity sha512-n+/JK+vi9FwJCe5Jrv7i0J0/keal3x+8ZXROJbLAdzYWoAaqjbEeUNWuqmSH3uU64eOhqUl6kRERLz/NB6LoZw==
+
+"@swc/html-linux-arm64-gnu@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.15.13.tgz#8e98a5b4672155ff13c6f1404abe731c8967992e"
+ integrity sha512-ThKrqeXiRKTj4/mo+KoXy4GE390Lt76GjF0apNwXB27YTQxMFLIlcHIntn/WhumAVJCu3pA/n0TYw8ZSu7K3DA==
+
+"@swc/html-linux-arm64-musl@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.15.13.tgz#64487978fcdb347490a3daa2aeee95f2c025d516"
+ integrity sha512-9nyG3dgAclXuAyOsHBpQq0Q15SwQXkGvifczfiKnyd3srjWrsl4ZhHiE3ZrBBshenoK76NwPxATazf/lU83JNg==
+
+"@swc/html-linux-x64-gnu@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.15.13.tgz#16f72d180846bdb27b60038cd48582f2c8307488"
+ integrity sha512-yzpOYvLXXDqplHrr9wVImJ+QBLeubP7m92zZTQaW8rdhag01bX2Y/+829emT58K3SfLJTiJdKBYsL3q3mbVWrg==
+
+"@swc/html-linux-x64-musl@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.15.13.tgz#4acf02ef41ee7dfc38cd824be81f79e7adc04483"
+ integrity sha512-VakiAq/YTiSP3TcWKL6Vo5qu7iS8M647T22zGNNMc4D/gxg57R+89SITc1zCphR6p9rEh7vx6bk8/b8NXgYZeQ==
+
+"@swc/html-win32-arm64-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.15.13.tgz#3df9183ef9e9d3d08cf1b830a50c72fade286240"
+ integrity sha512-AhO5wmpnK5doUDDkOLqoPMDnNUrY3xa5HShiqiZBiGH2opB++kys77Q1Q9iW9ZKZgAiFLLZmiqVfcQRjhgdy0g==
+
+"@swc/html-win32-ia32-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.15.13.tgz#1586e4b4d6aaf1d69ad93f58b5b996bcaca91705"
+ integrity sha512-nyjUqwCSezmrWOBTCUf5EXl1oU+Fk/x+zSvvmrEGLAUo7fgpmSJtsNveODkZ8M755MI13ANdO8XkPg0UhYM+4g==
+
+"@swc/html-win32-x64-msvc@1.15.13":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.15.13.tgz#d00f0c1fb82658ccb2f3f92a8d0ae98c7214434c"
+ integrity sha512-ClKtII06nneMXik7dURXOlkPX8XyyBKE/3VfAAEC7B4E00m228gOy4CwTy9E2TDCeo6eqdePcSETSQzY8uOe8w==
+
+"@swc/html@^1.13.5":
+ version "1.15.13"
+ resolved "https://registry.yarnpkg.com/@swc/html/-/html-1.15.13.tgz#4f1a1e6f70e4fa31732f2acffb2f8b9968da9dcd"
+ integrity sha512-3eICmZEt1QTYEF++ZiyGULhuB3QSyoDaFXRjq2Dso7gD8yENeZ00HHpGt340ievtve11BYSD3rVlPRN3/BGlIA==
+ dependencies:
+ "@swc/counter" "^0.1.3"
+ optionalDependencies:
+ "@swc/html-darwin-arm64" "1.15.13"
+ "@swc/html-darwin-x64" "1.15.13"
+ "@swc/html-linux-arm-gnueabihf" "1.15.13"
+ "@swc/html-linux-arm64-gnu" "1.15.13"
+ "@swc/html-linux-arm64-musl" "1.15.13"
+ "@swc/html-linux-x64-gnu" "1.15.13"
+ "@swc/html-linux-x64-musl" "1.15.13"
+ "@swc/html-win32-arm64-msvc" "1.15.13"
+ "@swc/html-win32-ia32-msvc" "1.15.13"
+ "@swc/html-win32-x64-msvc" "1.15.13"
+
"@swc/types@^0.1.25":
version "0.1.25"
resolved "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz"
@@ -4143,6 +4451,13 @@
resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
+"@tybys/wasm-util@^0.10.1":
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414"
+ integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==
+ dependencies:
+ tslib "^2.4.0"
+
"@types/body-parser@*":
version "1.19.6"
resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz"
@@ -5645,7 +5960,7 @@ browser-assert@^1.2.1:
resolved "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz"
integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==
-browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.0, browserslist@^4.25.3, browserslist@^4.28.1:
+browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.2, browserslist@^4.24.4, browserslist@^4.25.0, browserslist@^4.25.3, browserslist@^4.28.1:
version "4.28.1"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz"
integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==
@@ -9589,6 +9904,80 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
+lightningcss-android-arm64@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz#609ff48332adff452a8157a7c2842fd692a8eac4"
+ integrity sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==
+
+lightningcss-darwin-arm64@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz#a13da040a7929582bab3ace9a67bdc146e99fc2d"
+ integrity sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==
+
+lightningcss-darwin-x64@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz#f7482c311273571ec0c2bd8277c1f5f6e90e03a4"
+ integrity sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==
+
+lightningcss-freebsd-x64@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz#91df1bb290f1cb7bb2af832d7d0d8809225e0124"
+ integrity sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==
+
+lightningcss-linux-arm-gnueabihf@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz#c3cad5ae8b70045f21600dc95295ab6166acf57e"
+ integrity sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==
+
+lightningcss-linux-arm64-gnu@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz#a5c4f6a5ac77447093f61b209c0bd7fef1f0a3e3"
+ integrity sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==
+
+lightningcss-linux-arm64-musl@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz#af26ab8f829b727ada0a200938a6c8796ff36900"
+ integrity sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==
+
+lightningcss-linux-x64-gnu@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz#a891d44e84b71c0d88959feb9a7522bbf61450ee"
+ integrity sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==
+
+lightningcss-linux-x64-musl@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz#8c8b21def851f4d477fa897b80cb3db2b650bc6e"
+ integrity sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==
+
+lightningcss-win32-arm64-msvc@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz#79000fb8c57e94a91b8fc643e74d5a54407d7080"
+ integrity sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==
+
+lightningcss-win32-x64-msvc@1.31.1:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz#7f025274c81c7d659829731e09c8b6f442209837"
+ integrity sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==
+
+lightningcss@^1.27.0:
+ version "1.31.1"
+ resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.31.1.tgz#1a19dd327b547a7eda1d5c296ebe1e72df5a184b"
+ integrity sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==
+ dependencies:
+ detect-libc "^2.0.3"
+ optionalDependencies:
+ lightningcss-android-arm64 "1.31.1"
+ lightningcss-darwin-arm64 "1.31.1"
+ lightningcss-darwin-x64 "1.31.1"
+ lightningcss-freebsd-x64 "1.31.1"
+ lightningcss-linux-arm-gnueabihf "1.31.1"
+ lightningcss-linux-arm64-gnu "1.31.1"
+ lightningcss-linux-arm64-musl "1.31.1"
+ lightningcss-linux-x64-gnu "1.31.1"
+ lightningcss-linux-x64-musl "1.31.1"
+ lightningcss-win32-arm64-msvc "1.31.1"
+ lightningcss-win32-x64-msvc "1.31.1"
+
lilconfig@^3.1.1:
version "3.1.3"
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz"
@@ -14107,7 +14496,7 @@ swagger2openapi@7.0.8, swagger2openapi@^7.0.8:
yaml "^1.10.0"
yargs "^17.0.1"
-swc-loader@^0.2.7:
+swc-loader@^0.2.6, swc-loader@^0.2.7:
version "0.2.7"
resolved "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz"
integrity sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==
@@ -14327,7 +14716,7 @@ ts-toolbelt@^9.6.0:
resolved "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz"
integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==
-tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.3.0, tslib@^2.6.0:
+tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.0:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==