import { getEntityGenerator, Query, QueryTable, TranslateToObject, UpsertTable, CreateTableIfNotExists, DeleteEntity } from '@feedyou/utils' import { User, TableUser, TableUserRaw, Domain, TableDomain, TableDomainRaw } from './types' const USERS_TABLE = 'User' const DOMAINS_TABLE = 'Domain' export function generateRandomId(): string { return Math.random() //if Math.random() returns 0.0, 0.5, etc., then output of this function is '' .toString(36) .substring(7) } export async function userExists(rowKey: string, email: string) { const result = await TranslateToObject( await QueryTable(USERS_TABLE, Query().where('Email eq ? or RowKey eq ?', email, rowKey)) ) return result && result.length > 0 } export async function saveUserToStorage(user: User) { if (await userExists(user.id, user.email)) { throw 'User ' + user.name + ' with email ' + user.email + ' already exists.' } const entityGenerator = getEntityGenerator() const entity = { PartitionKey: entityGenerator.String(user.source), RowKey: entityGenerator.String(user.id), Email: entityGenerator.String(user.email), Name: entityGenerator.String(user.name), Role: entityGenerator.String(user.role) } await CreateTableIfNotExists(USERS_TABLE) await UpsertTable(USERS_TABLE, entity, 'replace') return user } export async function getUsersFromStorage() { const users = await TranslateToObject(await QueryTable(USERS_TABLE)) return users.map(user => { return entityToUser(user) }) } function entityToUser(entity: TableUser) { const user: User = { id: entity.RowKey, source: entity.PartitionKey, email: entity.Email, role: entity.Role, name: entity.Name } Object.keys(user).forEach(key => user[key] === undefined && delete user[key]) return user } export async function updateUserInStorage(userId: string, user: User) { if (user) { const originalUser = await QueryTable( USERS_TABLE, Query() .top(1) .where('RowKey eq ?', String(userId)) ) if (originalUser && originalUser.entries && originalUser.entries.length === 1) { const entityGenerator = getEntityGenerator() let entity = originalUser.entries[0] if (user.email) entity.Email = entityGenerator.String(user.email) if (user.name) entity.Name = entityGenerator.String(user.name) if (user.role) entity.Role = entityGenerator.String(user.role) Object.keys(entity).forEach(key => (entity[key] === undefined ? delete entity[key] : '')) await UpsertTable(USERS_TABLE, entity, 'replace') const entityObject = await TranslateToObject({ entries: [entity] }) const updatedUser = entityToUser(entityObject[0]) return updatedUser } else { throw `User ${userId} doesn't exist` } } else { throw 'Request body is empty!' } } export async function deleteUserFromStorage(userId: string) { let originalUser: TableUser[] try { originalUser = await TranslateToObject( await QueryTable( USERS_TABLE, Query() .top(1) .where('RowKey eq ?', String(userId)) ) ) if (!(originalUser && originalUser.length >= 1 && originalUser[0].PartitionKey)) { throw 'no user found' } } catch (err) { return `User ${userId} doesn't exist` } try { return await DeleteEntity(USERS_TABLE, originalUser[0].PartitionKey, userId) } catch (err) { throw new Error(`Could not delete user ${userId}: ${err}`) } } export async function saveDomainToStorage(domain: Domain) { const entityGenerator = getEntityGenerator() const entity = { PartitionKey: entityGenerator.String(domain.domain), RowKey: entityGenerator.String(generateRandomId()), Role: entityGenerator.String(domain.role), Name: entityGenerator.String(domain.name) } await CreateTableIfNotExists(DOMAINS_TABLE) await UpsertTable(DOMAINS_TABLE, entity, 'replace') return domain } export async function updateDomainToStorage(domainId: string, domain: Domain) { if (domain) { const originalDomain = await QueryTable( DOMAINS_TABLE, Query() .top(1) .where('PartitionKey eq ?', String(domainId)) ) if (originalDomain && originalDomain.entries && originalDomain.entries.length === 1) { const entityGenerator = getEntityGenerator() let entity = originalDomain.entries[0] if (domain.name) entity.Name = entityGenerator.String(domain.name) if (domain.role) entity.Role = entityGenerator.String(domain.role) Object.keys(entity).forEach(key => (entity[key] === undefined ? delete entity[key] : '')) await UpsertTable(DOMAINS_TABLE, entity, 'replace') const entityObject = await TranslateToObject({ entries: [entity] }) const updatedUser = entityToDomain(entityObject[0]) return updatedUser } else { throw `Domain ${domainId} doesn't exist` } } else { throw 'Domain body is empty!' } } export async function deleteDomainFromStorage(domainId: string) { let originalDomain: TableDomain[] try { originalDomain = TranslateToObject( await QueryTable( DOMAINS_TABLE, Query() .top(1) .where('PartitionKey eq ?', String(domainId)) ) ) if (!(originalDomain && originalDomain.length >= 1 && originalDomain[0].RowKey)) { throw 'no domain found' } } catch (err) { return `Domain ${domainId} doesn't exist` } try { return await DeleteEntity(DOMAINS_TABLE, domainId, originalDomain[0].RowKey) } catch (err) { throw new Error(`Could not delete domain ${domainId}: ${err}`) } } export async function getDomainsFromStorage() { const users = await TranslateToObject(await QueryTable(DOMAINS_TABLE)) return users.map(user => { return entityToDomain(user) }) } function entityToDomain(entity: TableDomain) { const domain: Domain = { domain: entity.PartitionKey, role: entity.Role, name: entity.Name } Object.keys(domain).forEach(key => domain[key] === undefined && delete domain[key]) return domain }