import { ICollection } from "@fluidframework/server-services-core" ; import * as _ from "lodash" ; export class Collection < T > implements ICollection < T > { private readonly collection = new Array < T > ( ) ; constructor ( ) { } public aggregate ( group , options ? ) { throw new Error ( "Method Not Implemented" ) ; } public async updateMany ( filter , set , addToSet ) { throw new Error ( "Method Not Implemented" ) ; } public async distinct ( key , query ) { throw new Error ( "Method Not Implemented" ) ; } public async find ( query , sort ? ) { return this . findInternal ( query , sort ) ; } public async findAll ( ) { return this . collection ; } public findOne ( query ) { return Promise . resolve ( this . findOneInternal ( query ) ) ; } public async update ( filter , set , addToSet ) { const value = this . findOneInternal ( filter ) ; if ( ! value ) { return Promise . reject ( new Error ( "Not found" ) ) ; } _ . extend ( value , set ) ; } public async upsert ( filter , set , addToSet ) { const value = this . findOneInternal ( filter ) ; if ( ! value ) { this . collection . push ( set ) ; } _ . extend ( value , set ) ; } public async insertOne ( value ) { if ( this . findOneInternal ( value ) !== null ) { return Promise . resolve ( "existing object" ) ; } return this . insertOneInternal ( value ) ; } public async findOrCreate ( query , value ) { const existing = this . findOneInternal ( query ) ; if ( existing ) { return { value : existing , existing : true } ; } return { value : this . insertOneInternal ( value ) , existing : false } ; } public async insertMany ( values , ordered ) { values . forEach ( ( value ) => { this . collection . push ( value ) ; } ) ; } public async deleteOne ( filter ) { throw new Error ( "Method not implemented." ) ; } public async deleteMany ( filter ) { throw new Error ( "Method not implemented." ) ; } public async createIndex ( index , unique ) { return ; } private insertOneInternal ( value ) { this . collection . push ( value ) ; return value ; } private findOneInternal ( query ) { let returnValue ; if ( query . _id ) { returnValue = this . collection . find ( ( value ) => ( value as any ) . _id === query . _id ) ; } else { const found = this . findInternal ( query ) ; returnValue = found [ 0 ] ; } return returnValue === undefined ? null : returnValue ; } private findInternal ( query , sort ? ) { function getValueByKey ( propertyBag , key ) { const keys = key . split ( "." ) ; let value = propertyBag ; keys . forEach ( ( splitKey ) => { value = value [ splitKey ] ; } ) ; return value ; } const queryKeys = Object . keys ( query ) ; let filteredCollection = this . collection ; queryKeys . forEach ( ( key ) => { if ( ! query [ key ] ) { return ; } if ( query [ key ] . $gt > 0 || query [ key ] . $lt > 0 ) { if ( query [ key ] . $gt > 0 ) { filteredCollection = filteredCollection . filter ( ( value ) => getValueByKey ( value , key ) > query [ key ] . $gt ) ; } if ( query [ key ] . $lt > 0 ) { filteredCollection = filteredCollection . filter ( ( value ) => getValueByKey ( value , key ) < query [ key ] . $lt ) ; } } else { filteredCollection = filteredCollection . filter ( ( value ) => getValueByKey ( value , key ) === query [ key ] ) ; } } ) ; if ( sort && Object . keys ( sort ) . length === 1 ) { function compare ( a , b ) { const sortKey = Object . keys ( sort ) [ 0 ] ; if ( sort [ sortKey ] === 1 ) { return getValueByKey ( a , sortKey ) - getValueByKey ( b , sortKey ) ; } else { return getValueByKey ( b , sortKey ) - getValueByKey ( a , sortKey ) ; } } filteredCollection = filteredCollection . sort ( compare ) ; } return filteredCollection ; } }