Compare commits

..

1 Commits

Author SHA1 Message Date
Elizabeth Thompson
98212189b8 fix(docker): bind webpack dev server to all interfaces
Change WEBPACK_DEVSERVER_HOST from 127.0.0.1 to 0.0.0.0 to make the
frontend accessible from outside the Docker container. This fixes an
issue where the frontend was only accessible from inside the container.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 17:03:49 -07:00
656 changed files with 6547 additions and 19098 deletions

View File

@@ -1,10 +0,0 @@
# JavaScript to TypeScript Migration Command
## Usage
```
/js-to-ts <core-filename>
```
- `<core-filename>` - Path to CORE file relative to `superset-frontend/` (e.g., `src/utils/common.js`, `src/middleware/loggerMiddleware.js`)
## Agent Instructions
**See:** [../projects/js-to-ts/AGENT.md](../projects/js-to-ts/AGENT.md) for complete migration guide.

View File

@@ -1,684 +0,0 @@
# JavaScript to TypeScript Migration Agent Guide
**Complete technical reference for converting JavaScript/JSX files to TypeScript/TSX in Apache Superset frontend.**
**Agent Role:** Atomic migration unit - migrate the core file + ALL related tests/mocks as one cohesive unit. Use `git mv` to preserve history, NO `git commit`. NO global import changes. Report results upon completion.
---
## 🎯 Migration Principles
1. **Atomic migration units** - Core file + all related tests/mocks migrate together
2. **Zero `any` types** - Use proper TypeScript throughout
3. **Leverage existing types** - Reuse established definitions
4. **Type inheritance** - Derivatives extend base component types
5. **Strategic placement** - File types for maximum discoverability
6. **Surgical improvements** - Enhance existing types during migration
---
## Step 0: Dependency Check (MANDATORY)
**Command:**
```bash
grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" superset-frontend/{filename}
```
**Decision:**
- ✅ No matches → Proceed with atomic migration (core + tests + mocks)
- ❌ Matches found → EXIT with dependency report (see format below)
---
## Step 1: Identify Related Files (REQUIRED)
**Atomic Migration Scope:**
For core file `src/utils/example.js`, also migrate:
- `src/utils/example.test.js` / `src/utils/example.test.jsx`
- `src/utils/example.spec.js` / `src/utils/example.spec.jsx`
- `src/utils/__mocks__/example.js`
- Any other related test/mock files found by pattern matching
**Find all related test and mock files:**
```bash
# Pattern-based search for related files
basename=$(basename {filename} .js)
dirname=$(dirname superset-frontend/{filename})
# Find test files
find "$dirname" -name "${basename}.test.js" -o -name "${basename}.test.jsx"
find "$dirname" -name "${basename}.spec.js" -o -name "${basename}.spec.jsx"
# Find mock files
find "$dirname" -name "__mocks__/${basename}.js"
find "$dirname" -name "${basename}.mock.js"
```
**Migration Requirement:** All discovered related files MUST be migrated together as one atomic unit.
**Test File Creation:** If NO test files exist for the core file, CREATE a minimal test file using the following pattern:
- Location: Same directory as core file
- Name: `{basename}.test.ts` (e.g., `DebouncedMessageQueue.test.ts`)
- Content: Basic test structure importing and testing the main functionality
- Use proper TypeScript types in test file
---
## 🗺️ Type Reference Map
### From `@superset-ui/core`
```typescript
// Data & Query
QueryFormData, QueryData, JsonObject, AnnotationData, AdhocMetric
LatestQueryFormData, GenericDataType, DatasourceType, ExtraFormData
DataMaskStateWithId, NativeFilterScope, NativeFiltersState, NativeFilterTarget
// UI & Theme
FeatureFlagMap, LanguagePack, ColorSchemeConfig, SequentialSchemeConfig
```
### From `@superset-ui/chart-controls`
```typescript
Dataset, ColumnMeta, ControlStateMapping
```
### From Local Types (`src/types/`)
```typescript
// Authentication
User, UserWithPermissionsAndRoles, BootstrapUser, PermissionsAndRoles
// Dashboard
Dashboard, DashboardState, DashboardInfo, DashboardLayout, LayoutItem
ComponentType, ChartConfiguration, ActiveFilters
// Charts
Chart, ChartState, ChartStatus, ChartLinkedDashboard, Slice, SaveActionType
// Data
Datasource, Database, Owner, Role
// UI Components
TagType, FavoriteStatus, Filter, ImportResourceName
```
### From Domain Types
```typescript
// src/dashboard/types.ts
RootState, ChartsState, DatasourcesState, FilterBarOrientation
ChartCrossFiltersConfig, ActiveTabs, MenuKeys
// src/explore/types.ts
ExplorePageInitialData, ExplorePageState, ExploreResponsePayload, OptionSortType
// src/SqlLab/types.ts
[SQL Lab specific types]
```
---
## 🏗️ Type Organization Strategy
### Type Placement Hierarchy
1. **Component-Colocated** (90% of cases)
```typescript
// Same file as component
interface MyComponentProps {
title: string;
onClick: () => void;
}
```
2. **Feature-Shared**
```typescript
// src/[domain]/components/[Feature]/types.ts
export interface FilterConfiguration {
filterId: string;
targets: NativeFilterTarget[];
}
```
3. **Domain-Wide**
```typescript
// src/[domain]/types.ts
export interface ExploreFormData extends QueryFormData {
viz_type: string;
}
```
4. **Global**
```typescript
// src/types/[TypeName].ts
export interface ApiResponse<T> {
result: T;
count?: number;
}
```
### Type Discovery Commands
```bash
# Search existing types before creating
find superset-frontend/src -name "types.ts" -exec grep -l "[TypeConcept]" {} \;
grep -r "interface.*Props\|type.*Props" superset-frontend/src/
```
### Derivative Component Patterns
**Rule:** Components that extend others should extend their type interfaces.
```typescript
// ✅ Base component type
interface SelectProps {
value: string | number;
options: SelectOption[];
onChange: (value: string | number) => void;
disabled?: boolean;
}
// ✅ Derivative extends base
interface ChartSelectProps extends SelectProps {
charts: Chart[];
onChartSelect: (chart: Chart) => void;
}
// ✅ Derivative with modified props
interface DatabaseSelectProps extends Omit<SelectProps, 'value' | 'onChange'> {
value: number; // Narrowed type
onChange: (databaseId: number) => void; // Specific signature
}
```
**Common Patterns:**
- **Extension:** `extends BaseProps` - adds new props
- **Omission:** `Omit<BaseProps, 'prop'>` - removes props
- **Modification:** `Omit<BaseProps, 'prop'> & { prop: NewType }` - changes prop type
- **Restriction:** Override with narrower types (union → specific)
---
## 📋 Migration Recipe
### Step 2: File Conversion
```bash
# Use git mv to preserve history
git mv component.js component.ts
git mv Component.jsx Component.tsx
```
### Step 3: Import & Type Setup
```typescript
// Import order (enforced by linting)
import { FC, ReactNode } from 'react';
import { JsonObject, QueryFormData } from '@superset-ui/core';
import { Dataset } from '@superset-ui/chart-controls';
import type { Dashboard } from 'src/types/Dashboard';
```
### Step 4: Function & Component Typing
```typescript
// Functions with proper parameter/return types
export function processData(
data: Dataset[],
config: JsonObject
): ProcessedData[] {
// implementation
}
// Component props with inheritance
interface ComponentProps extends BaseProps {
data: Chart[];
onSelect: (id: number) => void;
}
const Component: FC<ComponentProps> = ({ data, onSelect }) => {
// implementation
};
```
### Step 5: State & Redux Typing
```typescript
// Hooks with specific types
const [data, setData] = useState<Chart[]>([]);
const [selected, setSelected] = useState<number | null>(null);
// Redux with existing RootState
const mapStateToProps = (state: RootState) => ({
charts: state.charts,
user: state.user,
});
```
---
## 🧠 Type Debugging Strategies (Real-World Learnings)
### The Evolution of Type Approaches
When you hit type errors, follow this debugging evolution:
#### 1. ❌ Idealized Union Types (First Attempt)
```typescript
// Looks clean but doesn't match reality
type DatasourceInput = Datasource | QueryEditor;
```
**Problem**: Real calling sites pass variations, not exact types.
#### 2. ❌ Overly Precise Types (Second Attempt)
```typescript
// Tried to match exact calling signatures
type DatasourceInput =
| IDatasource // From DatasourcePanel
| (QueryEditor & { columns: ColumnMeta[] }); // From SaveQuery
```
**Problem**: Too rigid, doesn't handle legacy variations.
#### 3. ✅ Flexible Interface (Final Solution)
```typescript
// Captures what the function actually needs
interface DatasourceInput {
name?: string | null; // Allow null for compatibility
datasource_name?: string | null; // Legacy variations
columns?: any[]; // Multiple column types accepted
database?: { id?: number };
// ... other optional properties
}
```
**Success**: Works with all calling sites, focuses on function needs.
### Type Debugging Process
1. **Start with compilation errors** - they show exact mismatches
2. **Examine actual usage** - look at calling sites, not idealized types
3. **Build flexible interfaces** - capture what functions need, not rigid contracts
4. **Iterate based on downstream validation** - let calling sites guide your types
---
## 🚨 Anti-Patterns to Avoid
```typescript
// ❌ Never use any
const obj: any = {};
// ✅ Use proper types
const obj: Record<string, JsonObject> = {};
// ❌ Don't recreate base component props
interface ChartSelectProps {
value: string; // Duplicated from SelectProps
onChange: () => void; // Duplicated from SelectProps
charts: Chart[]; // New prop
}
// ✅ Inherit and extend
interface ChartSelectProps extends SelectProps {
charts: Chart[]; // Only new props
}
// ❌ Don't create ad-hoc type variations
interface UserInfo {
name: string;
email: string;
}
// ✅ Extend existing types (DRY principle)
import { User } from 'src/types/bootstrapTypes';
type UserDisplayInfo = Pick<User, 'firstName' | 'lastName' | 'email'>;
// ❌ Don't create overly rigid unions
type StrictInput = ExactTypeA | ExactTypeB;
// ✅ Create flexible interfaces for function parameters
interface FlexibleInput {
// Focus on what the function actually needs
commonProperty: string;
optionalVariations?: any; // Allow for legacy variations
}
```
## 📍 DRY Type Guidelines (WHERE TYPES BELONG)
### Type Placement Rules
**CRITICAL**: Type variations must live close to where they belong, not scattered across files.
#### ✅ Proper Type Organization
```typescript
// ❌ Don't create one-off interfaces in utility files
// src/utils/datasourceUtils.ts
interface DatasourceInput { /* custom interface */ } // Wrong!
// ✅ Use existing types or extend them in their proper domain
// src/utils/datasourceUtils.ts
import { IDatasource } from 'src/explore/components/DatasourcePanel';
import { QueryEditor } from 'src/SqlLab/types';
// Create flexible interface that references existing types
interface FlexibleDatasourceInput {
// Properties that actually exist across variations
}
```
#### Type Location Hierarchy
1. **Domain Types**: `src/{domain}/types.ts` (dashboard, explore, SqlLab)
2. **Component Types**: Co-located with components
3. **Global Types**: `src/types/` directory
4. **Utility Types**: Only when they truly don't belong elsewhere
#### ✅ DRY Type Patterns
```typescript
// ✅ Extend existing domain types
interface SaveQueryData extends Pick<QueryEditor, 'sql' | 'dbId' | 'catalog'> {
columns: ColumnMeta[]; // Add what's needed
}
// ✅ Create flexible interfaces for cross-domain utilities
interface CrossDomainInput {
// Common properties that exist across different source types
name?: string | null; // Accommodate legacy null values
// Only include properties the function actually uses
}
```
---
## 🎯 PropTypes Auto-Generation (Elegant Approach)
**IMPORTANT**: Superset has `babel-plugin-typescript-to-proptypes` configured to automatically generate PropTypes from TypeScript interfaces. Use this instead of manual PropTypes duplication!
### ❌ Manual PropTypes Duplication (Avoid This)
```typescript
export interface MyComponentProps {
title: string;
count?: number;
}
// 8+ lines of manual PropTypes duplication 😱
const propTypes = PropTypes.shape({
title: PropTypes.string.isRequired,
count: PropTypes.number,
});
export default propTypes;
```
### ✅ Auto-Generated PropTypes (Use This)
```typescript
import { InferProps } from 'prop-types';
export interface MyComponentProps {
title: string;
count?: number;
}
// Single validator function - babel plugin auto-generates PropTypes! ✨
export default function MyComponentValidator(props: MyComponentProps) {
return null; // PropTypes auto-assigned by babel-plugin-typescript-to-proptypes
}
// Optional: For consumers needing PropTypes type inference
export type MyComponentPropsInferred = InferProps<typeof MyComponentValidator>;
```
### Migration Pattern for Type-Only Files
**When migrating type-only files with manual PropTypes:**
1. **Keep the TypeScript interfaces** (single source of truth)
2. **Replace manual PropTypes** with validator function
3. **Remove PropTypes imports** and manual shape definitions
4. **Add InferProps import** if type inference needed
**Example Migration:**
```typescript
// Before: 25+ lines with manual PropTypes duplication
export interface AdhocFilterType { /* ... */ }
const adhocFilterTypePropTypes = PropTypes.oneOfType([...]);
// After: 3 lines with auto-generation
export interface AdhocFilterType { /* ... */ }
export default function AdhocFilterValidator(props: { filter: AdhocFilterType }) {
return null; // Auto-generated PropTypes by babel plugin
}
```
### Component PropTypes Pattern
**For React components, the babel plugin works automatically:**
```typescript
interface ComponentProps {
title: string;
onClick: () => void;
}
const MyComponent: FC<ComponentProps> = ({ title, onClick }) => {
// Component implementation
};
// PropTypes automatically generated by babel plugin - no manual work needed!
export default MyComponent;
```
### Auto-Generation Benefits
- ✅ **Single source of truth**: TypeScript interfaces drive PropTypes
- ✅ **No duplication**: Eliminate 15-20 lines of manual PropTypes code
- ✅ **Automatic updates**: Changes to TypeScript automatically update PropTypes
- ✅ **Type safety**: Compile-time checking ensures PropTypes match interfaces
- ✅ **Backward compatibility**: Existing JavaScript components continue working
### Babel Plugin Configuration
The plugin is already configured in `babel.config.js`:
```javascript
['babel-plugin-typescript-to-proptypes', { loose: true }]
```
**No additional setup required** - just use TypeScript interfaces and the plugin handles the rest!
---
## 🧪 Test File Migration Patterns
### Test File Priority
- **Always migrate test files** alongside production files
- **Test files are often leaf nodes** - good starting candidates
- **Create tests if missing** - Leverage new TypeScript types for better test coverage
### Test-Specific Type Patterns
```typescript
// Mock interfaces for testing
interface MockStore {
getState: () => Partial<RootState>; // Partial allows minimal mocking
}
// Type-safe mocking for complex objects
const mockDashboardInfo: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
};
// Sinon stub typing
let postStub: sinon.SinonStub;
beforeEach(() => {
postStub = sinon.stub(SupersetClient, 'post');
});
// Use stub reference instead of original method
expect(postStub.callCount).toBe(1);
expect(postStub.getCall(0).args[0].endpoint).toMatch('/api/');
```
### Test Migration Recipe
1. **Migrate production file first** (if both need migration)
2. **Update test imports** to point to `.ts/.tsx` files
3. **Add proper mock typing** using `Partial<T> as T` pattern
4. **Fix stub typing** - Use stub references, not original methods
5. **Verify all tests pass** with TypeScript compilation
---
## 🔧 Type Conflict Resolution
### Multiple Type Definitions Issue
**Problem**: Same type name defined in multiple files causes compilation errors.
**Example**: `DashboardInfo` defined in both:
- `src/dashboard/reducers/types.ts` (minimal)
- `src/dashboard/components/Header/types.ts` (different shape)
- `src/dashboard/types.ts` (complete - used by RootState)
### Resolution Strategy
1. **Identify the authoritative type**:
```bash
# Find which type is used by RootState/main interfaces
grep -r "DashboardInfo" src/dashboard/types.ts
```
2. **Use import from authoritative source**:
```typescript
// ✅ Import from main domain types
import { RootState, DashboardInfo } from 'src/dashboard/types';
// ❌ Don't import from component-specific files
import { DashboardInfo } from 'src/dashboard/components/Header/types';
```
3. **Mock complex types in tests**:
```typescript
// For testing - provide minimal required fields
const mockInfo: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
// Only provide fields actually used in test
};
```
### Type Hierarchy Discovery Commands
```bash
# Find all definitions of a type
grep -r "interface.*TypeName\|type.*TypeName" src/
# Find import usage patterns
grep -r "import.*TypeName" src/
# Check what RootState uses
grep -A 10 -B 10 "TypeName" src/*/types.ts
```
---
## Agent Constraints (CRITICAL)
1. **Use git mv** - Run `git mv file.js file.ts` to preserve git history, but NO `git commit`
2. **NO global import changes** - Don't update imports across codebase
3. **Type files OK** - Can modify existing type files to improve/align types
4. **Single-File TypeScript Validation** (CRITICAL) - tsc has known issues with multi-file compilation:
- **Core Issue**: TypeScript's `tsc` has documented problems validating multiple files simultaneously in complex projects
- **Solution**: ALWAYS validate files one at a time using individual `tsc` calls
- **Command Pattern**: `cd superset-frontend && npx tscw --noEmit --allowJs --composite false --project tsconfig.json {single-file-path}`
- **Why**: Multi-file validation can produce false positives, miss real errors, and conflict during parallel agent execution
5. **Downstream Impact Validation** (CRITICAL) - Your migration affects calling sites:
- **Find downstream files**: `find superset-frontend/src -name "*.tsx" -o -name "*.ts" | xargs grep -l "your-core-filename" 2>/dev/null || echo "No files found"`
- **Validate each downstream file individually**: `cd superset-frontend && npx tscw --noEmit --allowJs --composite false --project tsconfig.json {each-downstream-file}`
- **Fix type mismatches** you introduced in calling sites
- **NEVER ignore downstream errors** - they indicate your types don't match reality
6. **Avoid Project-Wide Validation During Migration**:
- **NEVER use `npm run type`** during parallel agent execution - produces unreliable results
- **Single-file validation is authoritative** - trust individual file checks over project-wide scans
6. **ESLint validation** - Run `npm run eslint -- --fix {file}` for each migrated file to auto-fix formatting/linting issues
6. Zero `any` types - use proper TypeScript types
7. Search existing types before creating new ones
8. Follow patterns from this guide
---
## Success Report Format
```
SUCCESS: Atomic Migration of {core-filename}
## Files Migrated (Atomic Unit)
- Core: {core-filename} → {core-filename.ts/tsx}
- Tests: {list-of-test-files} → {list-of-test-files.ts/tsx} OR "CREATED: {basename}.test.ts"
- Mocks: {list-of-mock-files} → {list-of-mock-files.ts}
- Type files modified: {list-of-type-files}
## Types Created/Improved
- {TypeName}: {location} ({scope}) - {rationale}
- {ExistingType}: enhanced in {location} - {improvement-description}
## Documentation Recommendations
- ADD_TO_DIRECTORY: {TypeName} - {reason}
- NO_DOCUMENTATION: {TypeName} - {reason}
## Quality Validation
- **Single-File TypeScript Validation**: ✅ PASS - Core files individually validated
- Core file: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {core-file}`
- Test files: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {test-file}` (if exists)
- **Downstream Impact Check**: ✅ PASS - Found {N} files importing this module, all validate individually
- Downstream files: {list-of-files-that-import-your-module}
- Individual validation: `npx tscw --noEmit --allowJs --composite false --project tsconfig.json {each-downstream-file}`
- **ESLint validation**: ✅ PASS (using `npm run eslint -- --fix {files}` to auto-fix formatting)
- **Zero any types**: ✅ PASS
- **Local imports resolved**: ✅ PASS
- **Functionality preserved**: ✅ PASS
- **Tests pass** (if test file): ✅ PASS
- **Follow-up action required**: {YES/NO}
## Validation Strategy Notes
- **Single-file approach used**: Avoided multi-file tsc validation due to known TypeScript compilation issues
- **Project-wide validation skipped**: `npm run type` not used during parallel migration to prevent false positives
## Migration Learnings
- Type conflicts encountered: {describe any multiple type definitions}
- Mock patterns used: {describe test mocking approaches}
- Import hierarchy decisions: {note authoritative type sources used}
- PropTypes strategy: {AUTO_GENERATED via babel plugin | MANUAL_DUPLICATION_REMOVED | N/A}
## Improvement Suggestions for Documentation
- AGENT.md enhancement: {suggest additions to migration guide}
- Common pattern identified: {note reusable patterns for future migrations}
```
---
## Dependency Block Report Format
```
DEPENDENCY_BLOCK: Cannot migrate {filename}
## Blocking Dependencies
- {path}: {type} - {usage} - {priority}
## Impact Analysis
- Estimated types: {number}
- Expected locations: {list}
- Cross-domain: {YES/NO}
## Recommended Order
{ordered-list}
```
---
## 📚 Quick Reference
**Type Utilities:**
- `Record<K, V>` - Object with specific key/value types
- `Partial<T>` - All properties optional
- `Pick<T, K>` - Subset of properties
- `Omit<T, K>` - Exclude specific properties
- `NonNullable<T>` - Exclude null/undefined
**Event Types:**
- `MouseEvent<HTMLButtonElement>`
- `ChangeEvent<HTMLInputElement>`
- `FormEvent<HTMLFormElement>`
**React Types:**
- `FC<Props>` - Functional component
- `ReactNode` - Any renderable content
- `CSSProperties` - Style objects
---
**Remember:** Every type should add value and clarity. The goal is meaningful type safety that catches bugs and improves developer experience.

