mbus-backend
    Preparing search index...

    Module routes/documented

    Wrappers around stuff you would otherwise do with express but with reflection capabilities used for openapi specification generation and built-in request format validation.

    The req and res objects aren't provided to the passed in handler functions, if you're doing something more complicated just use the router directly for now.

    Nested routing not supported yet, but should probably be added since api.ts is getting long (or we could separate the functions from the route defintions).

    Extra functionality can be added as needed.

    Getting Started

    // have express app
    const app = express();

    // cool router (mandatory probably)
    const router = express.Router();

    // use local context if you want
    const ctx = newContext();

    // add router to app (app.use(router, '/api'))
    addRouter(globalContext, app, router, '/api')

    // add route (/api/double)
    addGetRoute(
    globalContext, router, '/double',
    // Zod schemas for each part of the request & response, defaults=emptyFormat
    // since query params end up as strings, z.coerce.number() is needed not z.number()
    { ...emptyFormat, query: z.object({ x: z.coerce.number() }), resBody: z.number() },
    // handling logic goes here, first arg is ignored b/c it is the path params
    (_, { x }) => {
    // x is already a number as opposed to any/unknown
    makeSuccessResponse(x * 2);
    },
    // documentation goes here
    { name: 'double a number', description: 'f: R -> R, x |-> 2x'}
    );

    // get docs
    const spec: OpenAPI = docsFor(globalContext);
    // output docs
    outputDocsFor(globalContext);

    Make sure you know how to use Zod, then look into addRouter, addGetRoute, and addPostRoute. It would also be useful to take a look at HandlerReturn + remember the existence of emptyFormat and globalContext.

    z.tuple isn't handled well by swagger_parser, prefer objects instead.

    If a Zod schema is reused / important enough to get its own variable, make sure to at the very least add .meta({ id: 'unique name' }) to it so that API/docs consumers can also take advantage of this. Other schemas can also have this even if they are not variables. Note that id must be unique, and accidentally setting name instead won't have the intended outcome.

    The OpenAPI spec will be populated with the output formats of the schemas you define routes with. This makes coerce work well with path/query formats but might be problematic with client generation if using transformations to non-primative types. Only use coerce, pipe, and transform with the parts of the request, not the response (the resBody schema is never used to validate, only to get a type).

    Look into setting the environment variables DOCUMENTED (to anything truthy), DOCUMENTED_OUTPUT_FILE (or it will log to the console), and DOCUMENTED_EXIT_ON_OUTPUT. Also look at globalContext, docsFor, and outputDocsFor.

    ExpressRequest
    OpenAPI
    OpenAPIGetPath
    OpenAPIPostPath
    ReflectionInfoRaw
    Context
    HandlerReturn
    StringlyZodObject
    emptyFormat
    ENABLED
    globalContext
    addGetRoute
    addPostRoute
    addRouter
    docsFor
    makeFailureResponse
    makeSuccessResponse
    newContext
    outputDocsFor