UNPKG

@rytass/cms-base-nestjs-module

Version:

Rytass Content Management System NestJS Base Module

111 lines (108 loc) 4.79 kB
import { Injectable, Inject } from '@nestjs/common'; import { RESOLVED_ARTICLE_REPO, RESOLVED_ARTICLE_VERSION_REPO } from '../typings/cms-base-providers.js'; import { Brackets, Repository } from 'typeorm'; import DataLoader from 'dataloader'; import { LRUCache } from 'lru-cache'; import { ArticleStage } from '../typings/article-stage.enum.js'; import { SignatureService } from '../services/signature.service.js'; import { ArticleSignatureResult } from '../typings/article-signature-result.enum.js'; function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function _ts_metadata(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } function _ts_param(paramIndex, decorator) { return function(target, key) { decorator(target, key, paramIndex); }; } class ArticleDataLoader { articleRepo; articleVersionRepo; signatureService; constructor(articleRepo, articleVersionRepo, signatureService){ this.articleRepo = articleRepo; this.articleVersionRepo = articleVersionRepo; this.signatureService = signatureService; } stageCache = new LRUCache({ ttl: 1000 * 5, ttlAutopurge: true, max: 1000 }); stageLoader = new DataLoader(async (queryArgs)=>{ const qb = this.articleVersionRepo.createQueryBuilder('versions'); qb.withDeleted(); qb.leftJoinAndSelect('versions.signatures', 'signatures'); qb.andWhere(new Brackets((subQb)=>{ queryArgs.forEach((args, index)=>{ subQb.orWhere(`versions.articleId = :id_${index} AND versions.version = :version_${index}`, { [`id_${index}`]: args.id, [`version_${index}`]: args.version }); }); return subQb; })); const versions = await qb.getMany(); const versionMap = new Map(versions.map((version)=>[ `${version.articleId}:${version.version}`, (()=>{ if (version.deletedAt) return ArticleStage.DELETED; if (version.releasedAt) { if (version.releasedAt.getTime() > Date.now()) { return ArticleStage.SCHEDULED; } return ArticleStage.RELEASED; } if (version.signatures.some((sig)=>sig.result === ArticleSignatureResult.APPROVED && sig.deletedAt === null && sig.signatureLevelId === this.signatureService.finalSignatureLevel?.id)) { return ArticleStage.VERIFIED; } if (version.submittedAt) { return ArticleStage.REVIEWING; } return ArticleStage.DRAFT; })() ])); return queryArgs.map((args)=>versionMap.get(`${args.id}:${args.version}`) ?? ArticleStage.UNKNOWN); }, { cache: true, cacheMap: this.stageCache, cacheKeyFn: (queryArgs)=>`${queryArgs.id}:${queryArgs.version}` }); categoriesLoader = new DataLoader(async (ids)=>{ const qb = this.articleRepo.createQueryBuilder('articles'); qb.leftJoinAndSelect('articles.categories', 'categories'); qb.andWhere('articles.id IN (:...ids)', { ids }); const articles = await qb.getMany(); const categoryMap = new Map(articles.map((article)=>[ article.id, article.categories ])); return ids.map((id)=>categoryMap.get(id) ?? []); }, { cache: true, cacheMap: new LRUCache({ ttl: 1000 * 60, ttlAutopurge: true, max: 1000 }) }); } ArticleDataLoader = _ts_decorate([ Injectable(), _ts_param(0, Inject(RESOLVED_ARTICLE_REPO)), _ts_param(1, Inject(RESOLVED_ARTICLE_VERSION_REPO)), _ts_metadata("design:type", Function), _ts_metadata("design:paramtypes", [ typeof Repository === "undefined" ? Object : Repository, typeof Repository === "undefined" ? Object : Repository, typeof SignatureService === "undefined" ? Object : SignatureService ]) ], ArticleDataLoader); export { ArticleDataLoader };