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

feathers-openapi

v1.2.1

Published

- This library will analyze your app for generate openapi/swagger schema.

Readme

Open-api generator for @feathersjs/feathers

  • This library will analyze your app for generate openapi/swagger schema.

Tested only for @feathers: 3.3.1, report if you meet problems

Installation

    npm i feathers-openapi

Example of use

import { OpenAPI } from 'feathers-openapi';   /// this library
import swaggerUi from 'swagger-ui-express'; // other library for generate UI based on openapi.json

const scheme = new OpenAPI({
app, // here you pass your express app that have attached @feathersjs/feathers and all endpoints
title: 'application',
version: '1',
serverUrl: `http://localhost:4200`,  // swagger documentation will reffered to this host
}).getSpecAsJson();

app.use('/swagger', swaggerUi.serve, swaggerUi.setup(JSON.parse(scheme))); // endpoint for swagger UI
app.use('/openapi', (req, res) => res.end(scheme)); // endpoint for get json version  (can be util for codegeneration)

Creating implementation of hooks where is connected info for validation

Hook should be function with name validateParamHook & validateId (for params), validateBody(for request body) or validateResponseHook( for response body) and also you should attach variable to this function that contain validation scheme with format [hookName].schema.schema = schema;

NOTE! supported only validation schema of type zod, joi. Ensure that you convert your schema to one of these formats


// function validateParam will create validateParamHook and attach to this hook validation schema
export function validateParam<S extends AnySchema | ZodSchema<any, any, any>>(name: 'query' | 'route', schema: S, options?: ValidationOptions): Hook {
  function validateParamHook(context: HookContext) {
    return {
      ...context,
      params: {
        ...context.params,
        [name]: validateBase(context.params[name], schema, 'params', false, options),
      },
    };
  }

  validateParamHook.schema = {  // it is mandatory for feathers-openapid
    name,
    schema,
    options,
  };

  return validateParamHook;
}

export function validateBody<S extends AnySchema | ZodSchema<any, any, any>>(schema: S, options?: ValidationOptions): Hook {
  function validateBodyHook(context: HookContext) {
    return {
      ...context,
      data: validateBase(context['data'], schema, 'data', false, options),
    };
  }

  validateBodyHook.schema = {
    schema,
    options,
  };

  return validateBodyHook;
}

export function validateResponse<S extends AnySchema | ZodSchema<any, any, any>>(schema: S, options?: ValidationOptions): Hook {
  function validateResponseHook(context: HookContext) {
    return {
      ...context,
      result: validateBase(context['result'], schema, 'result', true, options),
    };
  }

  validateResponseHook.schema = {
    schema,
    options,
  };

  return validateResponseHook;
}

export function validateId<S extends AnySchema | ZodSchema<any, any, any>>(schema: S, options?: ValidationOptions): Hook {
  function validateIdHook(context: HookContext) {
    return {
      ...context,
      id: validateBase(context['id'], schema, 'id', false, options),
    };
  }

  validateIdHook.schema = {
    schema: isJoiScheme(schema) ? Joi.object({ id: schema }) : z.object({ id: schema }),
    options,
  };

  return validateIdHook;
}


const isJoiScheme = <J extends AnySchema, Z extends ZodSchema<any, any, any>>(s: J | Z): s is J => {
  return Joi.isSchema(s);
};

function validateBase<S extends AnySchema | ZodSchema<any, any, any>>(data: unknown, schema: S, target: string, softErrors: boolean, options?: ValidationOptions) {
  if (isJoiScheme(schema)) {
    const { error, value } = schema.validate(data, options);

    if (error) {
      logger.warn(`validateBase ${ target } validation failed`, error);

      const { message, details } = error;

      if (!softErrors) {
        throw new BadRequest(message, details);
      }
    }

    return value;
  }
  try {
    return schema.parse(data);
  } catch (e: unknown) {
    logger.warn(`validateBase ${ target } validation failed`, e);

    const { message, issues } = e as ZodError;

    if (!softErrors) {
      throw new BadRequest(message, issues);
    }
  }


  return context;
}

Using hooks


app.service(serviceName).hooks({
  before: {
    create: [
      validators.validateBody(z.object({ username: z.string(), password: z.string() })),
      validators.validateParam(
        'route',
        Joi.object({
          appId: Joi.string().required(),
        }).required(),
      )
    ],
  },
  after: {
    create: [
      validators.validateResponse(z.object({ userId: z.number() }))
    ]
  }
});

License

MIT