All files / src/services spec-coverage-service.ts

0% Statements 0/24
0% Branches 0/9
0% Functions 0/6
0% Lines 0/23

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                                                                                                             
import fs from "fs";
import { HttpMethod } from "../api";
import { logger } from "../logger";
 
export interface SpecPath {
  /**
   * Path to implement.
   */
  path: string;
  /**
   * List of HTTP methods to implement.
   */
  methods: (HttpMethod | "options")[];
}
 
export const getPathsFromSpecs = async (specPaths: string[]): Promise<SpecPath[]> => {
  let paths: SpecPath[] = [];
  for (const specPath of specPaths) {
    paths = paths.concat(await getPathsFromSpec(specPath));
  }
  return paths;
};
 
const getPathsFromSpec = async (specPath: string): Promise<SpecPath[]> => {
  logger.debug(`Parsing spec ${specPath}`);
  const json = await parseSpec(specPath);
  return json.paths && typeof json.paths === "object" ? parseOpenAPIPath(json.paths as Record<string, unknown>) : [];
};
 
const parseOpenAPIPath = (paths: Record<string, unknown>): SpecPath[] => {
  return Object.entries(paths)
    .map(([path, content]) => {
      return {
        path,
        methods: content && typeof content === "object" ? (Object.keys(content) as HttpMethod[]) : [],
      };
    })
    .filter((x) => x.methods.length > 0);
};
 
const parseSpec = async (specPath: string): Promise<Record<string, unknown>> => {
  const content = await fs.promises.readFile(specPath);
  try {
    const json = JSON.parse(content.toString().replace(/^\uFEFF/, ""));
 
    Iif (typeof json !== "object") {
      throw new Error(`Spec ${specPath} is not valid, should be an json object.`);
    }
 
    return json;
  } catch (e) {
    throw new Error(`Spec ${specPath} is not valid json, ${e}`);
  }
};