@lancercomet/suntori
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

SunTori

SunTori npm version

SunTori is a Typescript JSON de/serializer to ensure everything is safe at runtime.

SunTori

Features

  • JSON <--- Mapping ---> Class.
  • JSON fields name <--- Mapping ---> Class props name.
  • Typesafe at runtime.
  • Deal with raw strings and dynamic keys.

First of all

SunTori depends on the very feature emitDecoratorMetadata which was introduced to TypeScript, so keep in mind:

  • Not available in pure JavaScript enviroment. You have to use it with TypeScript.
  • Not available for ESBuild because ESBuild doesn't emit decorator metadata.

Installation

Install reflect-metadata:

npm install reflect-metadata --save

Import reflect-metadata in the whole project entry:

// Project entry.
import 'reflect-metadata'

Remember to enable this two things in tsconfig.json:

"emitDecoratorMetadata": true,
"experimentalDecorators": true

Usage

Deserialization.

import { Serializable, JsonProperty, deserialize } from '@lancercomet/suntori'

@Serializable()
class User {
  @JsonProperty()
  name: string = ''

  @JsonProperty()
  age: number = 0

  @JsonProperty('user_address')
  address: string = 'Default address'
}

const dataSource = {
  name: 'Doge',
  age: 1,
  user_address: 'The Moon.'
}
const doge = deserialize(dataSource, User)  // User

Array-typed deserialization.

import { Serializable, JsonProperty, deserialize } from '@lancercomet/suntori'

@Serializable()
class User {
  @JsonProperty()
  name: string = ''

  @JsonProperty()
  age: number = 0

  @JsonProperty('user_address')
  address: string = 'Default address'
}


@Serializable()
class UserList {
  // Array-typed property must be described like this.
  @JsonProperty({
    name: 'users',
    type: User
  })
  users: User[] = []
}

const dataSource = [
  { name: 'LancerComet', age: 10, user_address: 'The Mars.' },
  { name: 'John Smith', age: 100, user_address: 'The Heaven.' }
]
const userList = deserialize(dataSource, UserList)  // User[]

Serialization.

@Serializable()
class User {
  @JsonProperty()
  name: string = ''

  @JsonProperty()
  age: number = 0

  @JsonProperty('user_address')
  address: string = 'Default address'
}

const dataSource = {
  name: 'Doge',
  age: 1,
  user_address: 'The Moon.'
}
const doge = deserialize(dataSource, User)  // User

const json = serialize(doge)  // json should be "equal" to dataSource.

More decorators

There are also some additional decorators, providing extra functionalities.

@JsonString

import { Serializable, JsonProperty, deserialize, JsonString } from '@lancercomet/suntori'

@Serializable()
class A {
  @JsonProperty()
  a: string = ''
}

@Serializable()
class B {
  @JsonProperty({
    type: A,
    name: 'list1'
  })
  list1: A[] = []

  @JsonProperty({
    type: A,
    name: 'list2'
  })
  @JsonString()  // <-- Add this.
  list2: A[] = []
}

const b = deserialize({
  list1: '[{ "a": "a1" }, { "a": "a2" }]',  // Oh no.
  list2: '[{ "a": "a1" }, { "a": "a2" }]'   // Yeah!
}, B)

@DynamicKey

import { Serializable, JsonProperty, deserialize, DynamicKey } from '@lancercomet/suntori'

@Serializable()
class A {
  @JsonProperty()
  a: string = ''
}

@Serializable()
class B {
  @JsonProperty({
    name: 'as',
    type: A
  })
  @DynamicKey()  // <-- Add this.
  as: { [key: string]: A } = {}    
}

const b = deserialize({
  as: {
    a: {},
    b: {},
    c: {}
  }
}, B)

@Nullable

@Serializable()
class A {
  @JsonProperty()
  readonly num: number = 0

  @JsonProperty()
  @Nullable()  // <--- Add this.
  readonly numNullable: number = 0

  @JsonProperty()
  @Nullable()  // <--- Add this.
  readonly numNullable2: number = 0
}

const a = deserialize({
  num: null,
  numNullable: null,
  numNullable2: undefined
}, A)

console.log(a.num)           // 0
console.log(a.numNullable)   // null
console.log(a.numNullable2)  // 0, only got null if payload were null.

@ParseInt and @ParseFloat

 @Serializable()
 class A {
   @JsonProperty()
   @ParseInt()
   readonly int: number = 0

   @JsonProperty()
   @ParseFloat()
   readonly float: number = 0
 }
 
 const a = deserialize({
   int: '10',
   float: '0.1'
 }, A)

 console.log(a.int)    // 10
 console.log(a.float)  // 0.1

License

Apache-2.0

Package Sidebar

Install

npm i @lancercomet/suntori

Weekly Downloads

13

Version

1.1.0

License

Apache-2.0

Unpacked Size

49.8 kB

Total Files

15

Last publish

Collaborators

  • pwch