npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fcjs/core

v1.1.2

Published

Core decorators and utilities for the FCJs framework

Readme

@fcjs/core

Core decorators and utilities for the First-Class Js (FCJs) framework. This package provides a set of TypeScript decorators and utility classes to rapidly build type-safe REST and WebSocket APIs using Express and Zod.

Features

  • Express Route Decorators: Easily define controllers and routes using decorators.
  • DTO Validation: Validate request bodies and query parameters with Zod schemas.
  • OpenAPI Generation: Automatically generate OpenAPI 3.1 docs from your routes and schemas.
  • Middleware Decorators: Attach and document custom middleware to routes.
  • WebSocket Decorators: Define WebSocket event handlers with decorators.
  • Typed Error Handling: Built-in HTTP exception classes for robust error responses.
  • Utility Classes: Includes logger, typecasting, and autobind utilities.

Installation

npm install @fcjs/core

Usage

1. Define DTOs with zod-openapi/extend

To enable OpenAPI documentation for your Zod schemas, import zod-openapi/extend before defining your DTOs. This allows you to use the .openapi() method to add metadata like descriptions and examples, which will be included in the generated OpenAPI docs.

import 'zod-openapi/extend';
import { z } from 'zod';

export const UserDto = z
  .object({
    id: z.number(),
    name: z.string(),
  })
  .openapi({
    description: 'User Data',
    example: { id: 1, name: 'John Doe' },
  });

export const CreateUserDto = z
  .object({
    name: z.string().min(1),
    email: z.string().email(),
  })
  .openapi({
    description: 'Create user body',
    example: { name: 'eg_user', email: '[email protected]' },
  });

2. Use the Decorators and DTOs in Controllers

import { Route, Get, Post, BodyDto, ResponseDto } from '@fcjs/core';
import { UserDto, CreateUserDto } from './dtos';

@Route('/users')
class UserController {
  @Get('/')
  @ResponseDto(UserDto)
  async getUser(req, res) {
    // ...fetch user logic
    return { id: 1, name: 'John Doe' };
  }

  @Post('/')
  @BodyDto(CreateUserDto)
  @ResponseDto(UserDto)
  async createUser(req, res) {
    // ...create user logic
    return { id: 2, name: req.body.name };
  }
}

3. Middleware Example

You can use custom middleware classes with the @Middleware decorator to protect routes or add custom logic. Middleware classes should have a handler method that receives Express's req, res, and next arguments.

import { Request, Response, NextFunction } from 'express';
import { Middleware, Get, ResponseDto } from '@fcjs/core';
import { UnauthorizedError } from '../utils/exceptions.util';
import { getUserDto } from './dtos';

export class authMiddleware {
  public headerKey = 'Authorization';
  public description = 'Bearer <token>';

  public handler(req: Request, res: Response, next: NextFunction) {
    const authHeader = req.headers['authorization'];
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      throw new UnauthorizedError('Missing or invalid Authorization header');
    }
    const token = authHeader.split(' ')[1];
    if (token !== 'success') {
      throw new UnauthorizedError('Invalid token');
    }
    next();
  }
}

// in user.controller.ts
class UserController {
  @Get('/:id')
  @Middleware(authMiddleware)
  @ResponseDto(getUserDto)
  public async getUserById(req: Request) {
    // ...fetch user by id logic
    return { id: +req.params.id, name: 'John Doe' };
  }
}

4. Register Controllers

import express from 'express';
import { loadRoutes, Logger } from '@fcjs/core';
import { UserController } from './controllers/user.controller';

const app = express();
app.use(express.json());

loadRoutes(app, [UserController]);

app.listen(3000, () => {
  // using Logger from FCJs
  Logger.log(
    'Server',
    `FCJs Server url: ${Logger.colorLog(`http://localhost:3000`, 'cyan')}`,
  );
});

5. Generate OpenAPI Docs

import { OpenApiDoc } from '@fcjs/core';

const openApiDoc = new OpenApiDoc('My FCJs API');
// Serve openApiDoc as JSON or with Swagger UI

6. WebSocket Support

import { WsRoute, WsMessage, loadWsRoutes } from '@fcjs/core';
import { createServer } from 'http';

@WsRoute('/ws')
class ChatWsController {
  @WsMessage('message')
  handleMessage(data: { text: string }) {
    return {
      event: 'message',
      data: { text: `Echo: ${data.text}` },
    };
  }
}

const server = createServer(app);
loadWsRoutes(server, [ChatWsController]);
server.listen(3001);

API Reference

License

MIT © Bhagyaraj BK


For more details, see the GitHub repository.

Example: fcjs-example repository