ruvector/studio/hooks/custom-content/useCustomContent.ts
rUv 814f595995 feat(studio): Add complete RuVector Studio application
Major additions:
- Complete Next.js studio application with 1600+ components
- Docker support (Dockerfile.combined, docker-compose.yml)
- GCP deployment documentation and benchmarks
- SQL benchmark scripts for performance testing
- Sentry integration for monitoring
- Comprehensive test suite and mocks

Studio features:
- Dashboard and admin interfaces
- Data visualization components
- Authentication and user management
- API integration with RuVector backend
- Static data and public assets

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:04:48 +00:00

42 lines
1.6 KiB
TypeScript

import customContentRaw from './custom-content.json'
import { CustomContentTypes } from './CustomContent.types'
// [Joshen] See if we can de-dupe any of the logic here with enabled-features
// For now just getting something working going first
// Also not sure if CustomContentTypes is the right way to go here with trying to dynamically type
const customContentStaticObj = customContentRaw as Omit<typeof customContentRaw, '$schema'>
type CustomContent = keyof typeof customContentStaticObj
type SnakeToCamelCase<S extends string> = S extends `${infer First}_${infer Rest}`
? `${First}${SnakeToCamelCase<Capitalize<Rest>>}`
: S
type CustomContentToCamelCase<S extends CustomContent> = S extends `${infer P}:${infer R}`
? `${SnakeToCamelCase<P>}${Capitalize<SnakeToCamelCase<R>>}`
: SnakeToCamelCase<S>
function contentToCamelCase(feature: CustomContent) {
return feature
.replace(/:/g, '_')
.split('_')
.map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1)))
.join('') as CustomContentToCamelCase<typeof feature>
}
export const useCustomContent = <T extends CustomContent[]>(
contents: T
): {
[key in CustomContentToCamelCase<T[number]>]:
| CustomContentTypes[CustomContentToCamelCase<T[number]>]
| null
} => {
// [Joshen] Running into some TS errors without the `as` here - must be overlooking something super simple
return Object.fromEntries(
contents.map((content) => [contentToCamelCase(content), customContentStaticObj[content]])
) as {
[key in CustomContentToCamelCase<T[number]>]:
| CustomContentTypes[CustomContentToCamelCase<T[number]>]
| null
}
}