View File

@@ -1,199 +0,0 @@
# JS-to-TS Coordinator Workflow
**Role:** Strategic migration coordination - select leaf-node files, trigger agents, review results, handle integration, manage dependencies.
---
## 1. Core File Selection Strategy
**Target ONLY Core Files**: Coordinators identify core files (production code), agents handle related tests/mocks atomically.
**File Analysis Commands**:
```bash
# Find CORE files with no JS/JSX dependencies (exclude tests/mocks) - SIZE PRIORITIZED
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | xargs wc -l | sort -n | head -20
# Alternative: Get file sizes in lines with paths
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | while read file; do
lines=$(wc -l < "$file")
echo "$lines $file"
done | sort -n | head -20
# Check dependencies for core files only (start with smallest)
for file in <core-files-sorted-by-size>; do
echo "=== $file ($(wc -l < "$file") lines) ==="
grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" "$file" || echo "✅ LEAF CANDIDATE"
done
# Identify heavily imported files (migrate last)
grep -r "from.*utils/common" superset-frontend/src/ | wc -l
# Quick leaf analysis with size priority
find superset-frontend/src -name "*.js" -o -name "*.jsx" | grep -v "test\|spec\|mock" | head -30 | while read file; do
deps=$(grep -E "from '\.\./.*\.jsx?'|from '\./.*\.jsx?'|from 'src/.*\.jsx?'" "$file" | wc -l)
lines=$(wc -l < "$file")
if [ "$deps" -eq 0 ]; then
echo "✅ LEAF: $lines lines - $file"
fi
done | sort -n
```
**Priority Order** (Smallest files first for easier wins):
1. **Small leaf files** (<50 lines) - No JS/JSX imports, quick TypeScript conversion
2. **Medium leaf files** (50-200 lines) - Self-contained utilities and helpers
3. **Small dependency files** (<100 lines) - Import only already-migrated files
4. **Larger components** (200+ lines) - Complex but well-contained functionality
5. **Core foundational files** (utils/common.js, controls.jsx) - migrate last regardless of size
**Size-First Benefits**:
- Faster completion builds momentum
- Earlier validation of migration patterns
- Easier rollback if issues arise
- Better success rate for agent learning
**Migration Unit**: Each agent call migrates:
- 1 core file (primary target)
- All related `*.test.js/jsx` files
- All related `*.mock.js` files
- All related `__mocks__/` files
---
## 2. Task Creation & Agent Control
### Task Triggering
When triggering the `/js-to-ts` command:
- **Task Title**: Use the core filename as the task title (e.g., "DebouncedMessageQueue.js migration", "hostNamesConfig.js migration")
- **Task Description**: Include the full relative path to help agent locate the file
- **Reference**: Point agent to [AGENT.md](./AGENT.md) for technical instructions
### Post-Processing Workflow
After each agent completes:
1. **Review Agent Report**: Always read and analyze the complete agent report
2. **Share Summary**: Provide user with key highlights from agent's work:
- Files migrated (core + tests/mocks)
- Types created or improved
- Any validation issues or coordinator actions needed
3. **Quality Assessment**: Evaluate agent's TypeScript implementation against criteria:
-**Type Usage**: Proper types used, no `any` types
-**Type Filing**: Types placed in correct hierarchy (component → feature → domain → global)
-**Side Effects**: No unintended changes to other files
-**Import Alignment**: Proper .ts/.tsx import extensions
4. **Integration Decision**:
- **COMMIT**: If agent work is complete and high quality
- **FIX & COMMIT**: If minor issues need coordinator fixes
- **ROLLBACK**: If major issues require complete rework
5. **Next Action**: Ask user preference - commit this work or trigger next migration
---
## 3. Integration Decision Framework
**Automatic Integration** ✅:
- `npm run type` passes without errors
- Agent created clean TypeScript with proper types
- Types appropriately filed in hierarchy
**Coordinator Integration** (Fix Side-Effects) 🔧:
- `npm run type` fails BUT agent's work is high quality
- Good type usage, proper patterns, well-organized
- Side-effects are manageable TypeScript compilation errors
- **Coordinator Action**: Integrate the change, then fix global compilation issues
**Rollback Only** ❌:
- Agent introduced `any` types or poor type choices
- Types poorly organized or conflicting with existing patterns
- Fundamental approach issues requiring complete rework
**Integration Process**:
1. **Review**: Agent already used `git mv` to preserve history
2. **Fix Side-Effects**: Update dependent files with proper import extensions
3. **Resolve Types**: Fix any cascading type issues across codebase
4. **Validate**: Ensure `npm run type` passes after fixes
---
## 4. Common Integration Patterns
**Common Side-Effects (Expect These)**:
- **Type import conflicts**: Multiple definitions of same type name
- **Mock object typing**: Tests need complete type satisfaction
- **Stub method references**: Use stub vars instead of original methods
**Coordinator Fixes (Standard Process)**:
1. **Import Resolution**:
```bash
# Find authoritative type source
grep -r "TypeName" src/*/types.ts
# Import from domain types (src/dashboard/types.ts) not component types
```
2. **Test Mock Completion**:
```typescript
// Use Partial<T> as T pattern for minimal mocking
const mockDashboard: Partial<DashboardInfo> as DashboardInfo = {
id: 123,
json_metadata: '{}',
};
```
3. **Stub Reference Fixes**:
```typescript
// ✅ Use stub variable
expect(postStub.callCount).toBe(1);
// ❌ Don't use original method
expect(SupersetClient.post.callCount).toBe(1);
```
4. **Validation Commands**:
```bash
npm run type # TypeScript compilation
npm test -- filename # Test functionality
git status # Should show rename, not add/delete
```
---
## 5. File Categories for Planning
### Leaf Files (Start Here)
**Self-contained files with minimal JS/JSX dependencies**:
- Test files (80 files) - Usually only import the file being tested
- Utility files without internal dependencies
- Components importing only external libraries
### Heavily Imported Files (Migrate Last)
**Core files that many others depend on**:
- `utils/common.js` - Core utility functions
- `utils/reducerUtils.js` - Redux helpers
- `@superset-ui/core` equivalent files
- Major state management files (`explore/store.js`, `dashboard/actions/`)
### Complex Components (Middle Priority)
**Large files requiring careful type analysis**:
- `components/Datasource/DatasourceEditor.jsx` (1,809 lines)
- `explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx` (1,031 lines)
- `explore/components/ExploreViewContainer/index.jsx` (911 lines)
---
## 6. Success Metrics & Continuous Improvement
**Per-File Gates**:
- ✅ `npm run type` passes after each migration
- ✅ Zero `any` types introduced
- ✅ All imports properly typed
- ✅ Types filed in correct hierarchy
**Linear Scheduling**:
When agents report `DEPENDENCY_BLOCK`:
- Queue dependencies in linear order
- Process one file at a time to avoid conflicts
- Handle cascading type changes between files
**After Each Migration**:
1. **Update guides** with new patterns discovered
2. **Document coordinator fixes** that become common
3. **Enhance agent instructions** based on recurring issues
4. **Track success metrics** - automatic vs coordinator integration rates

View File

@@ -1,76 +0,0 @@
# JavaScript to TypeScript Migration Project
Progressive migration of 219 JS/JSX files to TypeScript in Apache Superset frontend.
## 📁 Project Documentation
- **[AGENT.md](./AGENT.md)** - Complete technical migration guide for agents (includes type reference, patterns, validation)
- **[COORDINATOR.md](./COORDINATOR.md)** - Strategic workflow for coordinators (file selection, task management, integration)
## 🎯 Quick Start
**For Agents:** Read [AGENT.md](./AGENT.md) for complete migration instructions
**For Coordinators:** Read [COORDINATOR.md](./COORDINATOR.md) for workflow and [AGENT.md](./AGENT.md) for supervision
**Command:** `/js-to-ts <filename>` - See [../../commands/js-to-ts.md](../../commands/js-to-ts.md)
## 📊 Migration Progress
**Scope**: 219 files total (112 JS + 107 JSX)
- Production files: 139 (63%)
- Test files: 80 (37%)
**Strategy**: Leaf-first migration with dependency-aware coordination
### Completed Migrations ✅
1. **roundDecimal** - `plugins/legacy-plugin-chart-map-box/src/utils/roundDecimal.js`
- Migrated core + test files
- Added proper TypeScript function signature with optional precision parameter
- All tests pass
2. **timeGrainSqlaAnimationOverrides** - `src/explore/controlPanels/timeGrainSqlaAnimationOverrides.js`
- Migrated to TypeScript with ControlPanelState and Dataset types
- Added TimeGrainOverrideState interface for return type
- Used type guards for safe property access
3. **DebouncedMessageQueue** - `src/utils/DebouncedMessageQueue.js`
- Migrated to TypeScript with proper generics
- Created DebouncedMessageQueueOptions interface
- **CREATED test file** with 4 comprehensive test cases
- Excellent class property typing with private/readonly modifiers
**Files Migrated**: 3/219 (1.4%)
**Tests Created**: 2 (roundDecimal had existing, DebouncedMessageQueue created)
### Next Candidates (Leaf Nodes) 🎯
**Identified leaf files with no JS/JSX dependencies:**
- `src/utils/hostNamesConfig.js` - Domain configuration utility
- `src/explore/controlPanels/Separator.js` - Control panel configuration
- `src/middleware/loggerMiddleware.js` - Logging middleware
**Migration Quality**: All completed migrations have:
- ✅ Zero `any` types
- ✅ Proper TypeScript compilation
- ✅ ESLint validation passed
- ✅ Test coverage (created where missing)
---
## 📈 Success Metrics
**Per-File Gates**:
-`npm run type` passes after each migration
- ✅ Zero `any` types introduced
- ✅ All imports properly typed
- ✅ Types filed in correct hierarchy
**Overall Progress**:
- **Automatic Integration Rate**: 100% (3/3 migrations required no coordinator fixes)
- **Test Coverage**: Improved (1 new test file created)
- **Type Safety**: Enhanced with proper interfaces and generics
---
*This is a claudette-managed progressive refactor. All documentation and coordination resources are organized under `.claude/projects/js-to-ts/`*

2
.github/CODEOWNERS vendored
View File

@@ -20,7 +20,7 @@
# Notify PMC members of changes to GitHub Actions
/.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar @sadpandajoe
/.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar
# Notify PMC members of changes to required GitHub Actions

View File

@@ -1 +1 @@
../AGENTS.md
../LLMS.md

View File

@@ -5,7 +5,7 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
interval: "monthly"
- package-ecosystem: "npm"
ignore:
@@ -18,7 +18,7 @@ updates:
- dependency-name: "jest-environment-jsdom"
directory: "/superset-frontend/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -40,21 +40,21 @@ updates:
- package-ecosystem: "npm"
directory: ".github/actions"
schedule:
interval: "daily"
interval: "monthly"
open-pull-requests-limit: 10
versioning-strategy: increase
- package-ecosystem: "npm"
directory: "/docs/"
schedule:
interval: "daily"
interval: "monthly"
open-pull-requests-limit: 10
versioning-strategy: increase
- package-ecosystem: "npm"
directory: "/superset-websocket/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -63,7 +63,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-websocket/utils/client-ws-app/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -75,7 +75,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-calendar/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -85,7 +85,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-histogram/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -95,7 +95,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-partition/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -105,7 +105,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-world-map/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -115,7 +115,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-pivot-table/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -125,7 +125,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-chord/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -135,7 +135,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-horizon/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -145,7 +145,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-rose/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -155,7 +155,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-preset-chart-deckgl/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -165,7 +165,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-table/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -175,7 +175,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-country-map/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -185,7 +185,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-map-box/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -195,7 +195,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -205,7 +205,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-preset-chart-nvd3/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -215,7 +215,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-word-cloud/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -225,7 +225,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-event-flow/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -235,7 +235,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-paired-t-test/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -245,7 +245,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -255,7 +255,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-echarts/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -265,7 +265,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/preset-chart-xy/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -275,7 +275,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-heatmap/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -285,7 +285,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-parallel-coordinates/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -295,7 +295,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/legacy-plugin-chart-sunburst/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -305,7 +305,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-handlebars/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -315,7 +315,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/packages/generator-superset/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -325,7 +325,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-chart-controls/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -339,7 +339,7 @@ updates:
- dependency-name: "react-markdown"
- dependency-name: "remark-gfm"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -349,7 +349,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-demo/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot
@@ -359,7 +359,7 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/packages/superset-ui-switchboard/"
schedule:
interval: "daily"
interval: "monthly"
labels:
- npm
- dependabot

View File

@@ -41,7 +41,7 @@ jobs:
uses: ./.github/actions/setup-supersetbot/
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v6
uses: actions/setup-python@v5
with:
python-version: "3.10"

View File

@@ -27,7 +27,7 @@ jobs:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v5
- name: Check and notify
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
script: |

View File

