Express¶
Express has no native OpenAPI spec and no native type system, so it's the primary case for the code-parsing path. There's no TypeScript or JavaScript AST this project depends on, so the parser is regex and heuristic based, not a real parser in the compiler sense.
If you have a spec¶
If your Express app is documented with swagger-jsdoc, tsoa, or a hand-written
openapi.json, point init at it and you get the high-confidence OpenAPI path instead:
Code-parsing fallback¶
The Express parser (input/parsers/express.py) reads body fields in this order, falling
through to the next only if the current one finds nothing:
- A Joi, Zod, or Yup schema validated against
req.bodyin the route, either defined inline or referenced from aconst schema = Joi.object({...})elsewhere in the file. Treated the same as a typed body: high confidence. - JSDoc
@body {type} nametags on the comment block above the route. Also high confidence, since it's an explicit author annotation. - Destructuring or dot-access on
req.body(const { amount } = req.bodyorreq.body.amount), with no schema or JSDoc backing it up. This is inferred from usage, carries no type information, and is flagged lower confidence.
| Aspect | From |
|---|---|
| Routes | app.get/post/put/patch/delete(...), router.* |
| Body | Schema validation, JSDoc, or inferred usage, in that order (above) |
| Auth | Middleware passed inline to the route, or registered globally with app.use(mw) / router.use(mw) |
Inferred bodies are flagged, not hidden
A body resolved from schema validation or JSDoc is just as trustworthy as a typed
DTO and isn't flagged. A body inferred purely from req.body usage, with neither of
those present, gets tagged [code] and "lower confidence" in the
diff. The fix is almost always to
add a JSDoc @body tag or adopt a validation library you're probably already using.
Routing spread across files is resolved through a real import graph
(app.use('/prefix', require('./x')) and app.use('/prefix', childRouter) both
follow the require/import specifier to the file that defines the mounted
router), not just literal same-file paths. What still isn't traceable is a prefix
built at runtime — a computed string, a value read from config — since there's no
static value to resolve. When that happens, sync the route explicitly with
/postman:syncapi "POST /path".
Example¶
See
examples/express-api/,
which has the real generated Collection items checked in under expected-output/, and
its README walks through exactly which fields come from JSDoc versus inference.