import { HoppRESTHeader, Environment, parseTemplateStringE, HoppRESTParam, } from "@hoppscotch/data"; import chalk from "chalk"; import { pipe } from "fp-ts/function"; import * as A from "fp-ts/Array"; import * as E from "fp-ts/Either"; import * as S from "fp-ts/string"; import * as O from "fp-ts/Option"; import { error } from "../types/errors"; import round from "lodash/round"; import { DEFAULT_DURATION_PRECISION } from "./constants"; /** * Generates template string (status + statusText) with specific color unicodes * based on type of status. * @param status Status code of a HTTP response. * @param statusText Status text of a HTTP response. * @returns Template string with related color unicodes. */ export const getColorStatusCode = ( status: number | string, statusText: string ): string => { const statusCode = `${status == 0 ? "Error" : status} : ${statusText}`; if (status.toString().startsWith("2")) { return chalk.greenBright(statusCode); } else if (status.toString().startsWith("3")) { return chalk.yellowBright(statusCode); } return chalk.redBright(statusCode); }; /** * Replaces all template-string with their effective ENV values to generate effective * request headers/parameters meta-data. * @param metaData Headers/parameters on which ENVs will be applied. * @param environment Provides ENV variables for parsing template-string. * @returns Active, non-empty-key, parsed headers/parameters pairs. */ export const getEffectiveFinalMetaData = ( metaData: HoppRESTHeader[] | HoppRESTParam[], environment: Environment ) => pipe( metaData, /** * Selecting only non-empty and active pairs. */ A.filter(({ key, active }) => !S.isEmpty(key) && active), A.map(({ key, value }) => ({ active: true, key: parseTemplateStringE(key, environment.variables), value: parseTemplateStringE(value, environment.variables), })), E.fromPredicate( /** * Check if every key-value is right either. Else return HoppCLIError with * appropriate reason. */ A.every(({ key, value }) => E.isRight(key) && E.isRight(value)), (reason) => error({ code: "PARSING_ERROR", data: reason }) ), E.map( /** * Filtering and mapping only right-eithers for each key-value as [string, string]. */ A.filterMap(({ key, value }) => E.isRight(key) && E.isRight(value) ? O.some({ active: true, key: key.right, value: value.right }) : O.none ) ) ); /** * Reduces array of HoppRESTParam or HoppRESTHeader to unique key-value * pair. * @param metaData Array of meta-data to reduce. * @returns Object with unique key-value pair. */ export const getMetaDataPairs = ( metaData: HoppRESTParam[] | HoppRESTHeader[] ) => pipe( metaData, // Excluding non-active & empty key request meta-data. A.filter(({ active, key }) => active && !S.isEmpty(key)), // Reducing array of request-meta-data to key-value pair object. A.reduce(>{}, (target, { key, value }) => Object.assign(target, { [`${key}`]: value }) ) ); /** * Object providing aliases for chalk color properties based on exceptions. */ export const exceptionColors = { WARN: chalk.yellow, INFO: chalk.blue, FAIL: chalk.red, SUCCESS: chalk.green, INFO_BRIGHT: chalk.blueBright, BG_WARN: chalk.bgYellow, BG_FAIL: chalk.bgRed, BG_INFO: chalk.bgBlue, BG_SUCCESS: chalk.bgGreen, }; /** * Calculates duration in seconds for given end-HRTime of format [seconds, nanoseconds], * which is rounded-off upto given decimal value. * @param end Providing end-HRTime of format [seconds, nanoseconds]. * @param precision Decimal precision to round-off float duration value (DEFAULT = 3). * @returns Rounded duration in seconds for given decimal precision. */ export const getDurationInSeconds = ( end: [number, number], precision: number = DEFAULT_DURATION_PRECISION ) => { const durationInSeconds = (end[0] * 1e9 + end[1]) / 1e9; return round(durationInSeconds, precision); }; export const roundDuration = ( duration: number, precision: number = DEFAULT_DURATION_PRECISION ) => round(duration, precision);