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 🙏

© 2024 – Pkg Stats / Ryan Hefner

stix-schema

v1.0.4

Published

A stix module that adds schema validation for your requests using joi.

Downloads

24

Readme

Stix-schema

A stix module and middleware that adds schema validation for your requests using joi.

Installation

  1. yarn add stix-schema.
  2. Add the module to your project
import SchemaModule from 'stix-schema';

export const modules: ModuleManagerConfigInterface = [
  SchemaModule,
  Application,
];

Summary

  • Cool feature alert: When combined with stix-swagger you get schemas generated for your swagger docs out of the box.
  • Schema validation will run immediately after the router is done.
  • If validation fails, stix-schema responds to the user with a clientError (bad request) of invalid_parameters and sends along the details of the failed validations.
  • If validation is successful, the parameters get set on ctx.state.params for consumption elsewhere.
  • If you use stix-gates as well, it's good to know that gates run after stix-schema validation.

Usage

Create a config in the schema namespace. Example configuration config/schema.ts:

import { AbstractActionController } from 'stix';
import { SchemaConfig, SchemaRuleset } from 'stix-schema';
import { UserController } from '../src/Controller';
import { NewUser } from '../src/Schema/User';

export const schema: SchemaConfig = {
  schemas: new Map<typeof AbstractActionController, SchemaRuleset>([
    [UserController, {
      register: { body: NewUser },
    }],
  ]),
};

With this in place, every request that triggers UserController.register will be validated against the NewUser schema first.

Example schema:

A schema must export an object wit ha name and the schema.

import Joi from 'joi';

export const NewUser = {
  name: 'NewUser',
  schema: Joi.object().keys({
    username: Joi.string().alphanum().min(3).max(30).required(),
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    email: Joi.string().email({ minDomainAtoms: 2 }),
  }),
};

Using the params

Stix-schema will take the result of the validation and when successful put the params on ctx.state.params.

export class UserController extends AbstractActionController {
  public async register (ctx): Promise<Response> {
    const { username, email, password } = ctx.state.params;
    // Go nuts!
  }
}

Now you can assume the data has been set and focus on logic.

Configuration

There are a couple of configuration options at your disposal of which the one you'll use most is schemas (as seen in the example above).

These are the defaults:

export const schema: SchemaConfig = {
  merge: true,
  defaultOptions: { allowUnknown: true, stripUnknown: true },
};

Schemas

Schemas is a mapping of actions to schemas.

import { AbstractActionController } from 'stix';
import { SchemaConfig, SchemaRuleset } from 'stix-schema';
import { UserController } from '../src/Controller';
import { NewUser, ProfileSearch, LanguageString, Translations } from '../src/Schema/User';

export const schema: SchemaConfig = {
  schemas: new Map<typeof AbstractActionController, SchemaRuleset>([
    [UserController, {
      // Validate the body. (e.g. for post requests)
      // This also shows you can use options on schema rules.
      register: { body: NewUser, options: { allowUnknown: false } },

      // Validate the query. (e.g. for get requests)
      profile: { query: ProfileSearch },

      // Validate both the query and the body (e.g. posting for a specific language)
      profile: { query: LanguageString, body: Translations },
    }],
  ]),
};

Merge

Merge tells stix-schema to merge the results of query and body into one object.

Merge false:

const result = {
  query: { bar: 'bar' },
  body: { foo: 'foo' },
};

Merge true:

const result = {
  bar: 'bar', 
  foo: 'foo',
};

This is generally the desired behaviour and is therefor the default.

defaultOptions

These are the default options used for schema validation. They're used when a schema entry in the config doesn't provide it's own options. Generally you'll want to allow additional params to be sent along, but simply ignore them. This is the default behaviour:

  • Unknown properties are allowed
  • Unknown properties get stripped

If you do need access to unknown properties, you can set stripUnknown to false or access them directly from ctx.request.query or ctx.request.body.

FAQ

Not really an FAQ as such... It's more a list of questions I'm expecting.

Why use Map

Because this follows the same philosophy as stix: modules should provide IoC. In other words, any module that decides to use stix-schema should allow the user to override configuration options.

You can have multiple controllers with the same name, so the controller itself is used as the key to make it very explicit.

License

MIT