fix: Address high-severity bandit issues
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example 1: Basic Token Ingestion
|
||||
Example 1: Basic Token Ingestion.
|
||||
|
||||
Shows how to ingest design tokens from different sources.
|
||||
"""
|
||||
@@ -62,19 +62,18 @@ async def main():
|
||||
# 3. JSON Tokens (W3C Format)
|
||||
print("\n3. JSON Design Tokens (W3C)")
|
||||
print("-" * 40)
|
||||
from tools.ingest.json_tokens import JSONTokenSource
|
||||
import json
|
||||
|
||||
from tools.ingest.json_tokens import JSONTokenSource
|
||||
|
||||
json_content = {
|
||||
"color": {
|
||||
"primary": {
|
||||
"500": {"value": "#3B82F6", "type": "color"},
|
||||
"600": {"value": "#2563EB", "type": "color"}
|
||||
"600": {"value": "#2563EB", "type": "color"},
|
||||
}
|
||||
},
|
||||
"spacing": {
|
||||
"md": {"value": "16px", "type": "dimension"}
|
||||
}
|
||||
"spacing": {"md": {"value": "16px", "type": "dimension"}},
|
||||
}
|
||||
|
||||
json_parser = JSONTokenSource()
|
||||
@@ -85,7 +84,9 @@ async def main():
|
||||
print(f" {token.name} = {token.value} ({token.type.value})")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"Total tokens extracted: {len(css_result.tokens) + len(scss_result.tokens) + len(json_result.tokens)}")
|
||||
print(
|
||||
f"Total tokens extracted: {len(css_result.tokens) + len(scss_result.tokens) + len(json_result.tokens)}"
|
||||
)
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example 2: Token Merging with Conflict Resolution
|
||||
Example 2: Token Merging with Conflict Resolution.
|
||||
|
||||
Shows how to merge tokens from multiple sources using different strategies.
|
||||
"""
|
||||
@@ -17,28 +17,40 @@ async def main():
|
||||
print("EXAMPLE 2: Token Merging & Conflict Resolution")
|
||||
print("=" * 60)
|
||||
|
||||
from tools.ingest.merge import TokenMerger, MergeStrategy
|
||||
from tools.ingest.base import TokenCollection, DesignToken, TokenType
|
||||
from tools.ingest.base import DesignToken, TokenCollection, TokenType
|
||||
from tools.ingest.merge import MergeStrategy, TokenMerger
|
||||
|
||||
# Create tokens from different sources
|
||||
print("\n1. Creating token collections from different sources...")
|
||||
print("-" * 60)
|
||||
|
||||
css_tokens = TokenCollection([
|
||||
DesignToken(name="color.primary", value="#FF0000", type=TokenType.COLOR, source="css"),
|
||||
DesignToken(name="color.secondary", value="#00FF00", type=TokenType.COLOR, source="css"),
|
||||
DesignToken(name="spacing.md", value="16px", type=TokenType.SPACING, source="css"),
|
||||
])
|
||||
css_tokens = TokenCollection(
|
||||
[
|
||||
DesignToken(name="color.primary", value="#FF0000", type=TokenType.COLOR, source="css"),
|
||||
DesignToken(
|
||||
name="color.secondary", value="#00FF00", type=TokenType.COLOR, source="css"
|
||||
),
|
||||
DesignToken(name="spacing.md", value="16px", type=TokenType.SPACING, source="css"),
|
||||
]
|
||||
)
|
||||
|
||||
figma_tokens = TokenCollection([
|
||||
DesignToken(name="color.primary", value="#3B82F6", type=TokenType.COLOR, source="figma"),
|
||||
DesignToken(name="color.accent", value="#F59E0B", type=TokenType.COLOR, source="figma"),
|
||||
])
|
||||
figma_tokens = TokenCollection(
|
||||
[
|
||||
DesignToken(
|
||||
name="color.primary", value="#3B82F6", type=TokenType.COLOR, source="figma"
|
||||
),
|
||||
DesignToken(name="color.accent", value="#F59E0B", type=TokenType.COLOR, source="figma"),
|
||||
]
|
||||
)
|
||||
|
||||
tailwind_tokens = TokenCollection([
|
||||
DesignToken(name="color.primary", value="#2563EB", type=TokenType.COLOR, source="tailwind"),
|
||||
DesignToken(name="spacing.lg", value="24px", type=TokenType.SPACING, source="tailwind"),
|
||||
])
|
||||
tailwind_tokens = TokenCollection(
|
||||
[
|
||||
DesignToken(
|
||||
name="color.primary", value="#2563EB", type=TokenType.COLOR, source="tailwind"
|
||||
),
|
||||
DesignToken(name="spacing.lg", value="24px", type=TokenType.SPACING, source="tailwind"),
|
||||
]
|
||||
)
|
||||
|
||||
print(f"CSS: {len(css_tokens.tokens)} tokens")
|
||||
print(f"Figma: {len(figma_tokens.tokens)} tokens")
|
||||
@@ -67,7 +79,9 @@ async def main():
|
||||
print(f" • {conflict.token_name}:")
|
||||
print(f" Existing: {conflict.existing.value} (from {conflict.existing.source})")
|
||||
print(f" Incoming: {conflict.incoming.value} (from {conflict.incoming.source})")
|
||||
print(f" ✓ Chose: {conflict.resolved_token.value} (from {conflict.resolved_token.source})")
|
||||
print(
|
||||
f" ✓ Chose: {conflict.resolved_token.value} (from {conflict.resolved_token.source})"
|
||||
)
|
||||
|
||||
# Show final token values
|
||||
print("\nFinal Tokens:")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example 3: Project Analysis & Quick Wins
|
||||
Example 3: Project Analysis & Quick Wins.
|
||||
|
||||
Shows how to analyze a React project and identify improvement opportunities.
|
||||
"""
|
||||
@@ -28,8 +28,8 @@ async def main():
|
||||
scanner = ProjectScanner(project_path)
|
||||
analysis = await scanner.scan()
|
||||
|
||||
print(f"✅ Project scanned successfully")
|
||||
print(f"\nProject Details:")
|
||||
print("✅ Project scanned successfully")
|
||||
print("\nProject Details:")
|
||||
print(f" Framework: {analysis.framework}")
|
||||
print(f" Styling: {analysis.styling_approach}")
|
||||
print(f" Package Manager: {analysis.package_manager}")
|
||||
@@ -63,7 +63,8 @@ async def main():
|
||||
print("-" * 60)
|
||||
|
||||
high_roi = [
|
||||
w for w in wins.opportunities
|
||||
w
|
||||
for w in wins.opportunities
|
||||
if w.impact.value == "high" and w.effort.value in ["low", "medium"]
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
DSS Merge Case Examples
|
||||
DSS Merge Case Examples.
|
||||
|
||||
Demonstrates how DSS handles multi-source token ingestion and translation
|
||||
to the canonical DSS structure. Uses HeroUI and shadcn as examples.
|
||||
@@ -8,18 +8,14 @@ Key Principle: DSS is MONOLITHIC. External systems translate TO us.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent to path for imports
|
||||
import sys
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "tools"))
|
||||
from pathlib import Path
|
||||
|
||||
from ingest import (
|
||||
DesignToken, TokenCollection, TokenMerger, MergeStrategy,
|
||||
CSSTokenSource, JSONTokenSource
|
||||
)
|
||||
from ingest.base import TokenType, TokenCategory
|
||||
from ingest import CSSTokenSource, MergeStrategy, TokenMerger
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "tools"))
|
||||
|
||||
|
||||
# =============================================================================
|
||||
@@ -162,27 +158,39 @@ LEGACY_CORPORATE_TOKENS = """
|
||||
|
||||
DSS_CANONICAL = {
|
||||
"colors": {
|
||||
"primary": {"50": None, "100": None, "200": None, "300": None, "400": None,
|
||||
"500": None, "600": None, "700": None, "800": None, "900": None},
|
||||
"primary": {
|
||||
"50": None,
|
||||
"100": None,
|
||||
"200": None,
|
||||
"300": None,
|
||||
"400": None,
|
||||
"500": None,
|
||||
"600": None,
|
||||
"700": None,
|
||||
"800": None,
|
||||
"900": None,
|
||||
},
|
||||
"secondary": {"500": None},
|
||||
"success": {"500": None},
|
||||
"warning": {"500": None},
|
||||
"danger": {"500": None},
|
||||
"neutral": {"50": None, "100": None, "200": None, "300": None, "400": None,
|
||||
"500": None, "600": None, "700": None, "800": None, "900": None},
|
||||
"neutral": {
|
||||
"50": None,
|
||||
"100": None,
|
||||
"200": None,
|
||||
"300": None,
|
||||
"400": None,
|
||||
"500": None,
|
||||
"600": None,
|
||||
"700": None,
|
||||
"800": None,
|
||||
"900": None,
|
||||
},
|
||||
},
|
||||
"spacing": {
|
||||
"xs": None, "sm": None, "md": None, "lg": None, "xl": None, "2xl": None
|
||||
},
|
||||
"radius": {
|
||||
"sm": None, "md": None, "lg": None, "xl": None, "full": None
|
||||
},
|
||||
"shadows": {
|
||||
"sm": None, "md": None, "lg": None, "xl": None
|
||||
},
|
||||
"typography": {
|
||||
"fontSize": {"xs": None, "sm": None, "base": None, "lg": None, "xl": None}
|
||||
}
|
||||
"spacing": {"xs": None, "sm": None, "md": None, "lg": None, "xl": None, "2xl": None},
|
||||
"radius": {"sm": None, "md": None, "lg": None, "xl": None, "full": None},
|
||||
"shadows": {"sm": None, "md": None, "lg": None, "xl": None},
|
||||
"typography": {"fontSize": {"xs": None, "sm": None, "base": None, "lg": None, "xl": None}},
|
||||
}
|
||||
|
||||
|
||||
@@ -190,9 +198,10 @@ DSS_CANONICAL = {
|
||||
# TRANSLATION DICTIONARIES
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def create_heroui_translation():
|
||||
"""
|
||||
Translation dictionary: HeroUI → DSS Canonical
|
||||
Translation dictionary: HeroUI → DSS Canonical.
|
||||
|
||||
HeroUI uses numeric color scales (like DSS) but different naming.
|
||||
Mapping is mostly 1:1 with prefix removal.
|
||||
@@ -214,33 +223,27 @@ def create_heroui_translation():
|
||||
"--heroui-primary-700": "color.primary.700",
|
||||
"--heroui-primary-800": "color.primary.800",
|
||||
"--heroui-primary-900": "color.primary.900",
|
||||
|
||||
"--heroui-secondary-500": "color.secondary.500",
|
||||
"--heroui-success-500": "color.success.500",
|
||||
"--heroui-warning-500": "color.warning.500",
|
||||
"--heroui-danger-500": "color.danger.500",
|
||||
|
||||
# Content layers → Neutral scale
|
||||
"--heroui-content1": "color.neutral.50",
|
||||
"--heroui-content2": "color.neutral.100",
|
||||
"--heroui-content3": "color.neutral.200",
|
||||
"--heroui-content4": "color.neutral.300",
|
||||
|
||||
# Layout tokens
|
||||
"--heroui-radius-small": "radius.sm",
|
||||
"--heroui-radius-medium": "radius.md",
|
||||
"--heroui-radius-large": "radius.lg",
|
||||
|
||||
"--heroui-shadow-small": "shadow.sm",
|
||||
"--heroui-shadow-medium": "shadow.md",
|
||||
"--heroui-shadow-large": "shadow.lg",
|
||||
|
||||
# Typography
|
||||
"--heroui-font-size-tiny": "typography.fontSize.xs",
|
||||
"--heroui-font-size-small": "typography.fontSize.sm",
|
||||
"--heroui-font-size-medium": "typography.fontSize.base",
|
||||
"--heroui-font-size-large": "typography.fontSize.lg",
|
||||
|
||||
# Spacing
|
||||
"--heroui-spacing-unit": "spacing.unit",
|
||||
},
|
||||
@@ -248,7 +251,7 @@ def create_heroui_translation():
|
||||
"Button": "Button", # HeroUI Button → DSS Button
|
||||
"Card": "Card",
|
||||
"Input": "Input",
|
||||
}
|
||||
},
|
||||
},
|
||||
"custom_props": {
|
||||
# HeroUI-specific that don't map to DSS core
|
||||
@@ -257,14 +260,14 @@ def create_heroui_translation():
|
||||
"notes": [
|
||||
"HeroUI uses numeric scales similar to DSS - easy mapping",
|
||||
"Content layers (1-4) map to neutral scale",
|
||||
"Component mapping is mostly 1:1"
|
||||
]
|
||||
"Component mapping is mostly 1:1",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def create_shadcn_translation():
|
||||
"""
|
||||
Translation dictionary: shadcn → DSS Canonical
|
||||
Translation dictionary: shadcn → DSS Canonical.
|
||||
|
||||
shadcn uses semantic naming (primary, secondary, muted) without scales.
|
||||
We map to the 500 (default) value in DSS scales.
|
||||
@@ -280,31 +283,22 @@ def create_shadcn_translation():
|
||||
# Semantic colors → DSS scale defaults
|
||||
"--background": "color.neutral.50",
|
||||
"--foreground": "color.neutral.900",
|
||||
|
||||
"--primary": "color.primary.500",
|
||||
"--primary-foreground": "color.primary.50",
|
||||
|
||||
"--secondary": "color.secondary.500",
|
||||
"--secondary-foreground": "color.secondary.50",
|
||||
|
||||
"--muted": "color.neutral.200",
|
||||
"--muted-foreground": "color.neutral.600",
|
||||
|
||||
"--accent": "color.accent.500",
|
||||
"--accent-foreground": "color.accent.50",
|
||||
|
||||
"--destructive": "color.danger.500",
|
||||
|
||||
"--card": "color.neutral.50",
|
||||
"--card-foreground": "color.neutral.900",
|
||||
|
||||
"--popover": "color.neutral.50",
|
||||
"--popover-foreground": "color.neutral.900",
|
||||
|
||||
"--border": "color.neutral.200",
|
||||
"--input": "color.neutral.200",
|
||||
"--ring": "color.primary.500",
|
||||
|
||||
# Layout
|
||||
"--radius": "radius.md",
|
||||
},
|
||||
@@ -315,7 +309,7 @@ def create_shadcn_translation():
|
||||
"Input": "Input",
|
||||
"Dialog": "Modal",
|
||||
"Popover": "Popover",
|
||||
}
|
||||
},
|
||||
},
|
||||
"custom_props": {
|
||||
# shadcn-specific that don't exist in DSS
|
||||
@@ -330,14 +324,14 @@ def create_shadcn_translation():
|
||||
"shadcn is HEADLESS - no numeric color scales",
|
||||
"Semantic names map to 500 (default) DSS values",
|
||||
"foreground variants map to contrast colors (50)",
|
||||
"Chart colors are shadcn-specific custom props"
|
||||
]
|
||||
"Chart colors are shadcn-specific custom props",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def create_legacy_translation():
|
||||
"""
|
||||
Translation dictionary: Legacy Corporate → DSS Canonical
|
||||
Translation dictionary: Legacy Corporate → DSS Canonical.
|
||||
|
||||
Messy legacy code with inconsistent naming needs careful mapping.
|
||||
"""
|
||||
@@ -352,23 +346,19 @@ def create_legacy_translation():
|
||||
"--brand-dark-blue": "color.primary.700",
|
||||
"--brand-light": "color.primary.100",
|
||||
"--brandAccent": "color.warning.500", # camelCase → DSS
|
||||
|
||||
# Button colors → Component tokens
|
||||
"--btn-primary-bg": "color.primary.500",
|
||||
"--btn-primary-text": "color.neutral.50",
|
||||
"--btn-secondary-bg": "color.neutral.100",
|
||||
|
||||
# Spacing chaos → DSS order
|
||||
"--space-xs": "spacing.xs",
|
||||
"--space-sm": "spacing.sm",
|
||||
"--spacing-md": "spacing.md",
|
||||
"--SPACING_LG": "spacing.lg",
|
||||
|
||||
# Typography normalization
|
||||
"--font-base": "typography.fontSize.base",
|
||||
"--fontSize-lg": "typography.fontSize.lg",
|
||||
"--text-xl": "typography.fontSize.xl",
|
||||
|
||||
# Radius normalization
|
||||
"--rounded": "radius.sm",
|
||||
"--border-radius-md": "radius.md",
|
||||
@@ -379,7 +369,7 @@ def create_legacy_translation():
|
||||
".btn-secondary": "Button[variant=secondary]",
|
||||
".card-wrapper": "Card",
|
||||
".input-field": "Input",
|
||||
}
|
||||
},
|
||||
},
|
||||
"custom_props": {
|
||||
# ACME-specific branding that extends DSS
|
||||
@@ -389,13 +379,13 @@ def create_legacy_translation():
|
||||
"validation_warnings": [
|
||||
"Inconsistent spacing prefixes detected",
|
||||
"Mixed case conventions found",
|
||||
"Some values may need manual review"
|
||||
"Some values may need manual review",
|
||||
],
|
||||
"notes": [
|
||||
"Legacy system had 4 different naming conventions",
|
||||
"All mapped to DSS canonical structure",
|
||||
"Brand-specific colors isolated in custom_props"
|
||||
]
|
||||
"Brand-specific colors isolated in custom_props",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -403,15 +393,16 @@ def create_legacy_translation():
|
||||
# MERGE DEMONSTRATIONS
|
||||
# =============================================================================
|
||||
|
||||
|
||||
async def demonstrate_merge_heroui_shadcn():
|
||||
"""
|
||||
CASE: Merge HeroUI and shadcn tokens into DSS canonical structure.
|
||||
|
||||
This demonstrates how two different atomic structures become one.
|
||||
"""
|
||||
print("\n" + "="*70)
|
||||
print("\n" + "=" * 70)
|
||||
print("MERGE CASE: HeroUI + shadcn → DSS Canonical")
|
||||
print("="*70)
|
||||
print("=" * 70)
|
||||
|
||||
css_source = CSSTokenSource()
|
||||
|
||||
@@ -441,9 +432,9 @@ async def demonstrate_merge_heroui_shadcn():
|
||||
print(f" Resolution: {conflict.resolution}")
|
||||
|
||||
# Demonstrate atomic structure difference
|
||||
print("\n" + "-"*70)
|
||||
print("\n" + "-" * 70)
|
||||
print("ATOMIC STRUCTURE COMPARISON:")
|
||||
print("-"*70)
|
||||
print("-" * 70)
|
||||
|
||||
print("\n🎨 HeroUI (Numeric Scale System):")
|
||||
print(" Uses: --heroui-primary-{50-900}")
|
||||
@@ -468,9 +459,9 @@ async def demonstrate_merge_with_legacy():
|
||||
|
||||
Shows how messy legacy code gets normalized.
|
||||
"""
|
||||
print("\n" + "="*70)
|
||||
print("\n" + "=" * 70)
|
||||
print("MERGE CASE: Legacy Corporate → DSS Canonical")
|
||||
print("="*70)
|
||||
print("=" * 70)
|
||||
|
||||
css_source = CSSTokenSource()
|
||||
|
||||
@@ -499,12 +490,10 @@ async def demonstrate_merge_with_legacy():
|
||||
|
||||
|
||||
async def demonstrate_conflict_strategies():
|
||||
"""
|
||||
CASE: Show different merge strategies and their outcomes.
|
||||
"""
|
||||
print("\n" + "="*70)
|
||||
"""CASE: Show different merge strategies and their outcomes."""
|
||||
print("\n" + "=" * 70)
|
||||
print("MERGE STRATEGIES COMPARISON")
|
||||
print("="*70)
|
||||
print("=" * 70)
|
||||
|
||||
css_source = CSSTokenSource()
|
||||
|
||||
@@ -538,8 +527,7 @@ async def demonstrate_conflict_strategies():
|
||||
result = merger.merge([collection_a, collection_b])
|
||||
|
||||
primary_token = next(
|
||||
(t for t in result.collection.tokens if 'primary' in t.name.lower()),
|
||||
None
|
||||
(t for t in result.collection.tokens if "primary" in t.name.lower()), None
|
||||
)
|
||||
|
||||
print(f"\n📋 {strategy.value}: {description}")
|
||||
@@ -551,10 +539,10 @@ async def demonstrate_conflict_strategies():
|
||||
|
||||
async def main():
|
||||
"""Run all merge demonstrations."""
|
||||
print("\n" + "="*70)
|
||||
print("\n" + "=" * 70)
|
||||
print("DSS MERGE CASE EXAMPLES")
|
||||
print("Demonstrating Multi-Source Token Ingestion")
|
||||
print("="*70)
|
||||
print("=" * 70)
|
||||
|
||||
# Run demonstrations
|
||||
await demonstrate_merge_heroui_shadcn()
|
||||
@@ -562,11 +550,12 @@ async def main():
|
||||
await demonstrate_conflict_strategies()
|
||||
|
||||
# Summary
|
||||
print("\n" + "="*70)
|
||||
print("\n" + "=" * 70)
|
||||
print("SUMMARY: ATOMIC STRUCTURE DIFFERENCES")
|
||||
print("="*70)
|
||||
print("=" * 70)
|
||||
|
||||
print("""
|
||||
print(
|
||||
"""
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ATOMIC STRUCTURE COMPARISON │
|
||||
├─────────────────┬──────────────────────┬────────────────────────────┤
|
||||
@@ -588,9 +577,11 @@ async def main():
|
||||
│ DSS Mapping │ Direct 1:1 │ Expand to scales │
|
||||
│ │ (strip prefix) │ (500 = default) │
|
||||
└─────────────────┴──────────────────────┴────────────────────────────┘
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
print("""
|
||||
print(
|
||||
"""
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ DSS TRANSLATION APPROACH │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
@@ -606,7 +597,8 @@ async def main():
|
||||
│ │ (IMMUTABLE) │ │
|
||||
│ │ │ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user