import type { Model } from 'mongoose' ; export type getIndexesFromModelOpts = { extractCompound ? : boolean ; skipSpecificIndexes ? : boolean ; } ; export type IndexT = { [ fieldName ] : any ; } ; function isSpecificIndex ( idx ) { let hasSpecialIndex = false ; Object . keys ( idx ) . forEach ( ( k ) => { if ( typeof idx [ k ] !== 'number' && typeof idx [ k ] !== 'boolean' ) { hasSpecialIndex = true ; } } ) ; return hasSpecialIndex ; } export function getIndexesFromModel ( mongooseModel , opts = { } ) { const extractCompound = opts . extractCompound === undefined ? true : Boolean ( opts . extractCompound ) ; const skipSpecificIndexes = opts . skipSpecificIndexes === undefined ? true : Boolean ( opts . skipSpecificIndexes ) ; const indexedFields = [ ] ; if ( mongooseModel . schema . paths . _id ) { indexedFields . push ( { _id : 1 } ) ; } Object . keys ( mongooseModel . schema . paths ) . forEach ( ( name ) => { if ( ( mongooseModel . schema . paths [ name ] as any ) . _index ) { indexedFields . push ( { [ name ] : 1 } ) ; } } ) ; if ( Array . isArray ( ( mongooseModel . schema as any ) . _indexes ) ) { ( mongooseModel . schema as any ) . _indexes . forEach ( ( idxData ) => { const partialIndexes = { } as Record < string , any > ; const idxFields = idxData [ 0 ] ; if ( ! skipSpecificIndexes || ! isSpecificIndex ( idxFields ) ) { if ( ! extractCompound ) { indexedFields . push ( idxFields ) ; } else { Object . keys ( idxFields ) . forEach ( ( fieldName ) => { partialIndexes [ fieldName ] = idxFields [ fieldName ] ; indexedFields . push ( { ... partialIndexes } ) ; } ) ; } } } ) ; } const tmp = [ ] ; const result = indexedFields . filter ( ( val ) => { const asString = JSON . stringify ( val ) ; if ( tmp . indexOf ( asString ) > - 1 ) return false ; tmp . push ( asString ) ; return true ; } ) ; return result ; } export function getUniqueIndexes ( mongooseModel ) { const indexedFields = [ ] ; if ( mongooseModel . schema . paths . _id ) { indexedFields . push ( { _id : 1 } ) ; } Object . keys ( mongooseModel . schema . paths ) . forEach ( ( name ) => { if ( ( mongooseModel . schema . paths [ name ] as any ) ?. _index ?. unique ) { indexedFields . push ( { [ name ] : 1 } ) ; } } ) ; if ( Array . isArray ( ( mongooseModel . schema as any ) . _indexes ) ) { ( mongooseModel . schema as any ) . _indexes . forEach ( ( idxData ) => { const idxFields = idxData [ 0 ] ; const idxCfg = idxData [ 1 ] ; if ( idxCfg . unique && ! isSpecificIndex ( idxFields ) ) { indexedFields . push ( idxFields ) ; } } ) ; } return indexedFields ; } export type extendByReversedIndexesOpts = { reversedFirst ? : boolean ; } ; export function extendByReversedIndexes ( indexes , opts = { } ) { const reversedFirst = opts . reversedFirst === undefined ? false : Boolean ( opts . reversedFirst ) ; const result = [ ] ; indexes . forEach ( ( indexObj ) => { let hasSpecificIndex = false ; const reversedIndexObj = { ... indexObj } ; Object . keys ( reversedIndexObj ) . forEach ( ( f ) => { if ( reversedIndexObj [ f ] === 1 ) reversedIndexObj [ f ] = - 1 ; else if ( reversedIndexObj [ f ] === - 1 ) reversedIndexObj [ f ] = 1 ; else hasSpecificIndex = true ; } ) ; if ( reversedFirst ) { if ( ! hasSpecificIndex ) { result . push ( reversedIndexObj ) ; } result . push ( indexObj ) ; } else { result . push ( indexObj ) ; if ( ! hasSpecificIndex ) { result . push ( reversedIndexObj ) ; } } } ) ; return result ; } export function getIndexedFieldNamesForGraphQL ( model ) { const indexes = getIndexesFromModel ( model ) ; const fieldNames = [ ] ; indexes . forEach ( ( indexData ) => { const keys = Object . keys ( indexData ) ; const clearedName = keys [ 0 ] . replace ( /[^_a-zA-Z0-9]/i , '__' ) ; fieldNames . push ( clearedName ) ; } ) ; const uniqueNames = [ ] ; const result = fieldNames . filter ( ( val ) => { if ( uniqueNames . indexOf ( val ) > - 1 ) return false ; uniqueNames . push ( val ) ; return true ; } ) ; return result ; }