You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.1 KiB
121 lines
3.1 KiB
import {
|
|
EntityType,
|
|
EntityStore,
|
|
Entity,
|
|
User,
|
|
Invitation,
|
|
GroupLog,
|
|
} from '../types'
|
|
|
|
import compact from 'lodash/compact'
|
|
|
|
export interface NormalizeResult {
|
|
keys: string[]
|
|
entities: EntityStore
|
|
}
|
|
|
|
function set(type: EntityType, store: EntityStore, entity?: Entity): string | undefined {
|
|
if (!entity) return
|
|
|
|
const collection = store[type] || {}
|
|
const existing = collection[entity.id] || {}
|
|
|
|
collection[entity.id] = {
|
|
...existing,
|
|
...entity,
|
|
}
|
|
|
|
store[type] = collection
|
|
return entity.id
|
|
}
|
|
|
|
function get(type: EntityType, store: EntityStore, id?: string): Entity | undefined {
|
|
if (!id) return
|
|
|
|
const collection = store[type] || {}
|
|
return collection[id]
|
|
}
|
|
|
|
export function normalize(entities: Entity[], type: EntityType): NormalizeResult {
|
|
let keys: Array<string | undefined> = []
|
|
const newStore: EntityStore = {}
|
|
|
|
switch (type) {
|
|
case EntityType.User:
|
|
keys = entities.map(entity => {
|
|
const user = entity as User
|
|
|
|
return set(type, newStore, {
|
|
...user,
|
|
group: set(EntityType.Group, newStore, user.group),
|
|
})
|
|
})
|
|
|
|
break
|
|
case EntityType.Group:
|
|
keys = entities.map(entity => set(type, newStore, entity))
|
|
break
|
|
case EntityType.Invitation:
|
|
keys = entities.map(entity => {
|
|
const invitation = entity as Invitation
|
|
|
|
return set(type, newStore, {
|
|
...invitation,
|
|
user: set(EntityType.Group, newStore, invitation.user),
|
|
})
|
|
})
|
|
|
|
break
|
|
case EntityType.Log:
|
|
keys = entities.map(entity => {
|
|
const log = entity as GroupLog
|
|
|
|
return set(type, newStore, {
|
|
...log,
|
|
user: set(EntityType.Group, newStore, log.user),
|
|
})
|
|
})
|
|
|
|
break
|
|
}
|
|
|
|
return {
|
|
keys: compact(keys),
|
|
entities: newStore,
|
|
}
|
|
}
|
|
|
|
export function denormalize(keys: string[], type: EntityType, store: EntityStore): Entity[] {
|
|
const entities = keys.map(key => {
|
|
switch (type) {
|
|
case EntityType.User:
|
|
const user = get(type, store, key)
|
|
if (!user) return
|
|
|
|
return {
|
|
...user,
|
|
group: get(EntityType.Group, store, user.group),
|
|
}
|
|
case EntityType.Group:
|
|
return get(type, store, key)
|
|
case EntityType.Invitation:
|
|
const invitation = get(type, store, key)
|
|
if (!invitation) return
|
|
|
|
return {
|
|
...invitation,
|
|
user: get(EntityType.User, store, invitation.user)
|
|
}
|
|
case EntityType.Log:
|
|
const log = get(type, store, key)
|
|
if (!log) return
|
|
|
|
return {
|
|
...log,
|
|
user: get(EntityType.User, store, log.user)
|
|
}
|
|
}
|
|
})
|
|
|
|
return compact(entities)
|
|
}
|