All files / services/blog blog.service.ts

97.83% Statements 45/46
83.33% Branches 10/12
100% Functions 6/6
97.83% Lines 45/46

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105                      1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 4x       1x   1x 1x 1x       4x 4x 4x   4x 4x 4x 4x   4x 10x 10x 3x   7x     7x 1x     6x 3x   3x   6x     3x       2x 2x           2x 1x   1x       2x             2x 1x   1x       2x     2x            
import { IBSBlog } from "@schemas/services/blog/blog.v1.service";
import {
  CreatePostReq,
  CreatePostRsp,
  EditPostReq,
  EditPostRsp,
  GetPostReq,
  GetPostRsp,
  ListPostsReq,
  ListPostsRsp,
} from "@schemas/services/blog/blog.v1.schemas";
import { BlogPostNotFound } from "@services/blog/errors/blog.errors";
import Knex from "knex";
import knexfile from "@services/blog/knexfile";
import { loadModels } from "@lib/objection-utils/objection-utils.lib";
import path from "path";
import BlogPost from "@services/blog/models/blog-post.model";
import { noCase } from "no-case";
import { UniqueViolationError } from "objection";
import { DateTime } from "luxon";
 
const snakeCase = input =>
  noCase(input, {
    delimiter: "_",
  });
 
export default class BSBlogService implements IBSBlog {
  async init(ctx) {
    const masterKnex = Knex(knexfile.production);
    const slaveKnex = Knex(knexfile.slave);
    loadModels(masterKnex, slaveKnex, path.join(__dirname, "models"));
  }
 
  async CreatePost(ctx, req: CreatePostReq): Promise<CreatePostRsp> {
    const newPost = req;
    Eif (!newPost.postId) {
      newPost.postId = snakeCase(newPost.title);
    }
    newPost.createdAt = new Date().toISOString();
    newPost.updatedAt = new Date().toISOString();
    let retry = 0;
    const postId = newPost.postId;
    // eslint-disable-next-line no-constant-condition
    while (true) {
      try {
        await BlogPost.queryOnMaster().insert(newPost);
        break;
      } catch (e) {
        Iif (!(e instanceof UniqueViolationError)) {
          throw e;
        }
        if (retry >= 3) {
          throw e;
        }
      }
      if (retry === 0) {
        newPost.postId = `${postId}_${DateTime.local().toFormat("yyyyMMdd")}`;
      } else {
        newPost.postId = `${postId}_${DateTime.local().toFormat("yyyyMMdd")}_${retry + 1}`;
      }
      retry += 1;
    }
 
    return newPost;
  }
 
  async EditPost(ctx, req: EditPostReq): Promise<EditPostRsp> {
    const newPost = req;
    const affectedRow = await BlogPost.queryOnMaster()
      .where({
        postId: req.postId,
      })
      .update(newPost);
 
    if (affectedRow === 0) {
      throw new BlogPostNotFound(req);
    }
    return newPost;
  }
 
  async GetPost(ctx, req: GetPostReq): Promise<GetPostRsp> {
    const post = await BlogPost.query()
      .where({
        postId: req.postId,
      })
      .select("*")
      .limit(1)
      .first();
    if (!post) {
      throw new BlogPostNotFound(req);
    }
    return post as any;
  }
 
  async ListPosts(ctx, req: ListPostsReq): Promise<ListPostsRsp> {
    const lists = await BlogPost.query()
      .select("*")
      .limit(10);
    return {
      list: lists as any,
      total: lists.length,
    };
  }
}