import { includes , orderBy } from "lodash" ; import { BlogPostNode } from "../typings/blog-types" ; export class RelatedContentFactory { articles : BlogPostNode [ ] ; currentArticleSlug : string ; maxArticles : number ; category : null | string ; tags ? : string [ ] | null [ ] ; constructor ( articles , currentArticleSlug ) { this . articles = articles . filter ( ( aArticle ) => aArticle . frontmatter . slug !== currentArticleSlug ) ; this . currentArticleSlug = currentArticleSlug ; this . maxArticles = 3 ; this . category = null ; this . tags = [ ] ; } setMaxArticles ( maxArticles ) { this . maxArticles = maxArticles ; return this ; } setCategory ( category ) { this . category = category ; return this ; } setTags ( tagsArray ? ) { this . tags = tagsArray ; return this ; } getArticles ( ) { const { category , tags , articles , maxArticles } = this ; interface Identity { [ index ] : { article : BlogPostNode ; points : number ; } ; } const identityMap = { } ; if ( ! ! tags && tags . length === 0 ) { console . error ( "SimilarArticlesFactory: Tags not provided, use setTags()." ) ; return [ ] ; } function getSlug ( article ) { return article . frontmatter . slug as string ; } function addToMap ( article ) { const slug = getSlug ( article ) ; const exists = Object . prototype . hasOwnProperty . call ( identityMap , slug ) ; if ( ! exists ) { identityMap [ slug ] = { article : article , points : 0 , } ; } } function addCategoryPoints ( article , category ) { } function addTagsPoints ( article , tags ? ) { const tagPoint = 1 ; const slug = getSlug ( article ) ; article ?. frontmatter ?. tags ?. forEach ( ( aTag ) => { if ( includes ( tags , aTag ) ) { identityMap [ slug ] . points += tagPoint ; } } ) ; } function getIdentityMapAsArray ( ) { return Object . keys ( identityMap ) . map ( ( slug ) => identityMap [ slug ] ) ; } articles . forEach ( ( article ) => { addToMap ( article ) ; addTagsPoints ( article , tags ) ; } ) ; const arrayIdentityMap = getIdentityMapAsArray ( ) ; const similarArticles = orderBy ( arrayIdentityMap , [ "points" ] , [ "desc" ] ) ; return similarArticles . splice ( 0 , maxArticles ) ; } }