import {Model, Connection} from 'mongoose'; import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException} from '@nestjs/common'; import {InjectConnection} from '@nestjs/mongoose'; import {Store, StoreRequest, StoreSchema} from './store.schema'; import {DB_TEST_NAME, DB_NAME, COLLECTION_STORE} from 'src/consts'; const validateModel = async (store: Store) => { try { await store.validate(); } catch (e) { throw new BadGatewayException(e); } }; @Injectable() export class StoreService { constructor( @InjectConnection(DB_NAME) private dbConnection: Connection, @InjectConnection(DB_TEST_NAME) private dbTestConnection: Connection, ) {} storeModel(api: string): Model { if (api === DB_TEST_NAME) { return this.dbTestConnection.model(COLLECTION_STORE, StoreSchema); } return this.dbConnection.model(COLLECTION_STORE, StoreSchema); } async findAll(api: string): Promise { return this.storeModel(api).find().exec(); } async create(api: string, store: StoreRequest): Promise { const searchStore = await this.storeModel(api).findOne({key: store.key}); if (searchStore) { throw new ConflictException(`Api key "${store.key}" is already taken`); } const createdStore = new (this.storeModel(api))(store); try { await validateModel(createdStore); } catch (e) { if (e?.message?.includes('validation failed')) { throw new BadRequestException(e.message); } throw e; } const savedStore = await createdStore.save(); if (!Object.keys(savedStore.value).length) { await savedStore.updateOne(store); } return savedStore; } async update(api: string, {author, ...omitProps}: StoreRequest): Promise { const searchStore = await this.findOne(api, omitProps.key); if (searchStore) { const store = { ...omitProps, author: searchStore.author, }; const updateStore = new (this.storeModel(api))(store); try { await validateModel(updateStore); } catch (e) { if (e?.message?.includes('validation failed')) { throw new BadRequestException(e.message); } throw e; } await searchStore.updateOne({ ...store, author: searchStore.author, }); return updateStore; } throw new NotFoundException(`Not found api key "${omitProps.key}"`); } async findOne(api: string, key: string): Promise { const searchStore = await this.storeModel(api).findOne({key}); if (!searchStore) { throw new NotFoundException(`Not found api key "${key}"`); } return searchStore; } async removeOne(api: string, key: string): Promise { const searchStore = await this.findOne(api, key); if (searchStore) { await this.storeModel(api).deleteOne({key}); return searchStore; } throw new NotFoundException(`Not found api key "${key}"`); } }