Skip to content

Repository files navigation

TRAPI

main codecov Known Vulnerabilities

TypeScript Rest API generates OpenAPI specifications and API metadata from TypeScript decorators — without locking you into a specific decorator library.

Why TRAPI?

Most tools that generate OpenAPI from decorators force you to adopt their own decorator set. TRAPI takes a different approach: bring your own decorators. You define a mapping from your framework's decorators to TRAPI's metadata model, and TRAPI handles the rest.

  • Decorator-agnostic — works with any decorator-based HTTP framework (Express, Koa, Fastify, or your own)
  • Pure static analysis — decorators are no-ops at runtime; metadata is extracted via the TypeScript compiler API
  • Zero runtime overhead — all work happens at build time, nothing is added to your application
  • Framework presets — ships with presets for typescript-rest and @decorators/express, or create your own
  • OpenAPI 2.0, 3.0, 3.1 & 3.2 — generates spec-compliant JSON/YAML output

Packages

Package Description
@trapi/core Framework-neutral contract: IR types, decorator/preset machinery, authoring helpers (no typescript dep)
@trapi/metadata Extracts API metadata from TypeScript decorators (depends on @trapi/core)
@trapi/swagger Transforms metadata into OpenAPI 2.0, 3.0, 3.1 & 3.2 specifications
@trapi/preset-decorators-express Self-contained preset for @decorators/express (routing + TRAPI markers + JSDoc)
@trapi/preset-typescript-rest Self-contained preset for typescript-rest (routing + TRAPI markers + JSDoc)
@trapi/cli trapi CLI — generate OpenAPI specs straight from the shell

Quick Start

npm install @trapi/metadata @trapi/swagger @trapi/preset-decorators-express @decorators/express
import { generateMetadata } from '@trapi/metadata';
import { generateSwagger, saveSwagger } from '@trapi/swagger';

// Extract metadata from your decorated TypeScript source
const metadata = await generateMetadata({
    entryPoint: './src/controllers/**/*.ts',
    preset: '@trapi/preset-decorators-express',
});

// Generate OpenAPI spec
const spec = await generateSwagger({
    version: 'v3',
    metadata,
    data: { name: 'My API', version: '1.0.0' },
});

// Write spec to disk
await saveSwagger(spec, { cwd: './docs' });

Or skip the script entirely and run it from the shell with @trapi/cli:

npx trapi generate \
  --preset @trapi/preset-decorators-express \
  --entry-point 'src/**/*.ts' \
  --output docs/openapi.json \
  --version 3.1

How It Works

TRAPI uses the TypeScript compiler API to statically analyze your source code. It reads decorator metadata from the AST — no reflect-metadata, no runtime type information.

TypeScript Source Code  -->  Metadata Extraction  -->  OpenAPI Specification
   (your decorators)        (@trapi/metadata)          (@trapi/swagger)

A preset is a collection of handlers that match decorators by name and mutate a draft (controller, method, parameter, ...). Each handler declares what it matches and how it contributes:

import { controller, method } from '@trapi/core';

const controllerHandler = controller({
    match: { name: 'Controller', on: 'class' },
    apply: (ctx, draft) => {
        const arg = ctx.argument(0);
        if (typeof arg?.raw === 'string') {
            draft.path = arg.raw;
        }
    },
});

const getHandler = method({
    match: { name: 'Get', on: 'method' },
    apply: (ctx, draft) => {
        draft.method = 'get';
        const arg = ctx.argument(0);
        if (typeof arg?.raw === 'string') {
            draft.path = arg.raw;
        }
    },
});

export default {
    name: 'my-preset',
    controllers: [controllerHandler],
    methods: [getHandler],
    parameters: [/* ... */],
};

Presets can extend other presets to inherit and override handlers. The shipped framework presets (@trapi/preset-decorators-express, @trapi/preset-typescript-rest) are self-contained — each ships its own routing handlers, TRAPI markers, and JSDoc handlers — but a user-authored preset can extend either by name. JSDoc tags use the same model through dedicated controllerJsDoc / methodJsDoc / parameterJsDoc handler arrays.

This means any HTTP framework built on TypeScript decorators can get metadata extraction and OpenAPI generation for free — without changing application code.

Documentation

The full docs live at https://trapi.tada5hi.net. Highlights:

License

Made with 💚

Published under MIT License.

About

TRAPI is a collection of packages to create/generate metadata for REST-APis and generate swagger documentations.

Topics

Resources

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages