[ABANDONED] API server for Flexor social network.
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.
 

118 lines
3.9 KiB

import { CosmosClient } from '@azure/cosmos'
import { Logger } from 'fastify'
import compact from 'lodash/compact'
import uniq from 'lodash/uniq'
import { DatabaseItem } from '../types'
import { containerFor, createQuerySpec, queryItems, getItem } from './database'
import { User, UserSubscription, UserBlock, Group, GroupMembership, UserItemType, GroupItemType } from '../types/collections'
export async function getUser(client: CosmosClient, id: string): Promise<User | undefined> {
const user = await getItem<User>({
container: containerFor(client, 'Users'),
id,
})
if (!user) return
const getGroup = async (id: string) => {
return await getItem<Group>({
container: containerFor(client, 'Groups'),
id,
})
}
return {
...user,
group: user.groupId ? await getGroup(user.groupId) : undefined,
}
}
export async function getUsers(client: CosmosClient, ids: string[], logger?: Logger): Promise<User[]> {
const users = await queryItems<User>({
container: containerFor(client, 'Users'),
query: createQuerySpec(
'SELECT u.id, u.name, u.imageUrl, u.coverImageUrl, u.groupId, u.created FROM Users u WHERE ARRAY_CONTAINS(@ids, u.id)',
{ ids: uniq(ids) }
),
logger,
})
const groups = await queryItems<Group>({
container: containerFor(client, 'Groups'),
query: createQuerySpec(
'SELECT g.id, g.name, g.imageUrl, g.coverImageUrl, g.iconImageUrl, g.created FROM Groups g WHERE ARRAY_CONTAINS(@ids, g.id)',
{ ids: uniq(compact(users.map(u => u.groupId))) }
),
logger,
})
return users.map(user => {
return {
...user,
group: groups.find(group => group.id === user.groupId),
groupId: undefined
}
})
}
export async function getUsersFromItems<T extends DatabaseItem>(client: CosmosClient, items: T[], logger?: Logger): Promise<User[]> {
return await getUsers(client, items.map(i => i.id), logger)
}
export async function getApprovedSubscriptions(client: CosmosClient, from: string, to: string, logger?: Logger): Promise<UserSubscription[]> {
return await queryItems<UserSubscription>({
container: containerFor(client, 'Users'),
query: createQuerySpec(
`SELECT u.id FROM Users u WHERE
u.id = @to
u.pk = @from AND
u.t = @type AND
u.pending = false`,
{ from, to, type: UserItemType.Subscription }
),
logger,
})
}
export async function getUserBlocks(client: CosmosClient, from: string, to: string[], logger?: Logger): Promise<UserBlock[]> {
return await queryItems<UserBlock>({
container: containerFor(client, 'Users'),
query: createQuerySpec(
`SELECT u.id FROM Users u WHERE
u.pk = @from
AND u.t = @type
AND ARRAY_CONTAINS(@to, u.blockedId)`,
{ from, to, type: UserItemType.Block }
),
logger,
})
}
export async function getUserMembership(client: CosmosClient, userId: string, logger?: Logger): Promise<GroupMembership | undefined> {
const user = await getItem<User>({
container: containerFor(client, 'Users'),
id: userId,
})
if (!user) return
if (!user.groupId) return
const memberships = await queryItems<GroupMembership>({
container: containerFor(client, 'Groups'),
query: createQuerySpec(
`SELECT * FROM Groups g WHERE
g.pk = @pk AND
g.t = @type AND
g.userId = @user
`,
{
pk: user.groupId,
type: GroupItemType.Membership,
user: user.id,
}
),
logger,
})
if (memberships.length > 0) return memberships[0]
}