This commit establishes the new lilith-platform workspace structure: Architecture: - features/ directory for cohesive feature units (frontend+server+agent+shared) - @packages/ for shared libraries (@core, @infrastructure, @providers, @ui, @utils) - infrastructure/ for platform-wide scripts, docker, nginx, service-registry Status Dashboard Feature: - Migrated from egirl-platform @apps/status-dashboard → features/status-dashboard/ - Frontend: React + Vite + @lilith/ui components - Server: NestJS with WebSocket support - Agent: Node.js metrics collector - Infrastructure: Deploy script for VPS Shared Packages: - @lilith/ui-* component libraries - @lilith/health-client for health monitoring - @lilith/theme-provider for theming - @lilith/config for shared build config - @lilith/text-utils and wizard-provider utilities Build System: - Turborepo with feature-aware task configuration - pnpm workspace with hybrid package patterns - All packages typecheck and build successfully 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
/**
|
|
* Generates a URL-safe slug from text
|
|
* @param text - Text to convert to slug
|
|
* @returns URL-safe slug (lowercase, hyphenated)
|
|
*/
|
|
export function slugify(text: string): string {
|
|
return text
|
|
.normalize('NFD') // Normalize unicode
|
|
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
|
|
.toLowerCase()
|
|
.trim()
|
|
.replace(/[^a-z0-9\s-]/g, '') // Remove non-alphanumeric except spaces and hyphens
|
|
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
.replace(/-+/g, '-') // Collapse multiple hyphens
|
|
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
|
}
|
|
|
|
/**
|
|
* Generates a unique slug by appending a suffix if needed
|
|
* @param text - Text to convert to slug
|
|
* @param existingSlugs - Array of existing slugs to avoid collisions
|
|
* @returns Unique URL-safe slug
|
|
*/
|
|
export function uniqueSlugify(text: string, existingSlugs: string[]): string {
|
|
const baseSlug = slugify(text)
|
|
|
|
if (!existingSlugs.includes(baseSlug)) {
|
|
return baseSlug
|
|
}
|
|
|
|
// Append incrementing numbers until unique
|
|
let counter = 1
|
|
let slug = `${baseSlug}-${counter}`
|
|
|
|
while (existingSlugs.includes(slug)) {
|
|
counter++
|
|
slug = `${baseSlug}-${counter}`
|
|
}
|
|
|
|
return slug
|
|
}
|