@@ -44,7 +44,7 @@ jobs:
pull-requests: write
steps:
- name: Comment access denied
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
script: |
const message = `👋 Hi @${{ github.event.comment.user.login || github.event.review.user.login || github.event.issue.user.login }}!

View File

@@ -29,7 +29,7 @@ jobs:
working-directory: superset-embedded-sdk
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
- uses: actions/setup-node@v4
with:
node-version-file: './superset-embedded-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org'

View File

@@ -19,7 +19,7 @@ jobs:
working-directory: superset-embedded-sdk
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
- uses: actions/setup-node@v4
with:
node-version-file: './superset-embedded-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org'

View File

@@ -33,7 +33,7 @@ jobs:
pull-requests: write
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -69,7 +69,7 @@ jobs:
- name: Comment (success)
if: steps.describe-services.outputs.active == 'true'
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{github.token}}
script: |

View File

@@ -63,7 +63,7 @@ jobs:
- name: Get event SHA
id: get-sha
if: steps.eval-label.outputs.result == 'up'
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
@@ -94,7 +94,7 @@ jobs:
core.setOutput("sha", prSha);
- name: Looking for feature flags in PR description
uses: actions/github-script@v8
uses: actions/github-script@v7
id: eval-feature-flags
if: steps.eval-label.outputs.result == 'up'
with:
@@ -116,7 +116,7 @@ jobs:
return results;
- name: Reply with confirmation comment
uses: actions/github-script@v8
uses: actions/github-script@v7
if: steps.eval-label.outputs.result == 'up'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -189,7 +189,7 @@ jobs:
--extra-flags "--build-arg INCLUDE_CHROMIUM=false"
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -225,7 +225,7 @@ jobs:
persist-credentials: false
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -248,7 +248,7 @@ jobs:
- name: Fail on missing container image
if: steps.check-image.outcome == 'failure'
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
script: |
@@ -318,7 +318,7 @@ jobs:
echo "ip=$(aws ec2 describe-network-interfaces --network-interface-ids ${{ steps.get-eni.outputs.eni }} | jq -r '.NetworkInterfaces | first | .Association.PublicIp')" >> $GITHUB_OUTPUT
- name: Comment (success)
if: ${{ success() }}
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{github.token}}
script: |
@@ -331,7 +331,7 @@ jobs:
});
- name: Comment (failure)
if: ${{ failure() }}
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{github.token}}
script: |

View File

@@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version: '20'

View File

@@ -9,7 +9,7 @@ jobs:
pull-requests: write
runs-on: ubuntu-24.04
steps:
- uses: actions/labeler@v6
- uses: actions/labeler@v5
with:
sync-labels: true

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Check for 'hold' label
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |

View File

@@ -39,7 +39,7 @@ jobs:
echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}"
brew install norwoodj/tap/helm-docs
- name: Setup Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version: '20'

View File

@@ -42,7 +42,7 @@ jobs:
- name: Install Node.js
if: env.HAS_TAGS
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'

View File

@@ -37,7 +37,7 @@ jobs:
steps:
- name: Security Check - Authorize Maintainers Only
id: auth
uses: actions/github-script@v8
uses: actions/github-script@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@@ -63,7 +63,7 @@ jobs:
with:
run: testdata
- name: Setup Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies

View File

@@ -36,7 +36,7 @@ jobs:
submodules: recursive
ref: master
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install eyes-storybook dependencies

View File

@@ -36,7 +36,7 @@ jobs:
persist-credentials: false
submodules: recursive
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './docs/.nvmrc'
- name: Setup Python

View File

@@ -21,14 +21,12 @@ jobs:
- uses: actions/checkout@v5
# Do not bump this linkinator-action version without opening
# an ASF Infra ticket to allow the new version first!
- uses: JustinBeckwith/linkinator-action@3d5ba091319fa7b0ac14703761eebb7d100e6f6d # v1.11.0
- uses: JustinBeckwith/linkinator-action@v1.11.0
continue-on-error: true # This will make the job advisory (non-blocking, no red X)
with:
paths: "**/*.md, **/*.mdx"
paths: "**/*.md, **/*.mdx, !superset-frontend/CHANGELOG.md"
linksToSkip: >-
^https://github.com/apache/(superset|incubator-superset)/(pull|issues)/\d+,
^https://github.com/apache/(superset|incubator-superset)/commit/[a-f0-9]+,
superset-frontend/.*CHANGELOG\.md,
^https://github.com/apache/(superset|incubator-superset)/(pull|issue)/\d+,
http://localhost:8088/,
http://127.0.0.1:3000/,
http://localhost:9001/,
@@ -43,12 +41,12 @@ jobs:
http://theiconic.com.au/,
https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html,
^https://img\.shields\.io/.*,
https://vkusvill.ru/,
https://www.linkedin.com/in/mark-thomas-b16751158/,
https://theiconic.com.au/,
https://wattbewerb.de/,
https://timbr.ai/,
https://opensource.org/license/apache-2-0,
https://vkusvill.ru/
https://www.linkedin.com/in/mark-thomas-b16751158/
https://theiconic.com.au/
https://wattbewerb.de/
https://timbr.ai/
https://opensource.org/license/apache-2-0
https://www.plaidcloud.com/
build-deploy:
name: Build & Deploy
@@ -63,7 +61,7 @@ jobs:
persist-credentials: false
submodules: recursive
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './docs/.nvmrc'
- name: yarn install

View File

@@ -109,7 +109,7 @@ jobs:
run: testdata
- name: Setup Node.js
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies

View File

@@ -101,7 +101,7 @@ jobs:
CR_RELEASE_NAME_TEMPLATE: "superset-helm-chart-{{ .Version }}"
- name: Open Pull Request
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
script: |
const branchName = '${{ env.branch_name }}';

View File

@@ -99,7 +99,7 @@ jobs:
run: testdata
- name: Setup Node.js
if: steps.check.outputs.python || steps.check.outputs.frontend
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install npm dependencies

View File

@@ -31,7 +31,7 @@ jobs:
- name: Setup Node.js
if: steps.check.outputs.frontend
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'
- name: Install dependencies

View File

@@ -26,7 +26,7 @@ jobs:
steps:
- name: Quickly add thumbs up!
if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot')
uses: actions/github-script@v8
uses: actions/github-script@v7
with:
script: |
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/')

View File

@@ -60,7 +60,7 @@ jobs:
build: "true"
- name: Use Node.js 20
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version: 20
@@ -112,7 +112,7 @@ jobs:
fetch-depth: 0
- name: Use Node.js 20
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version: 20

View File

@@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v4
with:
node-version-file: './superset-frontend/.nvmrc'

View File

@@ -82,7 +82,6 @@ intro_header.txt
# for LLMs
llm-context.md
AGENTS.md
LLMS.md
CLAUDE.md
CURSOR.md

View File

@@ -1 +1 @@
AGENTS.md
LLMS.md

View File

@@ -26,9 +26,6 @@ ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64}
# Include translations in the final build
ARG BUILD_TRANSLATIONS="false"
# Build arg to pre-populate examples DuckDB file
ARG LOAD_EXAMPLES_DUCKDB="false"
######################################################################
# superset-node-ci used as a base for building frontend assets and CI
######################################################################
@@ -146,8 +143,8 @@ RUN if [ "${BUILD_TRANSLATIONS}" = "true" ]; then \
######################################################################
FROM python-base AS python-common
# Re-declare build arg to receive it in this stage
ARG LOAD_EXAMPLES_DUCKDB
# Build arg to pre-populate examples DuckDB file
ARG LOAD_EXAMPLES_DUCKDB="false"
ENV SUPERSET_HOME="/app/superset_home" \
HOME="/app/superset_home" \

View File

@@ -1 +1 @@
AGENTS.md
LLMS.md

2
GPT.md
View File

@@ -1 +1 @@
AGENTS.md
LLMS.md

View File

@@ -68,11 +68,7 @@ superset/
### Apache License Headers
- **New files require ASF license headers** - When creating new code files, include the standard Apache Software Foundation license header
- **LLM instruction files are excluded** - Files like AGENTS.md, CLAUDE.md, etc. are in `.rat-excludes` to avoid header token overhead
### Code Comments
- **Avoid time-specific language** - Don't use words like "now", "currently", "today" in code comments as they become outdated
- **Write timeless comments** - Comments should remain accurate regardless of when they're read
- **LLM instruction files are excluded** - Files like LLMS.md, CLAUDE.md, etc. are in `.rat-excludes` to avoid header token overhead
## Documentation Requirements

View File

@@ -28,7 +28,6 @@ x-superset-image: &superset-image apachesuperset.docker.scarf.sh/apache/superset
x-superset-volumes:
&superset-volumes # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker
- ./superset-core:/app/superset-core
- superset_home:/app/superset_home
services:

View File

@@ -163,7 +163,7 @@ services:
# configuring the dev-server to use the host.docker.internal to connect to the backend
superset: "http://superset-light:8088"
# Webpack dev server configuration
WEBPACK_DEVSERVER_HOST: "${WEBPACK_DEVSERVER_HOST:-127.0.0.1}"
WEBPACK_DEVSERVER_HOST: "${WEBPACK_DEVSERVER_HOST:-0.0.0.0}"
WEBPACK_DEVSERVER_PORT: "${WEBPACK_DEVSERVER_PORT:-9000}"
ports:
- "${NODE_PORT:-9001}:9000" # Parameterized port, accessible on all interfaces

View File

@@ -29,11 +29,9 @@ x-superset-volumes: &superset-volumes
# /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker
- ./superset:/app/superset
- ./superset-core:/app/superset-core
- ./superset-frontend:/app/superset-frontend
- superset_home:/app/superset_home
- ./tests:/app/tests
- superset_data:/app/data
x-common-build: &common-build
context: .
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
@@ -276,5 +274,3 @@ volumes:
external: false
redis:
external: false
superset_data:
external: false

View File

@@ -21,15 +21,8 @@ set -eo pipefail
# Make python interactive
if [ "$DEV_MODE" == "true" ]; then
if [ "$(whoami)" = "root" ] && command -v uv > /dev/null 2>&1; then
# Always ensure superset-core is available
echo "Installing superset-core in editable mode"
uv pip install --no-deps -e /app/superset-core
# Only reinstall the main app for non-worker processes
if [ "$1" != "worker" ] && [ "$1" != "beat" ]; then
echo "Reinstalling the app in editable mode"
uv pip install -e .
fi
echo "Reinstalling the app in editable mode"
uv pip install -e .
fi
fi
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
@@ -41,8 +34,7 @@ if [ "$CYPRESS_CONFIG" == "true" ]; then
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress
PORT=8081
fi
# Skip postgres requirements installation for workers to avoid conflicts
if [[ "$DATABASE_DIALECT" == postgres* ]] && [ "$(whoami)" = "root" ] && [ "$1" != "worker" ] && [ "$1" != "beat" ]; then
if [[ "$DATABASE_DIALECT" == postgres* ]] && [ "$(whoami)" = "root" ]; then
# older images may not have the postgres dev requirements installed
echo "Installing postgres requirements"
if command -v uv > /dev/null 2>&1; then

View File

@@ -36,11 +36,11 @@ Screenshots will be taken but no messages actually sent as long as `ALERT_REPORT
#### In your `Dockerfile`
You'll need to extend the Superset image to include a headless browser. Your options include:
- Use Playwright with Chrome: this is the recommended approach as of version 4.1.x or greater. A working example of a Dockerfile that installs these tools is provided under "Building your own production Docker image" on the [Docker Builds](/docs/installation/docker-builds#building-your-own-production-docker-image) page. Read the code comments there as you'll also need to change a feature flag in your config.
- Use Playwright with Chrome: this is the recommended approach as of version >=4.1.x. A working example of a Dockerfile that installs these tools is provided under Building your own production Docker image on the [Docker Builds](/docs/installation/docker-builds#building-your-own-production-docker-image) page. Read the code comments there as you'll also need to change a feature flag in your config.
- Use Firefox: you'll need to install geckodriver and Firefox.
- Use Chrome without Playwright: you'll need to install Chrome and set the value of `WEBDRIVER_TYPE` to `"chrome"` in your `superset_config.py`.
In Superset versions prior to 4.1, users installed Firefox or Chrome and that was documented here.
In Superset versions <=4.0x, users installed Firefox or Chrome and that was documented here.
Only the worker container needs the browser.

View File

@@ -67,7 +67,7 @@ are compatible with Superset.
| [IBM Netezza Performance Server](/docs/configuration/databases#ibm-netezza-performance-server) | `pip install nzalchemy` | `netezza+nzpy://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [MySQL](/docs/configuration/databases#mysql) | `pip install mysqlclient` | `mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [OceanBase](/docs/configuration/databases#oceanbase) | `pip install oceanbase_py` | `oceanbase://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Oracle](/docs/configuration/databases#oracle) | `pip install oracledb` | `oracle://<username>:<password>@<hostname>:<port>` |
| [Oracle](/docs/configuration/databases#oracle) | `pip install cx_Oracle` | `oracle://<username>:<password>@<hostname>:<port>` |
| [Parseable](/docs/configuration/databases#parseable) | `pip install sqlalchemy-parseable` | `parseable://<UserName>:<DBPassword>@<Database Host>/<Stream Name>` |
| [PostgreSQL](/docs/configuration/databases#postgres) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Presto](/docs/configuration/databases#presto) | `pip install pyhive` | `presto://{username}:{password}@{hostname}:{port}/{database}` |
@@ -1769,48 +1769,6 @@ You can use the `Extra` field in the **Edit Databases** form to configure SSL:
}
}
```
##### Custom Error Messages
You can use the `CUSTOM_DATABASE_ERRORS` in the `superset/custom_database_errors.py` file or overwrite it in your config file to configure custom error messages for database exceptions.
This feature lets you transform raw database errors into user-friendly messages, optionally including documentation links and hiding default error codes.
Provide an empty string as the first value to keep the original error message. This way, you can add just a link to the documentation
**Example usage:**
```Python
CUSTOM_DATABASE_ERRORS = {
"database_name": {
re.compile('permission denied for view'): (
__(
'Permission denied'
),
SupersetErrorType.GENERIC_DB_ENGINE_ERROR,
{
"custom_doc_links": [
{
"url": "https://example.com/docs/1",
"label": "Check documentation"
},
],
"show_issue_info": False,
}
)
},
"examples": {
re.compile(r'message="(?P<message>[^"]*)"'): (
__(
'Unexpected error: "%(message)s"'
),
SupersetErrorType.GENERIC_DB_ENGINE_ERROR,
{}
)
}
}
```
**Options:**
- ``custom_doc_links``: List of documentation links to display with the error.
- ``show_issue_info``: Set to ``False`` to hide default error codes.
## Misc

View File

@@ -7,7 +7,7 @@ version: 1
# Theming Superset
:::note
`apache-superset>=6.0`
apache-superset>=6.0
:::
Superset now rides on **Ant Design v5's token-based theming**.

View File

@@ -130,7 +130,7 @@ Committers may also update title to reflect the issue/PR content if the author-p
If the PR passes CI tests and does not have any `need:` labels, it is ready for review, add label `review` and/or `design-review`.
If an issue/PR has been inactive for at least 30 days, it will be closed. If it does not have any status label, add `inactive`.
If an issue/PR has been inactive for >=30 days, it will be closed. If it does not have any status label, add `inactive`.
When creating a PR, if you're aiming to have it included in a specific release, please tag it with the version label. For example, to have a PR considered for inclusion in Superset 1.1 use the label `v1.1`.

View File

@@ -27,7 +27,7 @@
"version:remove:components": "node scripts/manage-versions.mjs remove components"
},
"dependencies": {
"@ant-design/icons": "^6.1.0",
"@ant-design/icons": "^6.0.0",
"@docusaurus/core": "3.8.1",
"@docusaurus/plugin-client-redirects": "3.8.1",
"@docusaurus/preset-classic": "3.8.1",
@@ -49,7 +49,7 @@
"@storybook/preview-api": "^8.6.11",
"@storybook/theming": "^8.6.11",
"@superset-ui/core": "^0.20.4",
"antd": "^5.27.4",
"antd": "^5.26.7",
"caniuse-lite": "^1.0.30001739",
"docusaurus-plugin-less": "^2.0.2",
"json-bigint": "^1.0.0",
@@ -63,7 +63,7 @@
"remark-import-partial": "^0.0.2",
"reselect": "^5.1.1",
"storybook": "^8.6.11",
"swagger-ui-react": "^5.29.1",
"swagger-ui-react": "^5.27.1",
"tinycolor2": "^1.4.2",
"ts-loader": "^9.5.4"
},
@@ -74,15 +74,15 @@
"@types/react": "^19.1.8",
"@typescript-eslint/eslint-plugin": "^8.37.0",
"@typescript-eslint/parser": "^8.42.0",
"eslint": "^9.36.0",
"eslint": "^9.34.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-react": "^7.37.5",
"globals": "^16.3.0",
"prettier": "^3.6.2",
"typescript": "~5.9.2",
"typescript-eslint": "^8.45.0",
"webpack": "^5.102.0"
"typescript-eslint": "^8.39.0",
"webpack": "^5.101.0"
},
"browserslist": {
"production": [

View File

@@ -23,8 +23,8 @@ import type { Plugin } from '@docusaurus/types';
export default function webpackExtendPlugin(): Plugin<void> {
return {
name: 'custom-webpack-plugin',
configureWebpack(config) {
const isDev = process.env.NODE_ENV === 'development';
configureWebpack(config, isServer, utils) {
const { isDev } = utils;
return {
devtool: isDev ? 'eval-source-map' : config.devtool,
...(isDev && {

View File

@@ -2,27 +2,12 @@
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"skipLibCheck": true,
"noImplicitAny": false,
"strict": false,
"types": ["@docusaurus/module-type-aliases"]
"baseUrl": "."
},
"jsx": "react-jsx",
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"@superset-ui/core": ["../superset-frontend/packages/superset-ui-core/src"],
"@superset-ui/core/*": ["../superset-frontend/packages/superset-ui-core/src/*"],
"*": ["src/*", "node_modules/*"]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"node_modules",
"../superset-frontend/**/*",
"src/webpack.extend.ts"
]
}
}

View File

@@ -232,15 +232,15 @@
classnames "^2.2.6"
rc-util "^5.31.1"
"@ant-design/icons@^6.1.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.1.0.tgz#97cc14a3c0528b8e2b37f41f232b019f2ca38c2c"
integrity sha512-KrWMu1fIg3w/1F2zfn+JlfNDU8dDqILfA5Tg85iqs1lf8ooyGlbkA+TkwfOKKgqpUmAiRY1PTFpuOU2DAIgSUg==
"@ant-design/icons@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.0.0.tgz#302c935b8b0b429e4444cbc45809247276186d94"
integrity sha512-o0aCCAlHc1o4CQcapAwWzHeaW2x9F49g7P3IDtvtNXgHowtRWYb7kiubt8sQPFvfVIVU/jLw2hzeSlNt0FU+Uw==
dependencies:
"@ant-design/colors" "^8.0.0"
"@ant-design/icons-svg" "^4.4.0"
"@rc-component/util" "^1.3.0"
clsx "^2.1.1"
"@rc-component/util" "^1.2.1"
classnames "^2.2.6"
"@ant-design/react-slick@~1.1.2":
version "1.1.2"
@@ -2385,10 +2385,10 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz#585624dc829cfb6e7c0aa6c3ca7d7e6daa87e34f"
integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==
"@eslint-community/eslint-utils@^4.7.0", "@eslint-community/eslint-utils@^4.8.0":
version "4.9.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3"
integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a"
integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==
dependencies:
eslint-visitor-keys "^3.4.3"
@@ -2433,10 +2433,10 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.36.0", "@eslint/js@^9.32.0":
version "9.36.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.36.0.tgz#b1a3893dd6ce2defed5fd49de805ba40368e8fef"
integrity sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==
"@eslint/js@9.34.0", "@eslint/js@^9.32.0":
version "9.34.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.34.0.tgz#fc423168b9d10e08dea9088d083788ec6442996b"
integrity sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==
"@eslint/object-schema@^2.1.6":
version "2.1.6"
@@ -2746,10 +2746,10 @@
rc-resize-observer "^1.3.1"
rc-util "^5.44.0"
"@rc-component/util@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.3.0.tgz#fc8e1ce1e5292592ef7f45839a3c07366288275c"
integrity sha512-hfXE04CVsxI/slmWKeSh6du7sSKpbvVdVEZCa8A+2QWDlL97EsCYme2c3ZWLn1uC9FR21JoewlrhUPWO4QgO8w==
"@rc-component/util@^1.2.1":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.2.2.tgz#f8363b0e1cc78af3ec56e2235cc3438eb8832040"
integrity sha512-p3zQr9Wu8BKncqmuW23olzBoAFsN8PYMS9FaI4JwJLwknH7DvfHAr1fwbfl9aAWw4Jva64ucpenbgG4fznLUSw==
dependencies:
is-mobile "^5.0.0"
react-is "^18.2.0"
@@ -3050,34 +3050,7 @@
ramda-adjunct "^5.0.0"
unraw "^3.0.0"
"@swagger-api/apidom-ast@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.50.tgz#9e0f4132ea54dd4fca0f31f919a0c5aad12d93c1"
integrity sha512-uUBUm6J6KlyKppyfS7DIW37De6oyMVIpHYmaNV3YAaDMuRMov5KHHWXKbqWlI+l493OljOcXEqDIPeLzm6B5PQ==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
unraw "^3.0.0"
"@swagger-api/apidom-core@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-core@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.50.tgz#d9ed6821d1b38b66ed8cd0b8d8bf5de997354178"
integrity sha512-9N7ySdyzx/3kUnprAi63GQNt+Kq8VUvErwDgPcMRAsZX8jUhk9KLJ9N0fup4mWm6+xGs0JH35wxBxnanS6aiqw==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-ast" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
minim "~0.23.8"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
short-unique-id "^5.3.2"
ts-mixer "^6.0.3"
"@swagger-api/apidom-core@^1.0.0-beta.46":
"@swagger-api/apidom-core@>=1.0.0-beta.41 <1.0.0-rc.0", "@swagger-api/apidom-core@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.46.tgz#6c879f6cf9e67fa0cc36955d3a7f0dd185e36b4f"
integrity sha512-CC8SdAkjSA/l31xfg5l4860cixbYABIXamJeNcXJr+O1z9YNKHIIENeI0zIwORk/TYUaSOg1KUjDnV2Pdctufg==
@@ -3092,31 +3065,14 @@
short-unique-id "^5.3.2"
ts-mixer "^6.0.3"
"@swagger-api/apidom-error@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-error@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.50.tgz#4354c4ade0482824ec7b17667390057f87838ddd"
integrity sha512-vdpi2nRVcxXLGc68JPNwTcKrCKl8PnOEPuykZSxeNbDKnZY80APbsoLDX+1gdRgafK/7k5XdsBkpDQscsTkDng==
dependencies:
"@babel/runtime-corejs3" "^7.20.7"
"@swagger-api/apidom-error@^1.0.0-beta.46":
"@swagger-api/apidom-error@>=1.0.0-beta.41 <1.0.0-rc.0", "@swagger-api/apidom-error@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.46.tgz#fe9039c23ac655930e1f06d99b8ea28bc40d905d"
integrity sha512-AN2ZOHp7gtVsCa6hWxH3nk/1PS7bRtqDVCih3C5qA8k5JfHjP2wfks7b14Ns971SUvDD/SubaCmXmu0CRBHLag==
dependencies:
"@babel/runtime-corejs3" "^7.20.7"
"@swagger-api/apidom-json-pointer@>=1.0.0-beta.50 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.50.tgz#8d2c4129c0d59cf059df3f0e40703114a5c3b49a"
integrity sha512-2TgFKHlZ/SlnTZzY7EwE8xx5Pr2BYePX52xZJFqWnueSAIcCcsrqZeazWIAaDe/gXd47CDqU95nDChMECERspA==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swaggerexpert/json-pointer" "^2.10.1"
"@swagger-api/apidom-json-pointer@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.46":
"@swagger-api/apidom-json-pointer@>=1.0.0-beta.41 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-json-pointer@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.46.tgz#40edcaf5fddc5c748ed4084c9042a2669cbf507c"
integrity sha512-JsbCkYDG7rbf1QmEhtXgbuCGJ4oW+uWDOEnW+Gar49sjk/OKX/2GSGUpywRstnZcopjNarLcEx/H1mHRLoL45A==
@@ -3180,20 +3136,6 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-2019-09@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.50.tgz#83c0eae65b2c4563c5233acdfbccb66c07065e93"
integrity sha512-QP6DuthV8ZWQnthYbPEVikK5rTN4T5lhnAnmO1v6zOCS9B1heKCFcIYgBhcqCnuZ0Tt8kGOfLyqGMb57lPkCdw==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-draft-7" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-2020-12@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.46.tgz#779dbfb80ad10c3d6b2fd182a35231803e9ee387"
@@ -3208,20 +3150,6 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-2020-12@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.50.tgz#0310fc351efd42695227c012b1407728e1400e92"
integrity sha512-ZaqrtZEXUx35x66ND8sc5vf1sIuWPERA15EdRHeca56E09RnjZMUHkiDvdx78165h31QmM67YLi04zEBYhQS0g==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-2019-09" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-4@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.46.tgz#f17bb2010dd933fb6875c82d83826eda62f87bb6"
@@ -3235,19 +3163,6 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-4@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.50.tgz#43b0e37d135b805ab3ea7efce0c5fc5678e95abc"
integrity sha512-aqCwW+iuN7RokH10vDp/eEwlrT4LAlHGy1pLzAS9aFVJyUutfm0I4fxLfddOKD2yd04z858zhLwOVSo4BjrLHg==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-ast" "^1.0.0-beta.50"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-6@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.46.tgz#6629cb35e9e10e670e34a4fd50b6d159f5666766"
@@ -3262,20 +3177,6 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-6@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.50.tgz#a311488627a12953a4a331d3b4231c20311aed9c"
integrity sha512-trF1TZZ79WJOjQw3C1Y7wcqNMxxgHMZtJW2/tP5MwII1hqsExGzmGyUuNlVuSC9k9v/9sCj85hQlJ4TW6HFciQ==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-7@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.46.tgz#04fa39cfe0f869e0c7be0f70ceb34ffb6cc830ad"
@@ -3290,20 +3191,6 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-json-schema-draft-7@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.50.tgz#eb99fdecf9746905331f281578e924082659aef0"
integrity sha512-g9VscnMwjPUYCfR6UxUwsLiIKnyXy2W28J+zN0rbijoSEtUdakcrxwdPhqwgJZHPci8NHNE8574zaocqKBiqSg==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-draft-6" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.4"
"@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-2@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.46.tgz#448f5b7bacd29a3dc37124a7a62f154c94cb818d"
@@ -3332,37 +3219,7 @@
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.3"
"@swagger-api/apidom-ns-openapi-3-0@^1.0.0-beta.50":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.50.tgz#1d9631c0c7504a8985671f2f8e5ca435235b1a54"
integrity sha512-I4GHyNILNxDsYKYeG1+ZA3rnfU1RAYtNp3dA+G8LCX5AB/2N7dT2VPK8HS4cj9m3ZVz7dl1o+X6tpaJIN5kDsA==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-draft-4" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.3"
"@swagger-api/apidom-ns-openapi-3-1@>=1.0.0-beta.50 <1.0.0-rc.0":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.50.tgz#8b9a0c97849cc107228e66dd746bed858b78c50d"
integrity sha512-kxwuaFl1kQddk/RBS5Mz3rE/6v5mXggqhzVwDBObGjgkRmDRVF5nUalziBRNg6A3NcpYbsjNMU/OCA1JihFkrg==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-ast" "^1.0.0-beta.50"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-json-pointer" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-json-schema-2020-12" "^1.0.0-beta.50"
"@swagger-api/apidom-ns-openapi-3-0" "^1.0.0-beta.50"
"@types/ramda" "~0.30.0"
ramda "~0.30.0"
ramda-adjunct "^5.0.0"
ts-mixer "^6.0.3"
"@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.46":
"@swagger-api/apidom-ns-openapi-3-1@>=1.0.0-beta.41 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.40 <1.0.0-rc.0", "@swagger-api/apidom-ns-openapi-3-1@^1.0.0-beta.46":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.46.tgz#87056343a5e2ff48992a27af99611fcbdfbc0f22"
integrity sha512-dSs9h4YEty7h8HJDtWSeC0cg0O2XUTwTVbnOylHX4Z7tXYub8TJ2LEbngRic/R4T58xt76Ro5rZqGUcrt5qXDQ==
@@ -3566,16 +3423,16 @@
tree-sitter "=0.22.4"
web-tree-sitter "=0.24.5"
"@swagger-api/apidom-reference@>=1.0.0-beta.50 <1.0.0-rc.0":
version "1.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.50.tgz#d03f5506327e92dff81a4fac6460edcd2bf3989e"
integrity sha512-aD7gTWPgkJb9oYaC4jZPvxb7YbQKG9pWDYZigAkVGqOAbeYxUXeI00XyCLj/cH8l7KwyhTZNX70F7VnfxOkq7w==
"@swagger-api/apidom-reference@>=1.0.0-beta.41 <1.0.0-rc.0":
version "1.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.46.tgz#c9cb8edfc1099f05e19075c880c4e7c4a87d5015"
integrity sha512-OpJ72k17hyrUJYvj5HgNg93uUsk/28cBWkDAna/cZtCiTdz9zji31JiDUr5GoUd81rpVGuxo4AuUvxXVsH35tA==
dependencies:
"@babel/runtime-corejs3" "^7.26.10"
"@swagger-api/apidom-core" "^1.0.0-beta.50"
"@swagger-api/apidom-error" "^1.0.0-beta.50"
"@swagger-api/apidom-core" "^1.0.0-beta.46"
"@swagger-api/apidom-error" "^1.0.0-beta.46"
"@types/ramda" "~0.30.0"
axios "^1.12.2"
axios "^1.9.0"
minimatch "^7.4.3"
process "^0.11.10"
ramda "~0.30.0"
@@ -4230,79 +4087,117 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@8.45.0", "@typescript-eslint/eslint-plugin@^8.37.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz#9f251d4e85ec5089e7cccb09257ce93dbf0d7744"
integrity sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==
"@typescript-eslint/eslint-plugin@8.40.0", "@typescript-eslint/eslint-plugin@^8.37.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.40.0.tgz#19f959f273b32f5082c891903645e6a85328db4e"
integrity sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.45.0"
"@typescript-eslint/type-utils" "8.45.0"
"@typescript-eslint/utils" "8.45.0"
"@typescript-eslint/visitor-keys" "8.45.0"
"@typescript-eslint/scope-manager" "8.40.0"
"@typescript-eslint/type-utils" "8.40.0"
"@typescript-eslint/utils" "8.40.0"
"@typescript-eslint/visitor-keys" "8.40.0"
graphemer "^1.4.0"
ignore "^7.0.0"
natural-compare "^1.4.0"
ts-api-utils "^2.1.0"
"@typescript-eslint/parser@8.45.0", "@typescript-eslint/parser@^8.42.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.45.0.tgz#571660c98824aefb4a6ec3b3766655d1348520a4"
integrity sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==
"@typescript-eslint/parser@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.40.0.tgz#1bc9f3701ced29540eb76ff2d95ce0d52ddc7e69"
integrity sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==
dependencies:
"@typescript-eslint/scope-manager" "8.45.0"
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/typescript-estree" "8.45.0"
"@typescript-eslint/visitor-keys" "8.45.0"
"@typescript-eslint/scope-manager" "8.40.0"
"@typescript-eslint/types" "8.40.0"
"@typescript-eslint/typescript-estree" "8.40.0"
"@typescript-eslint/visitor-keys" "8.40.0"
debug "^4.3.4"
"@typescript-eslint/project-service@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.45.0.tgz#f83dda1bca31dae2fd6821f9131daf1edebfd46c"
integrity sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==
"@typescript-eslint/parser@^8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.42.0.tgz#20ea66f4867981fb5bb62cbe1454250fc4a440ab"
integrity sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==
dependencies:
"@typescript-eslint/tsconfig-utils" "^8.45.0"
"@typescript-eslint/types" "^8.45.0"
"@typescript-eslint/scope-manager" "8.42.0"
"@typescript-eslint/types" "8.42.0"
"@typescript-eslint/typescript-estree" "8.42.0"
"@typescript-eslint/visitor-keys" "8.42.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz#59615ba506a9e3479d1efb0d09d6ab52f2a19142"
integrity sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==
"@typescript-eslint/project-service@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.40.0.tgz#1b7ba6079ff580c3215882fe75a43e5d3ed166b9"
integrity sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==
dependencies:
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/visitor-keys" "8.45.0"
"@typescript-eslint/tsconfig-utils" "^8.40.0"
"@typescript-eslint/types" "^8.40.0"
debug "^4.3.4"
"@typescript-eslint/tsconfig-utils@8.45.0", "@typescript-eslint/tsconfig-utils@^8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz#63d38282790a2566c571bad423e7c1cad1f3d64c"
integrity sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==
"@typescript-eslint/type-utils@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz#04004bdf2598844faa29fb936fb6b0ee10d6d3f3"
integrity sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==
"@typescript-eslint/project-service@8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.42.0.tgz#636eb3418b6c42c98554dce884943708bf41a583"
integrity sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==
dependencies:
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/typescript-estree" "8.45.0"
"@typescript-eslint/utils" "8.45.0"
"@typescript-eslint/tsconfig-utils" "^8.42.0"
"@typescript-eslint/types" "^8.42.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.40.0.tgz#2fbfcc8643340d8cd692267e61548b946190be8a"
integrity sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==
dependencies:
"@typescript-eslint/types" "8.40.0"
"@typescript-eslint/visitor-keys" "8.40.0"
"@typescript-eslint/scope-manager@8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz#36016757bc85b46ea42bae47b61f9421eddedde3"
integrity sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==
dependencies:
"@typescript-eslint/types" "8.42.0"
"@typescript-eslint/visitor-keys" "8.42.0"
"@typescript-eslint/tsconfig-utils@8.40.0", "@typescript-eslint/tsconfig-utils@^8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.40.0.tgz#8e8fdb9b988854aedd04abdde3239c4bdd2d26e4"
integrity sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==
"@typescript-eslint/tsconfig-utils@8.42.0", "@typescript-eslint/tsconfig-utils@^8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz#21a3e74396fd7443ff930bc41b27789ba7e9236e"
integrity sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==
"@typescript-eslint/type-utils@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.40.0.tgz#a7e4a1f0815dd0ba3e4eef945cc87193ca32c422"
integrity sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==
dependencies:
"@typescript-eslint/types" "8.40.0"
"@typescript-eslint/typescript-estree" "8.40.0"
"@typescript-eslint/utils" "8.40.0"
debug "^4.3.4"
ts-api-utils "^2.1.0"
"@typescript-eslint/types@8.45.0", "@typescript-eslint/types@^8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.45.0.tgz#fc01cd2a4690b9713b02f895e82fb43f7d960684"
integrity sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==
"@typescript-eslint/types@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.40.0.tgz#0b580fdf643737aa5c01285314b5c6e9543846a9"
integrity sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==
"@typescript-eslint/typescript-estree@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz#3498500f109a89b104d2770497c707e56dfe062d"
integrity sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==
"@typescript-eslint/types@8.42.0", "@typescript-eslint/types@^8.40.0", "@typescript-eslint/types@^8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.42.0.tgz#ae15c09cebda20473772902033328e87372db008"
integrity sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==
"@typescript-eslint/typescript-estree@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.40.0.tgz#295149440ce7da81c790a4e14e327599a3a1e5c9"
integrity sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==
dependencies:
"@typescript-eslint/project-service" "8.45.0"
"@typescript-eslint/tsconfig-utils" "8.45.0"
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/visitor-keys" "8.45.0"
"@typescript-eslint/project-service" "8.40.0"
"@typescript-eslint/tsconfig-utils" "8.40.0"
"@typescript-eslint/types" "8.40.0"
"@typescript-eslint/visitor-keys" "8.40.0"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
@@ -4310,22 +4205,46 @@
semver "^7.6.0"
ts-api-utils "^2.1.0"
"@typescript-eslint/utils@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.45.0.tgz#6e68e92d99019fdf56018d0e6664c76a70470c95"
integrity sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==
"@typescript-eslint/typescript-estree@8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz#593c3af87d4462252c0d7239d1720b84a1b56864"
integrity sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==
dependencies:
"@typescript-eslint/project-service" "8.42.0"
"@typescript-eslint/tsconfig-utils" "8.42.0"
"@typescript-eslint/types" "8.42.0"
"@typescript-eslint/visitor-keys" "8.42.0"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
minimatch "^9.0.4"
semver "^7.6.0"
ts-api-utils "^2.1.0"
"@typescript-eslint/utils@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.40.0.tgz#8d0c6430ed2f5dc350784bb0d8be514da1e54054"
integrity sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==
dependencies:
"@eslint-community/eslint-utils" "^4.7.0"
"@typescript-eslint/scope-manager" "8.45.0"
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/typescript-estree" "8.45.0"
"@typescript-eslint/scope-manager" "8.40.0"
"@typescript-eslint/types" "8.40.0"
"@typescript-eslint/typescript-estree" "8.40.0"
"@typescript-eslint/visitor-keys@8.45.0":
version "8.45.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz#4e3bcc55da64ac61069ebfe62ca240567ac7d784"
integrity sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==
"@typescript-eslint/visitor-keys@8.40.0":
version "8.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.40.0.tgz#c1b45196981311fed7256863be4bfb2d3eda332a"
integrity sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==
dependencies:
"@typescript-eslint/types" "8.45.0"
"@typescript-eslint/types" "8.40.0"
eslint-visitor-keys "^4.2.1"
"@typescript-eslint/visitor-keys@8.42.0":
version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz#87c6caaa1ac307bc73a87c1fc469f88f0162f27e"
integrity sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==
dependencies:
"@typescript-eslint/types" "8.42.0"
eslint-visitor-keys "^4.2.1"
"@ungap/structured-clone@^1.0.0":
@@ -4625,10 +4544,10 @@ ansi-styles@^6.1.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
antd@^5.27.4:
version "5.27.4"
resolved "https://registry.yarnpkg.com/antd/-/antd-5.27.4.tgz#13c97deb12e6aeb43adecd23f3dbe3139a62e579"
integrity sha512-rhArohoAUCxhkPjGI/BXthOrrjaElL4Fb7d4vEHnIR3DpxFXfegd4rN21IgGdiF+Iz4EFuUZu8MdS8NuJHLSVQ==
antd@^5.26.7:
version "5.27.1"
resolved "https://registry.yarnpkg.com/antd/-/antd-5.27.1.tgz#5378fc017cb4057ffefe2a670f20e54b924d897d"
integrity sha512-jGMSdBN7hAMvPV27B4RhzZfL6n6yu8yDbo7oXrlJasaOqB7bSDPcjdEy1kXy3JPsny/Qazb1ykzRI4EfcByAPQ==
dependencies:
"@ant-design/colors" "^7.2.1"
"@ant-design/cssinjs" "^1.23.0"
@@ -4666,10 +4585,10 @@ antd@^5.27.4:
rc-resize-observer "^1.4.3"
rc-segmented "~2.7.0"
rc-select "~14.16.8"
rc-slider "~11.1.9"
rc-slider "~11.1.8"
rc-steps "~6.0.1"
rc-switch "~4.1.0"
rc-table "~7.53.0"
rc-table "~7.51.1"
rc-tabs "~15.7.0"
rc-textarea "~1.10.2"
rc-tooltip "~6.4.0"
@@ -4846,10 +4765,10 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
axios@^1.12.2:
version "1.12.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7"
integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==
axios@^1.9.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.0.tgz#11248459be05a5ee493485628fa0e4323d0abfc3"
integrity sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.4"
@@ -4943,16 +4862,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.3.1, base64-js@^1.5.1:
base64-js@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
baseline-browser-mapping@^2.8.9:
version "2.8.10"
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.10.tgz#32eb5e253d633fa3fa3ffb1685fabf41680d9e8a"
integrity sha512-uLfgBi+7IBNay8ECBO2mVMGZAc1VgZWEChxm4lv+TobGdG82LnXMjuNGo/BSSZZL4UmkWhxEHP2f5ziLNwGWMA==
batch@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
@@ -5066,15 +4980,14 @@ browser-assert@^1.2.1:
resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200"
integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.24.5, browserslist@^4.25.0, browserslist@^4.25.3:
version "4.26.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.26.3.tgz#40fbfe2d1cd420281ce5b1caa8840049c79afb56"
integrity sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.0, browserslist@^4.25.3:
version "4.25.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.3.tgz#9167c9cbb40473f15f75f85189290678b99b16c5"
integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==
dependencies:
baseline-browser-mapping "^2.8.9"
caniuse-lite "^1.0.30001746"
electron-to-chromium "^1.5.227"
node-releases "^2.0.21"
caniuse-lite "^1.0.30001735"
electron-to-chromium "^1.5.204"
node-releases "^2.0.19"
update-browserslist-db "^1.1.3"
buffer-from@^1.0.0:
@@ -5082,14 +4995,6 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -5177,16 +5082,11 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001739:
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001735, caniuse-lite@^1.0.30001739:
version "1.0.30001739"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz#b34ce2d56bfc22f4352b2af0144102d623a124f4"
integrity sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==
caniuse-lite@^1.0.30001746:
version "1.0.30001746"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001746.tgz#199d20f04f5369825e00ff7067d45d5dfa03aee7"
integrity sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==
ccount@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5"
@@ -5354,7 +5254,7 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
clsx@^2.0.0, clsx@^2.1.1:
clsx@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
@@ -6440,7 +6340,14 @@ domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"
dompurify@=3.2.6, dompurify@^3.2.5:
dompurify@=3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.4.tgz#af5a5a11407524431456cf18836c55d13441cd8e"
integrity sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==
optionalDependencies:
"@types/trusted-types" "^2.0.7"
dompurify@^3.2.5:
version "3.2.6"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.6.tgz#ca040a6ad2b88e2a92dc45f38c79f84a714a1cad"
integrity sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==
@@ -6509,10 +6416,10 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
electron-to-chromium@^1.5.227:
version "1.5.228"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz#38b849bc8714bd21fb64f5ad56bf8cfd8638e1e9"
integrity sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==
electron-to-chromium@^1.5.204:
version "1.5.207"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.207.tgz#0fedde3eec615065ee95531c09a10578644c5552"
integrity sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==
emoji-regex@^8.0.0:
version "8.0.0"
@@ -6868,18 +6775,18 @@ eslint-visitor-keys@^4.2.1:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
eslint@^9.36.0:
version "9.36.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.36.0.tgz#9cc5cbbfb9c01070425d9bfed81b4e79a1c09088"
integrity sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==
eslint@^9.34.0:
version "9.34.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.34.0.tgz#0ea1f2c1b5d1671db8f01aa6b8ce722302016f7b"
integrity sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==
dependencies:
"@eslint-community/eslint-utils" "^4.8.0"
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.21.0"
"@eslint/config-helpers" "^0.3.1"
"@eslint/core" "^0.15.2"
"@eslint/eslintrc" "^3.3.1"
"@eslint/js" "9.36.0"
"@eslint/js" "9.34.0"
"@eslint/plugin-kit" "^0.3.5"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
@@ -10076,10 +9983,10 @@ node-gyp-build@^4.8.0, node-gyp-build@^4.8.2, node-gyp-build@^4.8.4:
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8"
integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==
node-releases@^2.0.21:
version "2.0.21"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c"
integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==
node-releases@^2.0.19:
version "2.0.19"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
@@ -11548,10 +11455,10 @@ rc-select@~14.16.2, rc-select@~14.16.8:
rc-util "^5.16.1"
rc-virtual-list "^3.5.2"
rc-slider@~11.1.9:
version "11.1.9"
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-11.1.9.tgz#d872130fbf4ec51f28543d62e90451091d6f5208"
integrity sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==
rc-slider@~11.1.8:
version "11.1.8"
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-11.1.8.tgz#cf3b30dacac8f98d44f7685f733f6f7da146fc06"
integrity sha512-2gg/72YFSpKP+Ja5AjC5DPL1YnV8DEITDQrcc1eASrUYjl0esptaBVJBh5nLTXCCp15eD8EuGjwezVGSHhs9tQ==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.5"
@@ -11575,10 +11482,10 @@ rc-switch@~4.1.0:
classnames "^2.2.1"
rc-util "^5.30.0"
rc-table@~7.53.0:
version "7.53.1"
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.53.1.tgz#b891aa39e9d1d944711f018692d2c52013afc90f"
integrity sha512-firAd7Z+liqIDS5TubJ1qqcoBd6YcANLKWQDZhFf3rfoOTt/UNPj4n3O+2vhl+z4QMqwPEUVAil661WHA8H8Aw==
rc-table@~7.51.1:
version "7.51.1"
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.51.1.tgz#cd69ae3262d3b61e4c93c979c12786906e944691"
integrity sha512-5iq15mTHhvC42TlBLRCoCBLoCmGlbRZAlyF21FonFnS/DIC8DeRqnmdyVREwt2CFbPceM0zSNdEeVfiGaqYsKw==
dependencies:
"@babel/runtime" "^7.10.1"
"@rc-component/context" "^1.4.0"
@@ -12608,7 +12515,7 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
sha.js@^2.4.12:
sha.js@^2.4.11:
version "2.4.12"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f"
integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==
@@ -13083,18 +12990,18 @@ svgo@^3.0.2, svgo@^3.2.0:
csso "^5.0.5"
picocolors "^1.0.0"
swagger-client@^3.35.7:
version "3.35.7"
resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.35.7.tgz#2f649c1875cb88a747254963ea85dad09605f238"
integrity sha512-AAVk7lBFIw41wI0tsqyh/l4dwJ0/eslHL2Ex4hmsGtuKcD6/wXunetO8AsmE5MptK4YgRvpmUDvKnF1TaGzdiQ==
swagger-client@^3.35.5:
version "3.35.6"
resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.35.6.tgz#03892a1ec9995db44d7b49feb7aafafc06d9ed51"
integrity sha512-OgwNneIdC45KXwOfwrlkwgWPeAKiV4K75mOnZioTddo1mpp9dTboCDVJas7185Ww1ziBwzShBqXpNGmyha9ZQg==
dependencies:
"@babel/runtime-corejs3" "^7.22.15"
"@scarf/scarf" "=1.4.0"
"@swagger-api/apidom-core" ">=1.0.0-beta.50 <1.0.0-rc.0"
"@swagger-api/apidom-error" ">=1.0.0-beta.50 <1.0.0-rc.0"
"@swagger-api/apidom-json-pointer" ">=1.0.0-beta.50 <1.0.0-rc.0"
"@swagger-api/apidom-ns-openapi-3-1" ">=1.0.0-beta.50 <1.0.0-rc.0"
"@swagger-api/apidom-reference" ">=1.0.0-beta.50 <1.0.0-rc.0"
"@swagger-api/apidom-core" ">=1.0.0-beta.41 <1.0.0-rc.0"
"@swagger-api/apidom-error" ">=1.0.0-beta.41 <1.0.0-rc.0"
"@swagger-api/apidom-json-pointer" ">=1.0.0-beta.41 <1.0.0-rc.0"
"@swagger-api/apidom-ns-openapi-3-1" ">=1.0.0-beta.41 <1.0.0-rc.0"
"@swagger-api/apidom-reference" ">=1.0.0-beta.41 <1.0.0-rc.0"
"@swaggerexpert/cookie" "^2.0.2"
deepmerge "~4.3.0"
fast-json-patch "^3.0.0-1"
@@ -13107,19 +13014,18 @@ swagger-client@^3.35.7:
ramda "^0.30.1"
ramda-adjunct "^5.1.0"
swagger-ui-react@^5.29.1:
version "5.29.1"
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.29.1.tgz#90875ef551f0fc271e369db60e4a8cd369ce70f9"
integrity sha512-simkO3VoHrWIQWLH2vCpOJSPVbocV+RLGvHzzh+jhqs5heWsA1cnadx31BbKJVajfxIO4dC3lclxgMYbLUk3fQ==
swagger-ui-react@^5.27.1:
version "5.27.1"
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.27.1.tgz#315b59970c33933a5f62ca0f702789741dcedc7c"
integrity sha512-wwDoavIeJI/Pwiavn32FMJ5dfptz0BAOKjSrj7EdU22QdP3gdk9+MZHdzzjxWURmVj0kc0XoQfsFgjln0toJaw==
dependencies:
"@babel/runtime-corejs3" "^7.27.1"
"@scarf/scarf" "=1.4.0"
base64-js "^1.5.1"
buffer "^6.0.3"
classnames "^2.5.1"
css.escape "1.5.1"
deep-extend "0.6.0"
dompurify "=3.2.6"
dompurify "=3.2.4"
ieee754 "^1.2.1"
immutable "^3.x.x"
js-file-download "^0.4.12"
@@ -13140,8 +13046,8 @@ swagger-ui-react@^5.29.1:
remarkable "^2.0.1"
reselect "^5.1.1"
serialize-error "^8.1.0"
sha.js "^2.4.12"
swagger-client "^3.35.7"
sha.js "^2.4.11"
swagger-client "^3.35.5"
url-parse "^1.5.10"
xml "=1.0.1"
xml-but-prettier "^1.0.1"
@@ -13154,10 +13060,10 @@ synckit@^0.11.7:
dependencies:
"@pkgr/core" "^0.2.9"
tapable@^2.0.0, tapable@^2.2.0, tapable@^2.2.1, tapable@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.3.tgz#4b67b635b2d97578a06a2713d2f04800c237e99b"
integrity sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==
tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.2.tgz#ab4984340d30cb9989a490032f086dbb8b56d872"
integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==
terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9:
version "5.3.14"
@@ -13415,15 +13321,15 @@ types-ramda@^0.30.1:
dependencies:
ts-toolbelt "^9.6.0"
typescript-eslint@^8.45.0:
version "8.45.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.45.0.tgz#98ab164234dc04c112747ec0a4ae29a94efe123b"
integrity sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==
typescript-eslint@^8.39.0:
version "8.40.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.40.0.tgz#27541748f3ca889c9698327bdacf815f7dc61804"
integrity sha512-Xvd2l+ZmFDPEt4oj1QEXzA4A2uUK6opvKu3eGN9aGjB8au02lIVcLyi375w94hHyejTOmzIU77L8ol2sRg9n7Q==
dependencies:
"@typescript-eslint/eslint-plugin" "8.45.0"
"@typescript-eslint/parser" "8.45.0"
"@typescript-eslint/typescript-estree" "8.45.0"
"@typescript-eslint/utils" "8.45.0"
"@typescript-eslint/eslint-plugin" "8.40.0"
"@typescript-eslint/parser" "8.40.0"
"@typescript-eslint/typescript-estree" "8.40.0"
"@typescript-eslint/utils" "8.40.0"
typescript@~5.9.2:
version "5.9.2"
@@ -13839,7 +13745,7 @@ vscode-uri@~3.0.8:
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
watchpack@^2.4.4:
watchpack@^2.4.1:
version "2.4.4"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947"
integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==
@@ -13962,10 +13868,10 @@ webpack-virtual-modules@^0.6.2:
resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"
integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==
webpack@^5.102.0, webpack@^5.88.1, webpack@^5.95.0:
version "5.102.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.102.0.tgz#7a2416e6da356c35f1fb35333d2f5cee0133e953"
integrity sha512-hUtqAR3ZLVEYDEABdBioQCIqSoguHbFn1K7WlPPWSuXmx0031BD73PSE35jKyftdSh4YLDoQNgK4pqBt5Q82MA==
webpack@^5.101.0, webpack@^5.88.1, webpack@^5.95.0:
version "5.101.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.3.tgz#3633b2375bb29ea4b06ffb1902734d977bc44346"
integrity sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==
dependencies:
"@types/eslint-scope" "^3.7.7"
"@types/estree" "^1.0.8"
@@ -13975,7 +13881,7 @@ webpack@^5.102.0, webpack@^5.88.1, webpack@^5.95.0:
"@webassemblyjs/wasm-parser" "^1.14.1"
acorn "^8.15.0"
acorn-import-phases "^1.0.3"
browserslist "^4.24.5"
browserslist "^4.24.0"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.17.3"
es-module-lexer "^1.2.1"
@@ -13988,9 +13894,9 @@ webpack@^5.102.0, webpack@^5.88.1, webpack@^5.95.0:
mime-types "^2.1.27"
neo-async "^2.6.2"
schema-utils "^4.3.2"
tapable "^2.2.3"
tapable "^2.1.1"
terser-webpack-plugin "^5.3.11"
watchpack "^2.4.4"
watchpack "^2.4.1"
webpack-sources "^3.3.3"
webpackbar@^6.0.1:

View File

@@ -29,7 +29,7 @@ maintainers:
- name: craig-rueda
email: craig@craigrueda.com
url: https://github.com/craig-rueda
version: 0.15.1 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details.
version: 0.15.0 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details.
dependencies:
- name: postgresql
version: 13.4.4

View File

@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
# superset
![Version: 0.15.1](https://img.shields.io/badge/Version-0.15.1-informational?style=flat-square)
![Version: 0.15.0](https://img.shields.io/badge/Version-0.15.0-informational?style=flat-square)
Apache Superset is a modern, enterprise-ready business intelligence web application
@@ -203,7 +203,6 @@ On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverri
| supersetNode.connections.db_name | string | `"superset"` | |
| supersetNode.connections.db_pass | string | `"superset"` | |
| supersetNode.connections.db_port | string | `"5432"` | |
| supersetNode.connections.db_type | string | `"postgresql"` | Database type for Superset metadata (Supported types: "postgresql", "mysql") |
| supersetNode.connections.db_user | string | `"superset"` | |
| supersetNode.connections.redis_cache_db | string | `"1"` | |
| supersetNode.connections.redis_celery_db | string | `"0"` | |

View File

@@ -96,18 +96,7 @@ CACHE_CONFIG = {
}
DATA_CACHE_CONFIG = CACHE_CONFIG
if os.getenv("SQLALCHEMY_DATABASE_URI"):
SQLALCHEMY_DATABASE_URI = os.getenv("SQLALCHEMY_DATABASE_URI")
else:
{{- if eq .Values.supersetNode.connections.db_type "postgresql" }}
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{os.getenv('DB_USER')}:{os.getenv('DB_PASS')}@{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}"
{{- else if eq .Values.supersetNode.connections.db_type "mysql" }}
SQLALCHEMY_DATABASE_URI = f"mysql+mysqldb://{os.getenv('DB_USER')}:{os.getenv('DB_PASS')}@{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}"
{{- else }}
{{ fail (printf "Unsupported database type: %s. Please use 'postgresql' or 'mysql'." .Values.supersetNode.connections.db_type) }}
{{- end }}
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{env('DB_USER')}:{env('DB_PASS')}@{env('DB_HOST')}:{env('DB_PORT')}/{env('DB_NAME')}"
SQLALCHEMY_TRACK_MODIFICATIONS = True
class CeleryConfig:

View File

@@ -289,8 +289,6 @@ supersetNode:
enabled: false
ssl_cert_reqs: CERT_NONE
# You need to change below configuration incase bringing own PostgresSQL instance and also set postgresql.enabled:false
# -- Database type for Superset metadata (Supported types: "postgresql", "mysql")
db_type: "postgresql"
db_host: "{{ .Release.Name }}-postgresql"
db_port: "5432"
db_user: superset

View File

@@ -100,7 +100,7 @@ dependencies = [
"slack_sdk>=3.19.0, <4",
"sqlalchemy>=1.4, <2",
"sqlalchemy-utils>=0.38.3, <0.39",
"sqlglot>=27.15.2, <28",
"sqlglot>=27.3.0, <28",
# newer pandas needs 0.9+
"tabulate>=0.9.0, <1.0",
"typing-extensions>=4, <5",
@@ -133,8 +133,7 @@ denodo = ["denodo-sqlalchemy~=1.0.6"]
dremio = ["sqlalchemy-dremio>=1.2.1, <4"]
drill = ["sqlalchemy-drill>=1.1.4, <2"]
druid = ["pydruid>=0.6.5,<0.7"]
# DuckDB 1.x has type system incompatibilities with duckdb-engine.
duckdb = ["duckdb>=0.10.2,<0.11", "duckdb-engine>=0.17.0"]
duckdb = ["duckdb-engine>=0.17.0"]
dynamodb = ["pydynamodb>=0.4.2"]
solr = ["sqlalchemy-solr >= 0.2.0"]
elasticsearch = ["elasticsearch-dbapi>=0.2.9, <0.3.0"]

View File

@@ -395,7 +395,7 @@ sqlalchemy-utils==0.38.3
# via
# apache-superset (pyproject.toml)
# flask-appbuilder
sqlglot==27.15.2
sqlglot==27.3.0
# via apache-superset (pyproject.toml)
sshtunnel==0.4.0
# via apache-superset (pyproject.toml)

View File

@@ -181,10 +181,8 @@ dnspython==2.7.0
# email-validator
docker==7.0.0
# via apache-superset
duckdb==0.10.3
# via
# apache-superset
# duckdb-engine
duckdb==1.3.2
# via duckdb-engine
duckdb-engine==0.17.0
# via apache-superset
email-validator==2.2.0
@@ -850,7 +848,7 @@ sqlalchemy-utils==0.38.3
# -c requirements/base-constraint.txt
# apache-superset
# flask-appbuilder
sqlglot==27.15.2
sqlglot==27.3.0
# via
# -c requirements/base-constraint.txt
# apache-superset

View File

@@ -272,10 +272,6 @@ module.exports = {
{
files: ['packages/**'],
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
'no-restricted-imports': [
'error',
{
@@ -327,12 +323,7 @@ module.exports = {
'*.stories.tsx',
'*.stories.jsx',
'fixtures.*',
'**/test/**/*',
'**/tests/**/*',
'spec/**/*',
'**/fixtures/**/*',
'**/__mocks__/**/*',
'**/spec/**/*',
'playwright/**/*',
],
excludedFiles: 'cypress-base/cypress/**/*',
plugins: ['jest', 'jest-dom', 'no-only-tests', 'testing-library'],
@@ -356,9 +347,7 @@ module.exports = {
devDependencies: true,
},
],
'jest/consistent-test-it': 'error',
'no-only-tests/no-only-tests': 'error',
'prefer-promise-reject-errors': 0,
'max-classes-per-file': 0,
// temporary rules to help with migration - please re-enable!
'testing-library/await-async-queries': 0,
@@ -397,12 +386,6 @@ module.exports = {
'*.stories.tsx',
'*.stories.jsx',
'fixtures.*',
'**/test/**/*',
'**/tests/**/*',
'spec/**/*',
'**/fixtures/**/*',
'**/__mocks__/**/*',
'**/spec/**/*',
'cypress-base/cypress/**/*',
'Stories.tsx',
'packages/superset-ui-core/src/theme/index.tsx',
@@ -416,27 +399,10 @@ module.exports = {
},
},
{
// Override specifically for packages stories and overview files
// This must come LAST to override other rules
files: [
'packages/**/*.stories.*',
'packages/**/*.overview.*',
'packages/**/fixtures.*',
],
files: ['playwright/**/*'],
rules: {
'import/no-extraneous-dependencies': 'off',
},
},
{
// Allow @playwright/test imports in Playwright test files
files: ['playwright/**/*.ts', 'playwright/**/*.js'],
rules: {
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: true,
},
],
'import/no-unresolved': 0, // Playwright is not installed in main build
'import/no-extraneous-dependencies': 0, // Playwright is not installed in main build
},
},
],
@@ -445,6 +411,7 @@ module.exports = {
'theme-colors/no-literal-colors': 'error',
'icons/no-fa-icons-usage': 'error',
'i18n-strings/no-template-vars': ['error', true],
'i18n-strings/sentence-case-buttons': 'error',
camelcase: [
'error',
{

View File

@@ -3,4 +3,3 @@ cypress/screenshots
cypress/videos
src/temp
.temp_cache/
.tsbuildinfo

File diff suppressed because it is too large Load Diff

View File

@@ -129,7 +129,7 @@
"@visx/xychart": "^3.5.1",
"ag-grid-community": "34.2.0",
"ag-grid-react": "34.2.0",
"antd": "^5.24.9",
"antd": "^5.24.6",
"chrono-node": "^2.7.8",
"classnames": "^2.2.5",
"content-disposition": "^0.5.4",
@@ -211,7 +211,7 @@
"yargs": "^17.7.2"
},
"devDependencies": {
"@applitools/eyes-storybook": "^3.60.0",
"@applitools/eyes-storybook": "^3.55.6",
"@babel/cli": "^7.27.2",
"@babel/compat-data": "^7.28.0",
"@babel/core": "^7.28.3",
@@ -225,7 +225,7 @@
"@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.26.0",
"@babel/register": "^7.23.7",
"@babel/runtime": "^7.28.4",
"@babel/runtime": "^7.28.2",
"@babel/runtime-corejs3": "^7.28.2",
"@babel/types": "^7.26.9",
"@cypress/react": "^8.0.2",
@@ -260,7 +260,7 @@
"@types/node": "^22.12.0",
"@types/react": "^17.0.83",
"@types/react-dom": "^17.0.26",
"@types/react-json-tree": "^0.13.0",
"@types/react-json-tree": "^0.6.11",
"@types/react-loadable": "^5.5.11",
"@types/react-redux": "^7.1.10",
"@types/react-resizable": "^3.0.8",
@@ -305,7 +305,6 @@
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-prefer-function-component": "^3.3.0",
"eslint-plugin-react-you-might-not-need-an-effect": "^0.5.1",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-testing-library": "^6.4.0",
"eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors",
@@ -318,7 +317,7 @@
"jest-environment-jsdom": "^29.7.0",
"jest-html-reporter": "^4.3.0",
"jest-websocket-mock": "^2.5.0",
"jsdom": "^27.0.0",
"jsdom": "^26.0.0",
"lerna": "^8.2.3",
"mini-css-extract-plugin": "^2.9.0",
"open-cli": "^8.0.0",
@@ -341,7 +340,7 @@
"tsx": "^4.20.3",
"typescript": "5.4.5",
"vm-browserify": "^1.1.2",
"webpack": "^5.102.0",
"webpack": "^5.99.9",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.2",

View File

@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
import { transformSpatialProps } from '../spatialUtils';
export default transformSpatialProps;
{
"settings": {
"import/resolver": {
"typescript": {}
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@apache-superset/core",
"version": "0.0.1-rc5",
"version": "0.0.1-rc4",
"description": "This package contains UI elements, APIs, and utility functions used by Superset.",
"sideEffects": false,
"main": "lib/index.js",
@@ -22,7 +22,7 @@
"typescript": "^5.0.0"
},
"peerDependencies": {
"antd": "^5.24.9",
"antd": "^5.24.6",
"react": "^17.0.2"
},
"scripts": {

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*", "types/**/*"],
"exclude": ["src/**/*.test.*", "src/**/*.stories.*"]

View File

@@ -18,8 +18,7 @@
* under the License.
*/
import { ReactNode } from 'react';
import { css, styled, t } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { css, GenericDataType, styled, t } from '@superset-ui/core';
import {
ClockCircleOutlined,
QuestionOutlined,

View File

@@ -16,11 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
import {
Popover,
type PopoverProps,
SQLEditor,
} from '@superset-ui/core/components';
import { useEffect, useState } from 'react';
import { Popover, type PopoverProps } from '@superset-ui/core/components';
import type ReactAce from 'react-ace';
import { CalculatorOutlined } from '@ant-design/icons';
import { css, styled, useTheme, t } from '@superset-ui/core';
@@ -37,10 +35,24 @@ const StyledCalculatorIcon = styled(CalculatorOutlined)`
export const SQLPopover = (props: PopoverProps & { sqlExpression: string }) => {
const theme = useTheme();
const [AceEditor, setAceEditor] = useState<typeof ReactAce | null>(null);
useEffect(() => {
Promise.all([
import('react-ace'),
import('ace-builds/src-min-noconflict/mode-sql'),
]).then(([reactAceModule]) => {
setAceEditor(() => reactAceModule.default);
});
}, []);
if (!AceEditor) {
return null;
}
return (
<Popover
content={
<SQLEditor
<AceEditor
mode="sql"
value={props.sqlExpression}
editorProps={{ $blockScrolling: true }}
setOptions={{
@@ -53,6 +65,7 @@ export const SQLPopover = (props: PopoverProps & { sqlExpression: string }) => {
wrapEnabled
style={{
border: `1px solid ${theme.colorBorder}`,
background: theme.colorPrimaryBg,
maxWidth: theme.sizeUnit * 100,
}}
/>

View File

@@ -16,8 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import { DTTM_ALIAS, QueryColumn, QueryMode, t } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import {
DTTM_ALIAS,
GenericDataType,
QueryColumn,
QueryMode,
t,
} from '@superset-ui/core';
import { ColumnMeta, SortSeriesData, SortSeriesType } from './types';
export const DEFAULT_MAX_ROW = 100000;

View File

@@ -16,8 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { DatasourceType } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { DatasourceType, GenericDataType } from '@superset-ui/core';
import { Dataset } from './types';
export const TestDataset: Dataset = {

View File

@@ -20,13 +20,13 @@
import {
ContributionType,
ensureIsArray,
GenericDataType,
getColumnLabel,
getMetricLabel,
QueryFormColumn,
QueryFormMetric,
t,
} from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import {
ControlPanelState,
ControlState,

View File

@@ -17,8 +17,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import { QueryColumn, t, validateNonEmpty } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import {
GenericDataType,
QueryColumn,
t,
validateNonEmpty,
} from '@superset-ui/core';
import {
ExtraControlProps,
SharedControlConfig,

View File

@@ -16,8 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ensureIsArray, ValueOf } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { ensureIsArray, GenericDataType, ValueOf } from '@superset-ui/core';
import { ControlPanelState, isDataset, isQueryResponse } from '../types';
export function checkColumnType(

View File

@@ -16,8 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { QueryColumn, QueryResponse } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType, QueryColumn, QueryResponse } from '@superset-ui/core';
import { ColumnMeta, Dataset, isDataset, isQueryResponse } from '../types';
export function columnsByType(

View File

@@ -17,11 +17,11 @@
* under the License.
*/
import {
GenericDataType,
getColumnLabel,
isPhysicalColumn,
QueryFormColumn,
} from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { checkColumnType, ControlStateMapping } from '..';
export function isSortable(controls: ControlStateMapping): boolean {

View File

@@ -18,7 +18,8 @@
*/
import '@testing-library/jest-dom';
import { render } from '@superset-ui/core/spec';
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType } from '@superset-ui/core';
import { ColumnOption, ColumnOptionProps } from '../../src';
jest.mock('@superset-ui/chart-controls/components/SQLPopover', () => ({

View File

@@ -19,7 +19,8 @@
import { isValidElement } from 'react';
import { render, screen } from '@superset-ui/core/spec';
import '@testing-library/jest-dom';
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType } from '@superset-ui/core';
import { ColumnTypeLabel, ColumnTypeLabelProps } from '../../src';
describe('ColumnOption', () => {

View File

@@ -40,7 +40,7 @@ describe('aggregationOperator', () => {
granularity: 'month',
};
it('should return undefined for LAST_VALUE aggregation', () => {
test('should return undefined for LAST_VALUE aggregation', () => {
const formDataWithLastValue = {
...formData,
aggregation: 'LAST_VALUE',
@@ -51,7 +51,7 @@ describe('aggregationOperator', () => {
).toBeUndefined();
});
it('should return undefined when metrics is empty', () => {
test('should return undefined when metrics is empty', () => {
const queryObjectWithoutMetrics = {
...queryObject,
metrics: [],
@@ -67,7 +67,7 @@ describe('aggregationOperator', () => {
).toBeUndefined();
});
it('should apply sum aggregation to all metrics', () => {
test('should apply sum aggregation to all metrics', () => {
const formDataWithSum = {
...formData,
aggregation: 'sum',
@@ -91,7 +91,7 @@ describe('aggregationOperator', () => {
});
});
it('should apply mean aggregation to all metrics', () => {
test('should apply mean aggregation to all metrics', () => {
const formDataWithMean = {
...formData,
aggregation: 'mean',
@@ -115,7 +115,7 @@ describe('aggregationOperator', () => {
});
});
it('should use default aggregation when not specified', () => {
test('should use default aggregation when not specified', () => {
expect(aggregationOperator(formData, queryObject)).toBeUndefined();
});
});

View File

@@ -16,8 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { testQueryResponse } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType, testQueryResponse } from '@superset-ui/core';
import { checkColumnType, TestDataset } from '../../src';
test('checkColumnType columns from a Dataset', () => {

View File

@@ -16,8 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { DatasourceType, testQueryResponse } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import {
DatasourceType,
GenericDataType,
testQueryResponse,
} from '@superset-ui/core';
import { columnChoices } from '../../src';
describe('columnChoices()', () => {

View File

@@ -16,8 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { testQueryResponse, testQueryResults } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import {
GenericDataType,
testQueryResponse,
testQueryResults,
} from '@superset-ui/core';
import {
Dataset,
getTemporalColumns,

View File

@@ -17,7 +17,7 @@
* under the License.
*/
import { ControlStateMapping } from '@superset-ui/chart-controls';
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType } from '@superset-ui/core';
import { isSortable } from '../../src/utils/isSortable';
const controls: ControlStateMapping = {

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*", "types/**/*"],
"exclude": ["src/**/*.test.*", "src/**/*.stories.*"],

View File

@@ -0,0 +1,68 @@
/**
* 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.
*/
{
"plugins": ["jest", "jest-dom", "no-only-tests", "testing-library"],
"env": {
"jest/globals": true
},
"settings": {
"jest": {
"version": "detect"
}
},
"extends": [
"plugin:jest/recommended",
"plugin:jest-dom/recommended",
"plugin:testing-library/react"
],
"overrides": [
{
"files": [
"**/*.stories.*",
"**/*.overview.*",
"**/fixtures.*"
],
"rules": {
"import/no-extraneous-dependencies": "off"
}
}
],
"rules": {
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
"jest/consistent-test-it": "error",
"no-only-tests/no-only-tests": "error",
"prefer-promise-reject-errors": 0,
"testing-library/no-node-access": "off",
"testing-library/prefer-screen-queries": "off",
"testing-library/no-container": "off",
"testing-library/await-async-queries": "off",
"testing-library/await-async-utils": "off",
"testing-library/no-await-sync-events": "off",
"testing-library/no-render-in-lifecycle": "off",
"testing-library/no-unnecessary-act": "off",
"testing-library/no-wait-for-multiple-assertions": "off",
"testing-library/await-async-events": "off",
"testing-library/no-wait-for-side-effects": "off",
"testing-library/prefer-presence-queries": "off",
"testing-library/render-result-naming-convention": "off",
"testing-library/prefer-find-by": "off",
"testing-library/no-manual-cleanup": "off"
}
}

View File

@@ -26,7 +26,7 @@
"dependencies": {
"@apache-superset/core": "*",
"@ant-design/icons": "^5.2.6",
"@babel/runtime": "^7.28.4",
"@babel/runtime": "^7.28.2",
"@fontsource/fira-code": "^5.2.6",
"@fontsource/inter": "^5.2.6",
"@types/json-bigint": "^1.0.4",
@@ -78,7 +78,7 @@
"@types/d3-time-format": "^4.0.3",
"@types/react-table": "^7.7.20",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/jquery": "^3.5.33",
"@types/jquery": "^3.5.8",
"@types/lodash": "^4.17.20",
"@types/math-expression-evaluator": "^1.3.3",
"@types/node": "^22.10.3",
@@ -91,7 +91,7 @@
"timezone-mock": "1.3.6"
},
"peerDependencies": {
"antd": "^5.24.9",
"antd": "^5.24.6",
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.14.1",

View File

@@ -127,9 +127,13 @@ const Select = forwardRef(
const shouldShowSearch = allowNewOptions ? true : showSearch;
const [selectValue, setSelectValue] = useState(value);
const [inputValue, setInputValue] = useState('');
const [isLoading, setIsLoading] = useState(loading);
const [isDropdownVisible, setIsDropdownVisible] = useState(false);
const [isSearching, setIsSearching] = useState(false);
const [visibleOptions, setVisibleOptions] = useState<SelectOptionsType>([]);
const [maxTagCount, setMaxTagCount] = useState(
propsMaxTagCount ?? MAX_TAG_COUNT,
);
const [onChangeCount, setOnChangeCount] = useState(0);
const previousChangeCount = usePrevious(onChangeCount, 0);
const fireOnChange = useCallback(
@@ -137,11 +141,11 @@ const Select = forwardRef(
[onChangeCount],
);
const maxTagCount = oneLine
? isDropdownVisible
? 0
: 1
: (propsMaxTagCount ?? MAX_TAG_COUNT);
useEffect(() => {
if (oneLine) {
setMaxTagCount(isDropdownVisible ? 0 : 1);
}
}, [isDropdownVisible, oneLine]);
const mappedMode = isSingleMode ? undefined : 'multiple';
@@ -506,8 +510,6 @@ const Select = forwardRef(
],
);
const isLoading = loading ?? false;
const popupRender = (
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
) =>
@@ -534,6 +536,12 @@ const Select = forwardRef(
setVisibleOptions(initialOptions);
}, [initialOptions]);
useEffect(() => {
if (loading !== undefined && loading !== isLoading) {
setIsLoading(loading);
}
}, [isLoading, loading]);
useEffect(() => {
setSelectValue(value);
}, [value]);

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { render, screen, fireEvent } from '@superset-ui/core/spec';
import { render, screen } from '@superset-ui/core/spec';
import { renderHook } from '@testing-library/react-hooks';
import { TableInstance, useTable } from 'react-table';
import TableCollection from '.';
@@ -36,28 +36,19 @@ beforeEach(() => {
accessor: 'col2',
id: 'col2',
},
{
Header: 'Nested Field',
accessor: 'parent.child',
id: 'parent.child',
dataIndex: ['parent', 'child'],
},
];
const data = [
{
col1: 'Line 01 - Col 01',
col2: 'Line 01 - Col 02',
parent: { child: 'Nested Value 1' },
},
{
col1: 'Line 02 - Col 01',
col2: 'Line 02 - Col 02',
parent: { child: 'Nested Value 2' },
},
{
col1: 'Line 03 - Col 01',
col2: 'Line 03 - Col 02',
parent: { child: 'Nested Value 3' },
},
];
// @ts-ignore
@@ -215,28 +206,3 @@ test('Bulk selection should work with pagination', () => {
const checkboxes = screen.getAllByRole('checkbox');
expect(checkboxes.length).toBeGreaterThan(0);
});
test('should call setSortBy when clicking sortable column header', () => {
const setSortBy = jest.fn();
const sortingProps = {
...defaultProps,
setSortBy,
};
render(<TableCollection {...sortingProps} />);
// Target the nested field column (the column that needs the array-to-dot conversion)
const nestedFieldHeader = screen.getByText('Nested Field');
expect(nestedFieldHeader).toBeInTheDocument();
// Click on the nested field column header to trigger sorting
fireEvent.click(nestedFieldHeader);
// Verify setSortBy was called with the correct arguments and dot notation conversion
expect(setSortBy).toHaveBeenCalledWith([
{
id: 'parent.child',
desc: expect.any(Boolean),
},
]);
});

View File

@@ -215,14 +215,9 @@ function TableCollection<T extends object>({
const handleTableChange = useCallback(
(_pagination: any, _filters: any, sorter: SorterResult) => {
if (sorter && sorter.field) {
// Convert array field back to dot notation for nested fields
const fieldId = Array.isArray(sorter.field)
? sorter.field.join('.')
: sorter.field;
setSortBy?.([
{
id: fieldId,
id: sorter.field,
desc: sorter.order === 'descend',
},
] as SortingRule<T>[]);

View File

@@ -50,7 +50,7 @@ describe('Typography Component', () => {
it('renders strong text', () => {
render(<Typography.Text strong>Strong Text</Typography.Text>);
expect(screen.getByText('Strong Text')).toHaveStyle('font-weight: 600');
expect(screen.getByText('Strong Text')).toHaveStyle('font-weight: 500');
});
it('renders underlined text', () => {

View File

@@ -18,7 +18,7 @@
* under the License.
*/
import { GenericDataType } from '@apache-superset/core/api/core';
import { GenericDataType } from './QueryResponse';
import { QueryFormColumn } from './QueryFormData';
export interface AdhocColumn {

View File

@@ -17,7 +17,6 @@
* specific language governing permissions and limitations
* under the License.
*/
import { GenericDataType } from '@apache-superset/core/api/core';
import { DatasourceType } from './Datasource';
import { BinaryOperator, SetOperator, UnaryOperator } from './Operator';
import { AppliedTimeExtras, TimeRange } from './Time';
@@ -32,7 +31,7 @@ import { Maybe } from '../../types';
import { PostProcessingRule } from './PostProcessing';
import { JsonObject } from '../../connection';
import { TimeGranularity } from '../../time-format';
import { DataRecordValue } from './QueryResponse';
import { GenericDataType, DataRecordValue } from './QueryResponse';
export type BaseQueryObjectFilterClause = {
col: QueryFormColumn;

View File

@@ -17,10 +17,19 @@
* under the License.
*/
import { GenericDataType } from '@apache-superset/core/api/core';
import { TimeseriesDataRecord } from '../../chart';
import { AnnotationData } from './AnnotationLayer';
/**
* Generic data types, see enum of the same name in superset/utils/core.py.
*/
export enum GenericDataType {
Numeric = 0,
String = 1,
Temporal = 2,
Boolean = 3,
}
/**
* Primitive types for data field values.
*/

View File

@@ -16,18 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
// @fontsource/* v5.1+ doesn't play nice with eslint-import plugin v2.31+
/* eslint-disable import/extensions */
import '@fontsource/inter/200.css';
import '@fontsource/inter/400.css';
import '@fontsource/inter/500.css';
import '@fontsource/inter/600.css';
import '@fontsource/fira-code/400.css';
import '@fontsource/fira-code/500.css';
import '@fontsource/fira-code/600.css';
/* eslint-enable import/extensions */
import { css, useTheme, Global } from '@emotion/react';
export const GlobalStyles = () => {

View File

@@ -49,12 +49,14 @@ describe('Theme', () => {
});
describe('fromConfig', () => {
it('creates a theme with Ant Design defaults when no config is provided', () => {
it('creates a theme with default tokens when no config is provided', () => {
const theme = Theme.fromConfig();
// Verify Ant Design default tokens are set
expect(theme.theme.colorPrimary).toBeDefined();
expect(theme.theme.fontFamily).toBeDefined();
// Verify default primary color is set
expect(theme.theme.colorPrimary).toBe('#2893b3');
// Verify default font family is set
expect(theme.theme.fontFamily).toContain('Inter');
// Verify the theme is initialized with semantic color tokens
expect(theme.theme.colorText).toBeDefined();
@@ -77,8 +79,8 @@ describe('Theme', () => {
// Verify custom font family is set
expect(theme.theme.fontFamily).toBe('CustomFont, sans-serif');
// Unspecified values will use Ant Design defaults
expect(theme.theme.colorError).toBeDefined();
// But default tokens should still be preserved for unspecified values
expect(theme.theme.colorError).toBe('#e04355');
});
it('creates a theme with dark mode when dark algorithm is specified', () => {
@@ -203,586 +205,4 @@ describe('Theme', () => {
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
});
describe('fromConfig with baseTheme', () => {
it('applies base theme tokens under the main config', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#ff0000',
colorError: '#00ff00',
fontFamily: 'BaseFont',
},
};
const userConfig: AnyThemeConfig = {
token: {
colorPrimary: '#0000ff',
},
};
const theme = Theme.fromConfig(userConfig, baseTheme);
// User config overrides base theme
expect(theme.theme.colorPrimary).toBe('#0000ff');
// Base theme tokens are preserved when not overridden
expect(theme.theme.colorError).toBe('#00ff00');
expect(theme.theme.fontFamily).toBe('BaseFont');
});
it('applies base theme when no user config is provided', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#ff0000',
fontFamily: 'TestFont',
},
algorithm: antdThemeImport.darkAlgorithm,
};
const theme = Theme.fromConfig(undefined, baseTheme);
// Color may be transformed by dark algorithm, check fontFamily instead
expect(theme.theme.fontFamily).toBe('TestFont');
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('handles empty config with base theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#ff0000',
},
algorithm: antdThemeImport.defaultAlgorithm,
};
const emptyConfig: AnyThemeConfig = {};
const theme = Theme.fromConfig(emptyConfig, baseTheme);
// Base theme tokens should be applied
expect(theme.theme.colorPrimary).toBe('#ff0000');
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DEFAULT);
});
it('merges algorithms correctly with base theme', () => {
const baseTheme: AnyThemeConfig = {
algorithm: antdThemeImport.compactAlgorithm,
};
const userConfig: AnyThemeConfig = {
algorithm: antdThemeImport.darkAlgorithm,
};
const theme = Theme.fromConfig(userConfig, baseTheme);
// User algorithm should override base algorithm
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('merges component overrides with base theme', () => {
const baseTheme: AnyThemeConfig = {
components: {
Button: {
colorPrimary: '#basebutton',
},
Input: {
colorBorder: '#baseinput',
},
},
};
const userConfig: AnyThemeConfig = {
components: {
Button: {
colorPrimary: '#userbutton',
},
},
};
const theme = Theme.fromConfig(userConfig, baseTheme);
const serialized = theme.toSerializedConfig();
// User component config overrides base
expect(serialized.components?.Button?.colorPrimary).toBe('#userbutton');
// Base component config preserved when not overridden
expect(serialized.components?.Input?.colorBorder).toBe('#baseinput');
});
it('handles undefined config and undefined base theme', () => {
const theme = Theme.fromConfig(undefined, undefined);
// Should get Ant Design defaults
expect(theme.theme.colorPrimary).toBeDefined();
expect(theme.theme.fontFamily).toBeDefined();
});
it('preserves custom tokens in base theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#ff0000',
// Custom superset-specific tokens
brandLogoAlt: 'CustomLogo',
menuHoverBackgroundColor: '#00ff00',
} as Record<string, any>,
};
const theme = Theme.fromConfig({}, baseTheme);
// Standard token
expect(theme.theme.colorPrimary).toBe('#ff0000');
// Custom tokens should be preserved
expect((theme.theme as any).brandLogoAlt).toBe('CustomLogo');
expect((theme.theme as any).menuHoverBackgroundColor).toBe('#00ff00');
});
});
describe('edge cases with base theme and dark mode', () => {
it('correctly applies base theme tokens in dark mode', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#1890ff',
fontFamily: 'TestFont',
},
algorithm: antdThemeImport.defaultAlgorithm,
};
const baseThemeDark: AnyThemeConfig = {
...baseTheme,
algorithm: antdThemeImport.darkAlgorithm,
};
// Simulate light mode with base theme
const lightTheme = Theme.fromConfig({}, baseTheme);
expect(lightTheme.theme.colorPrimary).toBe('#1890ff');
expect(lightTheme.theme.fontFamily).toBe('TestFont');
// Simulate dark mode with base theme dark
const darkTheme = Theme.fromConfig({}, baseThemeDark);
// Dark algorithm transforms colors, but fontFamily should be preserved
expect(darkTheme.theme.fontFamily).toBe('TestFont');
// Verify the algorithm is different
const lightSerialized = lightTheme.toSerializedConfig();
const darkSerialized = darkTheme.toSerializedConfig();
expect(lightSerialized.algorithm).toBe(ThemeAlgorithm.DEFAULT);
expect(darkSerialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('handles switching from custom theme back to base theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#1890ff',
},
algorithm: antdThemeImport.defaultAlgorithm,
};
// First apply custom theme
const customConfig: AnyThemeConfig = {
token: {
colorPrimary: '#52c41a',
},
};
const themeWithCustom = Theme.fromConfig(customConfig, baseTheme);
expect(themeWithCustom.theme.colorPrimary).toBe('#52c41a');
// Then switch back to empty config (simulating removal of custom theme)
const themeWithEmpty = Theme.fromConfig({}, baseTheme);
expect(themeWithEmpty.theme.colorPrimary).toBe('#1890ff');
// Verify they produce different outputs
expect(themeWithCustom.theme.colorPrimary).not.toBe(
themeWithEmpty.theme.colorPrimary,
);
});
it('handles algorithm-only config with base theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
fontFamily: 'TestFont',
borderRadius: 8,
},
algorithm: antdThemeImport.defaultAlgorithm,
};
// Config that only specifies algorithm (common for THEME_DARK)
const algorithmOnlyConfig: AnyThemeConfig = {
algorithm: antdThemeImport.darkAlgorithm,
};
const theme = Theme.fromConfig(algorithmOnlyConfig, baseTheme);
// Should have base theme tokens
expect(theme.theme.fontFamily).toBe('TestFont');
expect(theme.theme.borderRadius).toBe(8);
// Should have user's algorithm
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
});
describe('base theme integration tests', () => {
it('merges base theme tokens with empty user theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
colorError: '#e04355',
fontFamily: 'Inter, Helvetica',
},
};
const userTheme: AnyThemeConfig = {
algorithm: antdThemeImport.defaultAlgorithm,
};
const theme = Theme.fromConfig(userTheme, baseTheme);
expect(theme.theme.colorPrimary).toBe('#2893B3');
expect(theme.theme.colorError).toBe('#e04355');
expect(theme.theme.fontFamily).toBe('Inter, Helvetica');
// Should have user's algorithm
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DEFAULT);
});
it('allows user theme to override specific base theme tokens', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
colorError: '#e04355',
fontFamily: 'Inter, Helvetica',
borderRadius: 4,
},
};
const userTheme: AnyThemeConfig = {
algorithm: antdThemeImport.defaultAlgorithm,
token: {
colorPrimary: '#123456', // Override primary color
// Leave other tokens from base
},
};
const theme = Theme.fromConfig(userTheme, baseTheme);
// User override should win
expect(theme.theme.colorPrimary).toBe('#123456');
// Base theme tokens should be preserved
expect(theme.theme.colorError).toBe('#e04355');
expect(theme.theme.fontFamily).toBe('Inter, Helvetica');
expect(theme.theme.borderRadius).toBe(4);
});
it('handles base theme with dark algorithm correctly', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
fontFamily: 'Inter, Helvetica',
},
};
const baseThemeDark: AnyThemeConfig = {
...baseTheme,
algorithm: antdThemeImport.darkAlgorithm,
};
const userDarkTheme: AnyThemeConfig = {
algorithm: antdThemeImport.darkAlgorithm,
};
const theme = Theme.fromConfig(userDarkTheme, baseThemeDark);
// Should have base tokens
expect(theme.theme.fontFamily).toBe('Inter, Helvetica');
// Should be in dark mode
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('works with real-world Superset base theme configuration', () => {
// Simulate actual Superset base theme (THEME_DEFAULT/THEME_DARK from config)
const supersetBaseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
colorError: '#e04355',
colorWarning: '#fcc700',
colorSuccess: '#5ac189',
colorInfo: '#66bcfe',
fontFamily: "'Inter', Helvetica, Arial",
fontFamilyCode: "'Fira Code', 'Courier New', monospace",
},
};
// Simulate THEME_DEFAULT from config
const themeDefault: AnyThemeConfig = {
algorithm: antdThemeImport.defaultAlgorithm,
};
// Simulate THEME_DARK from config
const themeDark: AnyThemeConfig = {
algorithm: antdThemeImport.darkAlgorithm,
};
// Test light mode
const lightTheme = Theme.fromConfig(themeDefault, supersetBaseTheme);
expect(lightTheme.theme.colorPrimary).toBe('#2893B3');
expect(lightTheme.theme.fontFamily).toBe("'Inter', Helvetica, Arial");
// Test dark mode
const darkTheme = Theme.fromConfig(themeDark, {
...supersetBaseTheme,
algorithm: antdThemeImport.darkAlgorithm,
});
expect(darkTheme.theme.fontFamily).toBe("'Inter', Helvetica, Arial");
const darkSerialized = darkTheme.toSerializedConfig();
expect(darkSerialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('handles component overrides in base theme', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
},
components: {
Button: {
primaryColor: '#custom-button',
borderRadius: 8,
},
},
};
const userTheme: AnyThemeConfig = {
algorithm: antdThemeImport.defaultAlgorithm,
};
const theme = Theme.fromConfig(userTheme, baseTheme);
// Should preserve component overrides
const serialized = theme.toSerializedConfig();
expect(serialized.components?.Button?.primaryColor).toBe(
'#custom-button',
);
expect(serialized.components?.Button?.borderRadius).toBe(8);
});
it('properly handles algorithm property override', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
},
algorithm: antdThemeImport.defaultAlgorithm,
};
const userTheme: AnyThemeConfig = {
algorithm: antdThemeImport.darkAlgorithm,
token: {
borderRadius: 8,
},
};
const theme = Theme.fromConfig(userTheme, baseTheme);
const serialized = theme.toSerializedConfig();
// User algorithm should override base algorithm
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
// Both base and user tokens should be merged
expect(serialized.token?.colorPrimary).toBeTruthy();
expect(serialized.token?.borderRadius).toBe(8);
});
it('handles cssVar, hashed and inherit properties correctly', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
},
cssVar: true,
hashed: false,
};
const userTheme: AnyThemeConfig = {
token: {
borderRadius: 8,
},
inherit: true,
};
const theme = Theme.fromConfig(userTheme, baseTheme);
const serialized = theme.toSerializedConfig();
// User properties override/add to base
expect(serialized.inherit).toBe(true);
expect(serialized.cssVar).toBe(true);
expect(serialized.hashed).toBe(false);
// Tokens are still merged
expect(serialized.token?.colorPrimary).toBeTruthy();
expect(serialized.token?.borderRadius).toBe(8);
});
it('merges nested component styles correctly', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
fontFamily: 'BaseFont',
},
components: {
Button: {
colorPrimary: '#basebutton',
fontSize: 14,
},
Input: {
colorBorder: '#baseinput',
},
},
};
const userTheme: AnyThemeConfig = {
token: {
borderRadius: 8,
},
components: {
Button: {
fontSize: 16, // Override Button fontSize
},
Select: {
colorBorder: '#userselect', // Add new component
},
},
};
const theme = Theme.fromConfig(userTheme, baseTheme);
const serialized = theme.toSerializedConfig();
// Tokens should be merged
// Note: components present may affect color transformation
expect(serialized.token?.colorPrimary).toBeTruthy();
expect(serialized.token?.borderRadius).toBe(8);
expect(serialized.token?.fontFamily).toBe('BaseFont');
// Components should be merged (shallow merge per component)
expect(serialized.components?.Button?.colorPrimary).toBe('#basebutton');
expect(serialized.components?.Button?.fontSize).toBe(16); // User override
expect(serialized.components?.Input?.colorBorder).toBe('#baseinput');
expect(serialized.components?.Select?.colorBorder).toBe('#userselect');
});
it('setConfig replaces theme config entirely (does not preserve base theme)', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
fontFamily: 'Inter',
},
};
const theme = Theme.fromConfig({}, baseTheme);
expect(theme.theme.colorPrimary).toBe('#2893B3');
expect(theme.theme.fontFamily).toBe('Inter');
// Update config (simulating theme change)
theme.setConfig({
token: {
colorPrimary: '#654321',
},
algorithm: antdThemeImport.darkAlgorithm,
});
// setConfig replaces the entire config, so base theme is NOT preserved
// This is expected behavior - setConfig is for complete replacement
expect(theme.theme.colorPrimary).toBeTruthy();
// fontFamily reverts to Ant Design default since base theme is not reapplied
expect(theme.theme.fontFamily).not.toBe('Inter');
});
it('minimal theme preserves ALL base theme tokens except overridden ones', () => {
// Simulate a comprehensive base theme with many tokens
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
colorError: '#e04355',
colorWarning: '#fcc700',
colorSuccess: '#5ac189',
colorInfo: '#66bcfe',
fontFamily: 'Inter, Helvetica',
fontSize: 14,
borderRadius: 4,
lineWidth: 1,
controlHeight: 32,
// Custom Superset tokens
brandLogoAlt: 'CustomLogo',
menuHoverBackgroundColor: '#eeeeee',
} as Record<string, any>,
algorithm: antdThemeImport.defaultAlgorithm,
};
// Minimal theme that only overrides primary color and algorithm
const minimalTheme: AnyThemeConfig = {
token: {
colorPrimary: '#ff05dd', // Only override this
},
algorithm: antdThemeImport.darkAlgorithm, // Change to dark
};
const theme = Theme.fromConfig(minimalTheme, baseTheme);
// User's override should apply
expect(theme.theme.colorPrimary).toBe('#ff05dd');
// ALL base theme tokens should be preserved
expect(theme.theme.colorError).toBe('#e04355');
expect(theme.theme.colorWarning).toBe('#fcc700');
expect(theme.theme.colorSuccess).toBe('#5ac189');
expect(theme.theme.colorInfo).toBe('#66bcfe');
expect(theme.theme.fontFamily).toBe('Inter, Helvetica');
expect(theme.theme.fontSize).toBe(14);
expect(theme.theme.borderRadius).toBe(4);
expect(theme.theme.lineWidth).toBe(1);
expect(theme.theme.controlHeight).toBe(32);
// Custom tokens should also be preserved
expect((theme.theme as any).brandLogoAlt).toBe('CustomLogo');
expect((theme.theme as any).menuHoverBackgroundColor).toBe('#eeeeee');
// Algorithm should be updated
const serialized = theme.toSerializedConfig();
expect(serialized.algorithm).toBe(ThemeAlgorithm.DARK);
});
it('arrays in themes are replaced entirely, not merged by index', () => {
const baseTheme: AnyThemeConfig = {
token: {
colorPrimary: '#2893B3',
},
algorithm: [
antdThemeImport.compactAlgorithm,
antdThemeImport.defaultAlgorithm,
],
};
const userTheme: AnyThemeConfig = {
algorithm: [antdThemeImport.darkAlgorithm], // Replace with single item array
};
const theme = Theme.fromConfig(userTheme, baseTheme);
const serialized = theme.toSerializedConfig();
// User's array should completely replace base array
expect(Array.isArray(serialized.algorithm)).toBe(true);
expect(serialized.algorithm).toHaveLength(1);
expect(serialized.algorithm).toContain(ThemeAlgorithm.DARK);
expect(serialized.algorithm).not.toContain(ThemeAlgorithm.COMPACT);
expect(serialized.algorithm).not.toContain(ThemeAlgorithm.DEFAULT);
});
});
});

View File

@@ -20,13 +20,31 @@
// eslint-disable-next-line no-restricted-syntax
import React from 'react';
import { theme as antdThemeImport, ConfigProvider } from 'antd';
// @fontsource/* v5.1+ doesn't play nice with eslint-import plugin v2.31+
/* eslint-disable import/extensions */
import '@fontsource/inter/200.css';
/* eslint-disable import/extensions */
import '@fontsource/inter/400.css';
/* eslint-disable import/extensions */
import '@fontsource/inter/500.css';
/* eslint-disable import/extensions */
import '@fontsource/inter/600.css';
/* eslint-disable import/extensions */
import '@fontsource/fira-code/400.css';
/* eslint-disable import/extensions */
import '@fontsource/fira-code/500.css';
/* eslint-disable import/extensions */
import '@fontsource/fira-code/600.css';
import {
ThemeProvider,
CacheProvider as EmotionCacheProvider,
} from '@emotion/react';
import createCache from '@emotion/cache';
import { noop, mergeWith } from 'lodash';
import { noop } from 'lodash';
import { GlobalStyles } from './GlobalStyles';
import {
AntdThemeConfig,
AnyThemeConfig,
@@ -35,16 +53,63 @@ import {
allowedAntdTokens,
SharedAntdTokens,
} from './types';
import { normalizeThemeConfig, serializeThemeConfig } from './utils';
/* eslint-disable theme-colors/no-literal-colors */
export class Theme {
theme: SupersetTheme;
private static readonly defaultTokens = {
// Brand
brandLogoAlt: 'Apache Superset',
brandLogoUrl: '/static/assets/images/superset-logo-horiz.png',
brandLogoMargin: '18px',
brandLogoHref: '/',
brandLogoHeight: '24px',
// Spinner
brandSpinnerUrl: undefined,
brandSpinnerSvg: undefined,
// Default colors
colorPrimary: '#2893B3', // NOTE: previous lighter primary color was #20a7c9
colorLink: '#2893B3',
colorError: '#e04355',
colorWarning: '#fcc700',
colorSuccess: '#5ac189',
colorInfo: '#66bcfe',
// Forcing some default tokens
fontFamily: `'Inter', Helvetica, Arial`,
fontFamilyCode: `'Fira Code', 'Courier New', monospace`,
// Extra tokens
transitionTiming: 0.3,
brandIconMaxWidth: 37,
fontSizeXS: '8',
fontSizeXXL: '28',
fontWeightNormal: '400',
fontWeightLight: '300',
fontWeightStrong: 500,
};
private antdConfig: AntdThemeConfig;
private constructor({ config }: { config?: AnyThemeConfig }) {
this.SupersetThemeProvider = this.SupersetThemeProvider.bind(this);
this.setConfig(config || {});
// Create a new config object with default tokens
const newConfig: AnyThemeConfig = config ? { ...config } : {};
// Ensure token property exists with defaults
newConfig.token = {
...Theme.defaultTokens,
...(config?.token || {}),
};
this.setConfig(newConfig);
}
/**
@@ -53,24 +118,9 @@ export class Theme {
* If simple tokens are provided as { token: {...} }, they will be applied with defaults
* If no config is provided, uses default tokens
* Dark mode can be set via the algorithm property in the config
* @param config - The theme configuration
* @param baseTheme - Optional base theme to apply under the config
*/
static fromConfig(
config?: AnyThemeConfig,
baseTheme?: AnyThemeConfig,
): Theme {
let mergedConfig: AnyThemeConfig | undefined = config;
if (baseTheme && config) {
mergedConfig = mergeWith({}, baseTheme, config, (objValue, srcValue) =>
Array.isArray(srcValue) ? srcValue : undefined,
);
} else if (baseTheme && !config) {
mergedConfig = baseTheme;
}
return new Theme({ config: mergedConfig });
static fromConfig(config?: AnyThemeConfig): Theme {
return new Theme({ config });
}
private static getFilteredAntdTheme(
@@ -98,15 +148,22 @@ export class Theme {
setConfig(config: AnyThemeConfig): void {
const antdConfig = normalizeThemeConfig(config);
// Apply default tokens to token property
antdConfig.token = {
...Theme.defaultTokens,
...(antdConfig.token || {}),
};
// First phase: Let Ant Design compute the tokens
const tokens = Theme.getFilteredAntdTheme(antdConfig);
// Set the base theme properties
this.antdConfig = antdConfig;
this.theme = {
...tokens, // First apply Ant Design computed tokens
...(antdConfig.token || {}), // Then override with our custom tokens
} as SupersetTheme;
...Theme.defaultTokens,
...antdConfig.token, // Passing through the extra, superset-specific tokens
...tokens,
};
// Update the providers with the fully formed theme
this.updateProviders(
@@ -193,3 +250,5 @@ export class Theme {
);
}
}
/* eslint-enable theme-colors/no-literal-colors */

View File

@@ -78,7 +78,6 @@ export type SerializableThemeConfig = {
algorithm?: ThemeAlgorithmOption;
hashed?: boolean;
inherit?: boolean;
cssVar?: boolean | { key?: string; prefix?: string };
};
/**

View File

@@ -16,13 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { theme as antdTheme } from 'antd';
import {
getFontSize,
getColorVariants,
isThemeDark,
isThemeConfigDark,
} from './themeUtils';
import { getFontSize, getColorVariants, isThemeDark } from './themeUtils';
import { Theme } from '../Theme';
import { ThemeAlgorithm } from '../types';
@@ -77,7 +71,8 @@ describe('themeUtils', () => {
token: { fontSize: '14' },
});
expect(getFontSize(minimalTheme.theme, 'xs')).toBe('14');
// Ant Design provides fontSizeXS: '8' by default
expect(getFontSize(minimalTheme.theme, 'xs')).toBe('8');
expect(getFontSize(minimalTheme.theme, 'm')).toBe('14');
});
});
@@ -136,111 +131,4 @@ describe('themeUtils', () => {
expect(variants.bg).toBeUndefined();
});
});
describe('isThemeConfigDark', () => {
it('returns true for config with dark algorithm', () => {
const config = {
algorithm: antdTheme.darkAlgorithm,
};
expect(isThemeConfigDark(config)).toBe(true);
});
it('returns true for config with dark algorithm in array', () => {
const config = {
algorithm: [antdTheme.darkAlgorithm, antdTheme.compactAlgorithm],
};
expect(isThemeConfigDark(config)).toBe(true);
});
it('returns false for config without dark algorithm', () => {
const config = {
algorithm: antdTheme.defaultAlgorithm,
};
expect(isThemeConfigDark(config)).toBe(false);
});
it('returns false for config with no algorithm', () => {
const config = {
token: {
colorPrimary: '#1890ff',
},
};
expect(isThemeConfigDark(config)).toBe(false);
});
it('detects manually-created dark theme without dark algorithm', () => {
// This is the edge case: dark colors without dark algorithm
const config = {
token: {
colorBgContainer: '#1a1a1a', // Dark background
colorBgBase: '#0a0a0a', // Dark base
colorText: '#ffffff', // Light text
},
};
expect(isThemeConfigDark(config)).toBe(true);
});
it('does not false-positive on light theme with custom colors', () => {
const config = {
token: {
colorBgContainer: '#ffffff', // Light background
colorBgBase: '#f5f5f5', // Light base
colorText: '#000000', // Dark text
},
};
expect(isThemeConfigDark(config)).toBe(false);
});
it('handles partial color tokens gracefully', () => {
// With actual theme computation, a dark colorBgContainer results in a dark theme
const config = {
token: {
colorBgContainer: '#1a1a1a', // Dark background
// Missing other color tokens
},
};
expect(isThemeConfigDark(config)).toBe(true);
});
it('respects colorBgContainer as the primary indicator', () => {
// The computed theme uses colorBgContainer as the main background
const darkConfig = {
token: {
colorBgContainer: '#1a1a1a', // Dark background
colorText: '#000000', // Dark text (unusual but doesn't override)
},
};
expect(isThemeConfigDark(darkConfig)).toBe(true);
const lightConfig = {
token: {
colorBgContainer: '#ffffff', // Light background
colorText: '#ffffff', // Light text (unusual but doesn't override)
},
};
expect(isThemeConfigDark(lightConfig)).toBe(false);
});
it('handles non-string color tokens gracefully', () => {
const config = {
token: {
colorBgContainer: undefined,
colorText: null,
colorBgBase: 123, // Invalid type
},
};
expect(isThemeConfigDark(config)).toBe(false);
});
it('returns false for empty config', () => {
expect(isThemeConfigDark({})).toBe(false);
});
it('returns false for config with empty token object', () => {
const config = {
token: {},
};
expect(isThemeConfigDark(config)).toBe(false);
});
});
});

View File

@@ -18,14 +18,7 @@
*/
import tinycolor from 'tinycolor2';
import { useTheme as useEmotionTheme } from '@emotion/react';
import { theme as antdTheme } from 'antd';
import type {
SupersetTheme,
FontSizeKey,
ColorVariants,
AnyThemeConfig,
} from '../types';
import { normalizeThemeConfig } from '../utils';
import type { SupersetTheme, FontSizeKey, ColorVariants } from '../types';
const fontSizeMap: Record<FontSizeKey, keyof SupersetTheme> = {
xs: 'fontSizeXS',
@@ -120,22 +113,6 @@ export function isThemeDark(theme: SupersetTheme): boolean {
return tinycolor(theme.colorBgContainer).isDark();
}
/**
* Check if a theme configuration results in a dark theme
* @param config - The theme configuration to check
* @returns true if the config results in a dark theme, false otherwise
*/
export function isThemeConfigDark(config: AnyThemeConfig): boolean {
try {
const normalizedConfig = normalizeThemeConfig(config);
const themeConfig = antdTheme.getDesignToken(normalizedConfig);
return tinycolor(themeConfig.colorBgContainer).isDark();
} catch {
return false;
}
}
/**
* Hook to determine if the current theme is dark mode
* @returns true if theme is dark, false if light

View File

@@ -16,8 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { AdhocMetric } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/api/core';
import { AdhocMetric, GenericDataType } from '@superset-ui/core';
export const NUM_METRIC: AdhocMetric = {
expressionType: 'SIMPLE',

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*", "types/**/*"],
"exclude": ["src/**/*.test.*", "src/**/*.stories.*"],

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*", "types/**/*"],
"exclude": ["src/**/*.test.*", "src/**/*.stories.*"]

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*.ts", "src/**/*.tsx", "types/**/*"],
"exclude": [

View File

@@ -1,15 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Path Resolution: Override baseUrl to maintain correct path mappings from parent config
// (e.g., "@apache-superset/core" -> "./packages/superset-core/src")
"baseUrl": "../..",
// Directory Overrides: Parent config paths are relative to frontend root,
// but packages need paths relative to their own directory
"outDir": "lib",
"rootDir": "src",
"declarationDir": "lib"
"outDir": "lib"
},
"include": ["src/**/*.ts", "src/**/*.tsx", "types/**/*"],
"exclude": [

Some files were not shown because too many files have changed in this diff Show More