@wepublish/api-db-mongodb
Version:
We.publish Database adapter for mongoDB
96 lines (81 loc) • 2.94 kB
text/typescript
import {
DBNavigationAdapter,
UpdateNavigationArgs,
OptionalNavigation,
DeleteNavigationArgs,
Navigation,
CreateNavigationArgs
} from '@wepublish/api'
import {Collection, Db, MongoError} from 'mongodb'
import {CollectionName, DBNavigation} from './schema'
import {MongoErrorCode} from '../utility'
export class MongoDBNavigationAdapter implements DBNavigationAdapter {
private navigations: Collection<DBNavigation>
constructor(db: Db) {
this.navigations = db.collection(CollectionName.Navigations)
}
async createNavigation({input}: CreateNavigationArgs): Promise<Navigation> {
try {
const {ops} = await this.navigations.insertOne({
createdAt: new Date(),
modifiedAt: new Date(),
name: input.name,
key: input.key,
links: input.links
})
const {_id: id, ...navigation} = ops[0]
return {id, ...navigation}
} catch (err) {
if (err instanceof MongoError && err.code === MongoErrorCode.DuplicateKey) {
throw new Error('"key" already exists!')
}
throw err
}
}
async updateNavigation({id, input}: UpdateNavigationArgs): Promise<OptionalNavigation> {
try {
const {value} = await this.navigations.findOneAndUpdate(
{_id: id},
{
$set: {
modifiedAt: new Date(),
name: input.name,
key: input.key,
links: input.links
}
},
{returnOriginal: false}
)
if (!value) return null
const {_id: outID, ...navigation} = value
return {id: outID, ...navigation}
} catch (err) {
if (err instanceof MongoError && err.code === MongoErrorCode.DuplicateKey) {
throw new Error('"key" already exists!')
}
throw err
}
}
async deleteNavigation({id}: DeleteNavigationArgs): Promise<string | null> {
const {deletedCount} = await this.navigations.deleteOne({_id: id})
return deletedCount !== 0 ? id : null
}
async getNavigations(): Promise<Navigation[]> {
const navigations = await this.navigations.find().sort({createdAt: -1}).toArray()
return navigations.map(({_id: id, ...data}) => ({id, ...data}))
}
async getNavigationsByID(ids: readonly string[]): Promise<OptionalNavigation[]> {
const navigations = await this.navigations.find({_id: {$in: ids}}).toArray()
const navigationMap = Object.fromEntries(
navigations.map(({_id: id, ...navigation}) => [id, {id, ...navigation}])
)
return ids.map(id => navigationMap[id] ?? null)
}
async getNavigationsByKey(keys: readonly string[]): Promise<OptionalNavigation[]> {
const navigations = await this.navigations.find({key: {$in: keys as string[]}}).toArray()
const navigationMap = Object.fromEntries(
navigations.map(({_id: id, ...navigation}) => [navigation.key, {id, ...navigation}])
)
return keys.map(key => navigationMap[key] ?? null)
}
}