Skip to content

Instantly share code, notes, and snippets.

@prxg22
Created February 5, 2024 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prxg22/a852c7d806a87ccf656263aea25dd6f8 to your computer and use it in GitHub Desktop.
Save prxg22/a852c7d806a87ccf656263aea25dd6f8 to your computer and use it in GitHub Desktop.
Graph db types
export type DBGraph = { [e: string]: { [k: string]: any } }
export type DBGraphRelations<G extends DBGraph = DBGraph> = {
[s in StringKeys<G>]: { [t in StringKeys<G>]?: { [k: string]: any } }
}
export type DBGraphEntityMockRelation<
G extends DBGraph,
E extends StringKeys<G>,
> = {
[S in E]: {
[T in E]?: G[E]
}
}
export type DBRelation<T> = (T extends undefined ? unknown : T) & {
source: string
target: string
createAt: number
updatedAt: number
}
export type DBEntity<T> = DBRelation<T> & {
id: string
}
export type DBEntityFunctionsNames<T extends string> =
| `get${Capitalize<T>}`
| `create${Capitalize<T>}`
| `update${Capitalize<T>}`
| `delete${Capitalize<T>}`
| `get${Capitalize<T>}AllRelations`
export type DBRelationsFunctionsNames<S extends string, T extends string> =
| `create${Capitalize<S>}${Capitalize<T>}Relation`
| `delete${Capitalize<S>}${Capitalize<T>}Relation`
| `update${Capitalize<S>}${Capitalize<T>}Relation`
| `get${Capitalize<S>}${Capitalize<T>}Relation`
| `get${Capitalize<S>}Children${Capitalize<T>}s`
| `get${Capitalize<S>}Parent${Capitalize<T>}s`
| `get${Capitalize<S>}RelationsTo${Capitalize<T>}s`
| `get${Capitalize<S>}RelationsFrom${Capitalize<T>}s`
export type DBEntityFunctions<T extends DBGraph> = UnionToIntersection<
{
[K in StringKeys<T>]: {
[P in DBEntityFunctionsNames<K>]: P extends `get${Capitalize<K>}`
? (id: string) => Promise<DBEntity<T[K]>>
: P extends `update${Capitalize<K>}`
? (id: string, data: Partial<T[K]>) => Promise<DBEntity<T[K]>>
: P extends `create${Capitalize<K>}`
? CreateTypedEntity<T, K>
: P extends `delete${Capitalize<K>}`
? (id: string) => Promise<void>
: P extends `get${Capitalize<K>}AllRelations`
? GetTypedEntity<T, K>
: never
}
}[StringKeys<T>]
>
export type DBRelationsFunctions<
G extends DBGraph,
R extends Required<{ [s in StringKeys<G>]: { [t in StringKeys<G>]?: any } }>,
> = UnionToIntersection<
{
[S in StringKeys<G>]: {
[T in StringKeys<G>]: {
[L in DBRelationsFunctionsNames<
S,
T
>]: L extends `get${Capitalize<S>}Children${Capitalize<T>}s`
? (id: string) => Promise<DBEntity<G[T]>[]>
: L extends `get${Capitalize<S>}Parent${Capitalize<T>}s`
? (id: string) => Promise<DBEntity<G[T]>[]>
: L extends `get${Capitalize<S>}RelationsTo${Capitalize<T>}s`
? (id: string) => Promise<DBRelation<R[S][T]>[]>
: L extends `get${Capitalize<S>}RelationsFrom${Capitalize<T>}s`
? (id: string) => Promise<DBRelation<R[S][T]>[]>
: L extends `create${Capitalize<S>}${Capitalize<T>}Relation`
? CreateTypedRelation<G, R, S, T>
: L extends `update${Capitalize<S>}${Capitalize<T>}Relation`
? (
sourceId: string,
targetId: string,
data: Partial<R[S][T]>,
keysToDelete?: string[],
) => Promise<DBRelation<R[S][T]>>
: L extends `delete${Capitalize<S>}${Capitalize<T>}Relation`
? (sourceId: string, targetId: string) => Promise<void>
: L extends `get${Capitalize<S>}${Capitalize<T>}Relation`
? GetTypedRelation<G, R, S, T>
: never
}
}
}[StringKeys<G>][StringKeys<G>]
>
export type DBFunctions<
G extends DBGraph,
R extends { [s in StringKeys<G>]?: { [t in StringKeys<G>]?: any } },
> = DBEntityFunctions<G> & DBRelationsFunctions<G, Required<R>>
export type UnionToIntersection<U> = (
U extends any ? (k: U) => void : never
) extends (k: infer I) => void
? I
: never
export type UnionToObject<U> = {
[k in keyof U]: U[k]
}
export type StringKeys<T> = {
[P in keyof T]: P extends string ? P : never
}[keyof T]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment