Socket
Socket
Sign inDemoInstall

scrubbr

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scrubbr

Serialize and sanitize JSON data using TypeScript.


Version published
Weekly downloads
1
decreased by-94.44%
Maintainers
1
Weekly downloads
 
Created
Source

Scrubbr

Tests npm version

Serialize and sanitize JSON data using TypeScript.

Simple Example

Serializing data sent from the webserver to the client shouldn't be hard. If you're already using TypeScript, you have everything you need. Scrubbr will use your TypeScript types to deeply transform and sanitize your data.

Table of contents

  • Install
  • Quick Start
  • Custom Serializer Functions
    • Type Serializers
    • Path Serializers
  • Cache the generated schema to disk
  • Schema Validation
  • Troubleshooting
    • Look at the generated schema
    • Enable debug logging

Install

npm i -S scrubbr

Quick Start

  1. Define a TypeScript file as your master schema:
// schema.ts

type UserList = {
  users: User[];
};

type User = {
  name: string;
  image: string;
};
  1. Load it into Scrubbr and serialize your data:
import Scrubbr from 'scrubbr';

// Load the typescript schema file
// PERFORMANCE NOTE: this is a synchronous call! Load early and cache to a shared variable.
const scrubbr = new Scrubbr('./schema.ts');

async function api() {
  const data = getUsers();

  // Serialize the data based on the UserList type defined in schema.ts
  return await scrubbr.serialize('UserList', data);
}

// Raw unsanitized data
function getUsers() {
  return {
    users: [
      {
        name: 'John Doe',
        image: 'http://i.pravatar.cc/300',
        email: 'donotspam@me.com',
        password: 'xxxsecretxxx',
      },
    ],
  };
}
  1. Output
{
  "users": [
    {
      "name": "John Doe",
      "image": "http://i.pravatar.cc/300"
    }
  ]
}

Custom Serializer Functions

You can define additional functions for custom serializations.

Type Serializers

Type serializer functions are called every time a matching TypeScript type is encountered.

For example, if you want to use another type to serialize a logged-in user:

import Scrubbr, { useType } from 'scrubbr';

// Called every time scrubbr finds a User type object
scrubbr.addTypeSerializer('User', (data, state) => {
  // `context` is a value you pass to scrubbr.serialize (see below)
  if (data.id === state.context.loggedInUserId) {
    return useType('UserPrivileged');
  }

  // You can manually transform the data here
  return data;
});

// Context can be anything you want
const context = {
  loggedInUserId: 10,
};
const serialized = await scrubbr.serialize('PostList', data, context);

Path Serializers

This serializer is called at each node of the data object, regardless of type. It's called a path serializer because you'll use the state.path value to determine which node you're serializing.

In this example we want to convert every createdAt date value to the local timezone.

import moment from 'moment-timezone';
import Scrubbr, { useType } from 'scrubbr';

// Convert date-like strings from UTC to local time
scrubbr.addPathSerializer((data, state) => {
  const path = state.path;
  if (path.match(/\.createdAt$/)) {
    return moment(data).tz(state.context.timezone).format();
  }
  return data;
});

const context = {
  timezone: 'America/Los_Angeles',
};
const serialized = await scrubbr.serialize('PostList', data, context);

Try it yourself

It's easy to try it yourself with the included example in example/index.ts. Just clone this repo, install the dependencies (npm install) and then run the example app with:

npm run example

Caching the generated schema to disk

To optimize startup time, you can save the schema object scrubbr uses internally to disk during your build step and then load it directly when you initialize scrubbr. Internally, scrubbr uses the ts-json-schema-generator library to convert TypeScript to a JSON schema file. NOTE: you cannot load any JSON schema file into scrubbr, it needs to follow the conventions of ts-json-schema-generator.

Build

npx ts-json-schema-generator -f ./tsconfig.json -e all -p ./schema.ts -o ./dist/schema.json

Runtime code

import Scrubbr, { JSONSchemaDefinitions } from 'scrubbr';

// Set resolveJsonModule to true in your tsconfig, otherwise use require()
import * as schema from './schema.json';
const scrubbr = new Scrubbr(schema as JSONSchemaDefinitions);

Schema Validation

For the sake of performance and simplicity, scrubber does not perform a schema validation step (it outputs data, not validates). However, under the hood scrubbr converts TypeScript to JSONSchema (via the great ts-json-schema-generator package). So you can easily use ajv to validate the serialized object.

import Ajv from 'ajv';
import Scrubbr from 'scrubbr';

const scrubbr = new Scrubbr('./schema.ts');

async function main() {
  // Serialize
  const output = await scrubbr.serialize('UserList', data);
  const jsonSchema = scrubbr.getSchema();

  // Validate
  const ajv = new Ajv();
  const schemaValidator = ajv.compile(jsonSchema);
  const isValid = schemaValidator(output);
  if (!isValid) {
    console.error(schemaValidator.errors);
  }
}

Troubleshooting

Look at the generated schema

If scrubbr is not returning the data you're expecting, the first place to look is at the internal schema definitions:

console.log(scrubbr.getSchema());

This is a JSON schema that is created from your TypeScript file.

Next look at the schema definition for the TypeScript type you're trying to serialize to.

// return scrubbr.serialize('UserList', data);
console.log(scrubbr.getSchemaForType('UserList'));

Verify that this returns a JSON Schema object and that it contains the properties you want serialized.

Debugging output

Enable debug logging:

import Scrubbr, { LogLevel } from 'scrubbr';

const scrubbr = new Scrubbr('./schema.ts', { logLevel: LogLevel.DEBUG });

Scrubbr can also nest the logs to make it easier to read:

const scrubbr = new Scrubbr('./schema.ts', {
  logLevel: LogLevel.DEBUG,
  logNesting: true,
});

And you can even enter the indent string to use for each level of nesting:

const scrubbr = new Scrubbr('./schema.ts', {
  logLevel: LogLevel.DEBUG,
  logNesting: '~~>',
});

License

MIT

FAQs

Package last updated on 23 Jun 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc