• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmcelhaney / counterfact / 3596104599

pending completion
3596104599

push

github

GitHub
Update dependency fs-extra to v11

380 of 401 branches covered (94.76%)

Branch coverage included in aggregate %.

1777 of 1999 relevant lines covered (88.89%)

21.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/server/start.js
1
import nodePath from "node:path";
×
2
import { pathToFileURL } from "node:url";
×
3

×
4
import yaml from "js-yaml";
×
5
import Koa from "koa";
×
6
import bodyParser from "koa-bodyparser";
×
7
import { koaSwagger } from "koa2-swagger-ui";
×
8
import Handlebars from "handlebars";
×
9

×
10
import { readFile } from "../util/read-file.js";
×
11

×
12
import { counterfact } from "./counterfact.js";
×
13

×
14
// eslint-disable-next-line no-underscore-dangle
×
15
const __dirname = nodePath.dirname(new URL(import.meta.url).pathname);
×
16

×
17
const DEFAULT_PORT = 3100;
×
18

×
19
Handlebars.registerHelper("escape_route", (route) =>
×
20
  route.replace(/[^\w/]/gu, "-")
×
21
);
×
22

×
23
function openapi(openApiPath, url) {
×
24
  return async (ctx, next) => {
×
25
    if (ctx.URL.pathname === "/counterfact/openapi") {
×
26
      const openApiDocument = await yaml.load(await readFile(openApiPath));
×
27

×
28
      openApiDocument.servers ??= [];
×
29

×
30
      openApiDocument.servers.unshift({
×
31
        description: "Counterfact",
×
32
        url,
×
33
      });
×
34

×
35
      // OpenApi 2 support:
×
36
      openApiDocument.host = url;
×
37

×
38
      // eslint-disable-next-line require-atomic-updates
×
39
      ctx.body = yaml.dump(openApiDocument);
×
40

×
41
      return;
×
42
    }
×
43

×
44
    // eslint-disable-next-line node/callback-return
×
45
    await next();
×
46
  };
×
47
}
×
48

×
49
function page(pathname, templateName, locals) {
×
50
  return async (ctx, next) => {
×
51
    const render = Handlebars.compile(
×
52
      await readFile(
×
53
        nodePath.join(__dirname, `../client/${templateName}.html.hbs`)
×
54
      )
×
55
    );
×
56

×
57
    if (ctx.URL.pathname === pathname) {
×
58
      // eslint-disable-next-line require-atomic-updates
×
59
      ctx.body = await render(locals);
×
60

×
61
      return;
×
62
    }
×
63

×
64
    // eslint-disable-next-line node/callback-return
×
65
    await next();
×
66
  };
×
67
}
×
68

×
69
export async function start({
×
70
  basePath = process.cwd(),
×
71
  port = DEFAULT_PORT,
×
72
  openApiPath = nodePath.join(basePath, "../openapi.yaml"),
×
73
}) {
×
74
  const app = new Koa();
×
75

×
76
  const { koaMiddleware, contextRegistry, registry } = await counterfact(
×
77
    basePath,
×
78
    openApiPath
×
79
  );
×
80

×
81
  app.use(openapi(openApiPath, `//localhost:${port}`));
×
82

×
83
  app.use(
×
84
    koaSwagger({
×
85
      routePrefix: "/counterfact/swagger",
×
86

×
87
      swaggerOptions: {
×
88
        url: "/counterfact/openapi",
×
89
      },
×
90
    })
×
91
  );
×
92

×
93
  app.use(
×
94
    page("/counterfact/", "index", {
×
95
      basePath,
×
96
      routes: registry.routes,
×
97
      methods: ["get", "post", "put", "delete", "patch"],
×
98
      openApiPath,
×
99

×
100
      openApiHref: openApiPath.includes("://")
×
101
        ? openApiPath
×
102
        : pathToFileURL(openApiPath).href,
×
103
    })
×
104
  );
×
105

×
106
  app.use(
×
107
    page("/counterfact/rapidoc", "rapi-doc", {
×
108
      basePath,
×
109
      routes: registry.routes,
×
110
    })
×
111
  );
×
112

×
113
  app.use(bodyParser());
×
114

×
115
  app.use(koaMiddleware);
×
116

×
117
  app.listen(port);
×
118

×
119
  return { contextRegistry };
×
120
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc