JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 596
  • Score
    100M100P100Q113146F
  • License MIT

TypeSerializer, designed to make prettier code while using exclusion strategies on objects.

Package Exports

  • typeserializer

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (typeserializer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

TypeSerializer


npm Build Status Coverage Status MIT licensed

Serializer / deserializer of javascript objects

Table of contents

Installation

  1. Install using npm:
 $ npm install typeserializer --save
  1. You also need to install reflect-metadata shim:
 $ npm install reflect-metadata --save
  1. Import reflect-metadata in a global place of your app (for ex. index.ts):
import 'reflect-metadata';

Decorators

Exclude

While using the default manual exclude you only need to decorate the properties you like to exclude with @Exclude. This will cause the property to be EXCLUDED from the response.

 import {serialize, Exclude} from 'typeserializer';

 class User {
 
   name = 'dan';
   
   @Exclude()
   password = '123456';
 }
 
 const user = new User();
 console.log(serialize(user)); // prints: '{ name: 'dan' }'

Expose

Using all as the exclusion strategy will exclude all properties except for those marked as @Expose().

 import {serialize, Expose, Strategy, ExclusionPolicy} from 'typeserializer';

 @Strategy(ExclusionPolicy.ALL) // <-- This is Required!
 class User {
   @Expose()
   name = 'dan';
   
   password = '123456';
 }
 
 const user = new User();
 console.log(serialize(user)); // prints: '{ name: 'dan' }'

Expose - Dynamic Exclusion

If you would like to use a dynamic approach as an exclusion strategy, you can also make use of the dynamic exclusion capability.

import {Strategy, Expose, ExclusionPolicy, serialize} from 'typeserializer';

 function validator(object: any, propertyKey: string) {
   return object[propertyKey] > 5;
 }
 
@Strategy(ExclusionPolicy.ALL)
 class Foo {
 
   @Expose(validator)
   prop = 1;
 
   @Expose(validator)
   prop2 = 10;
 
   @Expose(validator)
   prop3 = 8;
 }
 
 const foo = new Foo();
 console.log(serialize(foo)); // prints: '{ prop2: 10, prop3: 8 }'

Name

Changing name of a selected property is supported by using the @Name decorator.

 import {serialize, Name} from 'typeserializer';

 class User {
 
   @Name('name')
   myName = 'dan';
   
 }
 
 const user = new User();
 console.log(serialize(user)); // prints: '{ name: 'dan' }'

Groups

You can expose different properties by using the @Groups annotation.

 import {Strategy, Expose, ExclusionPolicy, Groups, serialize} from 'typeserializer';

 @Strategy(ExclusionPolicy.ALL)
 class User {
 
   @Expose()
   @Groups(['user-account'])
   username = 'Dan';
 
   @Expose()
   @Groups(['user-details'])
   age = 28;
 
   password = 'foo';
 }
 
 const user = new User();
 console.log(serialize(user)); // prints: '{ username: 'Dan', age: 28 }'
 console.log(serialize(user, ['user-account'])); // prints: '{ username: 'Dan' }'
 console.log(serialize(user, ['user-details'])); // prints: '{ age: 28 }'
 console.log(serialize(user, ['user-account', 'user-details'])); // prints: '{ username: 'Dan', age: 28 }'

Deep Objects

TypeSerializer can also serialize objects deeply.

 import {Strategy, Expose, ExclusionPolicy, Groups, serialize} from 'typeserializer';

@Strategy(ExclusionPolicy.ALL)
class UserDetails {

  @Expose()
  @Groups(['name'])
  firstName = 'Dan';

  @Expose()
  @Groups(['name'])
  lastName = 'Revah';

  @Expose()
  @Groups(['other'])
  age = 28; 
}

@Strategy(ExclusionPolicy.ALL)
 class User {
 
   @Expose()
   @Groups(['user-account'])
   username = 'Dan';
 
   @Expose()
   @Groups(['user-details'])
   details = new UserDetails();
 
   password = 'foo';
 }
 
 const user = new User();
 console.log(serialize(user, ['user-details'])); // prints: { details: { firstName: 'Dan', lastName: 'Revah', age: 28 } }
 console.log(serialize(user, ['user-details', 'name'])); // prints: { details: { firstName: 'Dan', lastName: 'Revah' } }
 console.log(serialize(user, ['user-details', 'other'])); // prints: { details: { age: 28 } }

Version

You can also serialize a property by version number with @Before & @After.

 import {Strategy, Expose, ExclusionPolicy, serialize, Before, After} from 'typeserializer';

@Strategy(ExclusionPolicy.ALL)
 class UserDetails {
 
   @Expose()
   @Before('1.2.0')
   firstName = 'Dan';
 
   @Expose()
   @Before('1.2.0')
   lastName = 'Revah';
 
   @Expose()
   @After('1.2.0')
   fullName = 'Dan Revah';
 }
 
 const user = new UserDetails();
 console.log(serialize(user)); // prints: '{ firstName: 'Dan', lastName: 'Revah', fullName: 'Dan Revah' }'
 
 console.log(serialize(user, [], '0.4.2')); // prints: '{ firstName: 'Dan', lastName: 'Revah' }'
 console.log(serialize(user, [], '1.1.9')); // prints: '{ firstName: 'Dan', lastName: 'Revah' }'
 
 console.log(serialize(user, [], '1.2.0')); // prints: '{ fullName: 'Dan Revah' }'
 console.log(serialize(user, [], '1.3.0')); // prints: '{ fullName: 'Dan Revah' }'

Type

TypeSerializer also contains a deserialize() method, to deserialize JSON to objects.

Since TypeScript doesn't transpiles types, it is a requirement to add @Type annotation for the 'complex' type properties, including JavaScript's Date.

This is very useful when you are getting a JSON string, and you know it's of a certain type.

import {deserialize, Type} from 'typeserializer';

const fixtureSimple =
  '{"firstName":"Dan","lastName":"Revah","age":28,"isHere":true,"birthDate":"2018-07-15T05:35:03.000Z"}';
  
const fixtureChild = `{"child":${fixtureSimple}}`;
const fixtureChildren = `{"children":[${fixtureSimple}, ${fixtureSimple}]}`;

class Simple {
  firstName: string;
  lastName: string;
  age: number;
  isHere: boolean;

  @Type(Date)
  birthDate: Date;
  
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

class SimpleChild {
  @Type(Simple) 
  child: Simple;
}

class SimpleChildArr {
  @Type([Simple])  // You must wrap with '[]' when defining an array of a type.
  children: Simple[];
}

const simple: Simple = deserialize(fixtureSimple, Simple);

 console.log(simple); // Simple { firstName: "Dan", ... }
 console.log(simple.getFullName()); // Now you can even use class methods! -> Prints 'Dan Revah'. 
 

 console.log(deserialize(fixtureChild, SimpleChild)); // SimpleChild { child: Simple { firstName: "Dan", ... } }
 console.log(deserialize(fixtureChildren, SimpleChildArr)); // SimpleChildArr { children: [Simple { ... }, Simple { ... }] }

Custom Deserializer

It's also possible to use a custom deserializer, in-case you have any 'special' types you want to handle.

For example you could deserialize to a Moment instance using the @Deserializer() annotation.

import {Deserializer, deserialize} from 'typeserializer';

const fixture = '{"date":"2012-12-21T00:00:00"}';

class Foo {
  @Deserializer((m: string): any => Moment(m))
  date: Moment;
  
  getDate() {
    return this.date.format('DD-MM-YYYY');  
  }
  
}

const foo: Foo = deserialize(fixture, Foo);

console.log(foo.getDate()); // '21-12-2012'

Custom Serializer

It's also possible to use a custom serializer, in-case you have any 'special' types you want to handle.

For example you could serialize from a Moment instance using the @Serializer() annotation.

import {Serializer, serialize} from 'typeserializer';

class Bar {
  @Serializer((m: Moment): any => m.format('DD-MM-YYYY'))
  date: Moment;
}

const bar: Bar = new Bar();

bar.date = Moment('2012-12-21T00:00:00');

console.log(serialize(bar)); // {"date":"21-12-2012"}

And ofcourse this can be combined with the previous custom Deserializer:

import {Serializer, serialize} from 'typeserializer';

class Bar {
  @Deserializer((m: string): any => Moment(m))
  @Serializer((m: Moment): any => m.format('DD-MM-YYYY'))
  date: Moment;
}

const bar: Bar = new Bar();
bar.date = Moment('2012-12-21T00:00:00');
const json = serialize(bar);
console.log(json); // {"date":"21-12-2012"}

const bar2: Bar = deserialize(json, Bar);
console.log(bar2.getDate()); // '21-12-2012'