useCustomContent.ts42 lines · main
1import customContentRaw from './custom-content.json'
2import { CustomContentTypes } from './CustomContent.types'
3
4// [Joshen] See if we can de-dupe any of the logic here with enabled-features
5// For now just getting something working going first
6// Also not sure if CustomContentTypes is the right way to go here with trying to dynamically type
7
8const customContentStaticObj = customContentRaw as Omit<typeof customContentRaw, '$schema'>
9type CustomContent = keyof typeof customContentStaticObj
10
11type SnakeToCamelCase<S extends string> = S extends `${infer First}_${infer Rest}`
12 ? `${First}${SnakeToCamelCase<Capitalize<Rest>>}`
13 : S
14
15type CustomContentToCamelCase<S extends CustomContent> = S extends `${infer P}:${infer R}`
16 ? `${SnakeToCamelCase<P>}${Capitalize<SnakeToCamelCase<R>>}`
17 : SnakeToCamelCase<S>
18
19function contentToCamelCase(feature: CustomContent) {
20 return feature
21 .replace(/:/g, '_')
22 .split('_')
23 .map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1)))
24 .join('') as CustomContentToCamelCase<typeof feature>
25}
26
27export const useCustomContent = <T extends CustomContent[]>(
28 contents: T
29): {
30 [key in CustomContentToCamelCase<T[number]>]:
31 | CustomContentTypes[CustomContentToCamelCase<T[number]>]
32 | null
33} => {
34 // [Joshen] Running into some TS errors without the `as` here - must be overlooking something super simple
35 return Object.fromEntries(
36 contents.map((content) => [contentToCamelCase(content), customContentStaticObj[content]])
37 ) as {
38 [key in CustomContentToCamelCase<T[number]>]:
39 | CustomContentTypes[CustomContentToCamelCase<T[number]>]
40 | null
41 }
42}