All files / src/services statistic.ts

100% Statements 60/60
100% Branches 16/16
80% Functions 4/5
100% Lines 60/60

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 851x     1x 1x     1x     1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                       1x 6x 6x 6x 6x 6x 6x 6x   6x   6x 6x 6x 6x 6x 6x 6x 6x   4x   6x 3x 3x 3x 3x 3x 3x 3x 3x 3x   1x 6x 6x 2x 2x 2x 2x 2x 1x 1x 2x 2x 6x 6x 6x 6x      
import { Effect, pipe, Schema } from 'effect';
 
// Constants
import { API_ROUTES, MULTIPLE_DATE_REGEX } from '@/constants';
import { STATUS_CODE, STATUS_MESSAGES } from '@shared/constants';
 
// Types
import { ApiError, HttpMethod } from '@shared/types';
import { StatisticsResponse } from '@/types/statistic';
 
export const StatisticRequestSchema = Schema.Struct({
  token: Schema.String.pipe(
    Schema.minLength(1, {
      message: () => STATUS_MESSAGES[STATUS_CODE.UNAUTHORIZED]!,
    }),
  ),
  time: Schema.String.pipe(
    Schema.pattern(MULTIPLE_DATE_REGEX, {
      message: () => STATUS_MESSAGES[STATUS_CODE.BAD_REQUEST]!,
    }),
  ),
});
 
interface StatisticServiceParams {
  token: string;
  time: string;
}
 
interface StatsResponse {
  data: StatisticsResponse[];
  error?: ApiError | null;
}
 
const statisticService = async ({
  token,
  time,
}: StatisticServiceParams): Promise<StatsResponse> =>
  Effect.runPromise(
    pipe(
      Effect.tryPromise({
        try: async (): Promise<StatsResponse> => {
          // Validate payload
          await Schema.decodeUnknown(StatisticRequestSchema)({ token, time });
 
          const res = await fetch(API_ROUTES.STATISTIC, {
            method: HttpMethod.POST,
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${token}`,
            },
            body: JSON.stringify({ time }),
          });
 
          const { data, error } = await res.json().catch(() => ({}));
 
          if (!data || error) {
            return {
              data: [],
              error: {
                status: error?.status ?? STATUS_CODE.BAD_REQUEST,
                message:
                  error?.message ?? STATUS_MESSAGES[STATUS_CODE.BAD_REQUEST],
              },
            };
          }
 
          return { data };
        },
        catch: (error) => ({
          data: [],
          error: {
            status: STATUS_CODE.INTERNAL_SERVER_ERROR,
            message:
              error instanceof Error
                ? error.message
                : STATUS_MESSAGES[STATUS_CODE.INTERNAL_SERVER_ERROR],
          },
        }),
      }),
      Effect.catchAll((error) => Effect.succeed(error)),
    ),
  );
 
export { statisticService };