GithubHelp home page GithubHelp logo

kaiu-lab / serializer Goto Github PK

View Code? Open in Web Editor NEW
3.0 4.0 1.0 1.8 MB

Simple JSON deserializer for typescript applications

License: MIT License

TypeScript 100.00%
serializer typescript ts json deserializer

serializer's Introduction

serializer

Build Status codecov npm version devDependency Status GitHub issues GitHub stars GitHub license

Table of contents

About

Serializer is a serialization library written in Typescript made to handle typing in deserialized objects.

Installation

Install through npm:

npm install --save @kaiu/serializer

Usage

Deserialize

import { Serializer } from '@kaiu/serializer';

const serializer = new Serializer();

class Foo {
    bar: string;

    public getUpperCaseBar(): string {
        return this.bar.toUpperCase();
    }
}

const foo = serializer.deserialize<Foo>({ bar: 'baz' }, Foo);

console.log(foo.getUpperCaseBar()); // Will print "BAZ"

More details: Class Serializer

Serialize

import { Serializer, Transient } from '@kaiu/serializer';

const serializer = new Serializer();

class Foo {
    bar: string;
    
    @Transient()
    secret: string;

    public getUpperCaseBar(): string {
        return this.bar.toUpperCase();
    }
}

const foo = new Foo();
foo.bar = 'baz';
foo.secret = 's3cr3t';

console.log(serializer.serialize(foo)); // Will print '{ "bar": "baz" }'

More details: Class Serializer

Usage with Angular

In order to use the serializer properly inside an Angular application, we created an angular wrapper to provide this serializer as an Injectable service: https://github.com/kaiu-lab/ng-serializer

Advanced Usages

Deep class fields

    import { Serializer, DeserializeAs } from '@kaiu/serializer';

    class Bar {
        baz: string;
   
       public getUpperCaseBaz(): string {
           return this.baz.toUpperCase();
       }   
    } 

   class Foo {
       @DeserializeAs(Bar) 
       bar: Bar;
   }
    
    const foo = serializer.deserialize<Foo>({ bar: { baz: 'baz' } }, Foo);

    console.log(foo.bar.getUpperCaseBar()); // Will print "BAZ"

More details: DeserializeAs

Arrays

import { Serializer } from '@kaiu/serializer';

const serializer = new Serializer();

class Foo {
    bar: string;

    public getUpperCaseBar(): string {
        return this.bar.toUpperCase();
    }
}

const foo = serializer.deserialize<Foo>([{ bar: 'baz' }, { bar: 'buz' }], [Foo]);

console.log(foos[1].getUpperCaseBar()); // Will print "BUZ"

Discriminant field

import { Serializer, Registry, Parent } from '@kaiu/serializer';

@Parent({
    discriminatorField: 'type',
    allowSelf: true // This one is optional.
})
export class Vehicle {
     type: string;
     color: string;

     public getDescription(): string {
        return 'I am just a vehicle';
     }
}

export class Car extends Vehicle {
    public getDescription(): string {
        return 'I am a car, I can move using wheels';
    }
}

const registry = new Registry();

registry.add([
     {
         parent: Vehicle,
         children: {
             car: Car
         }
     }
]);

const serializer = new Serializer(registry);

const foo = serializer.deserialize<Vehicle>({type: 'car', color: 'red'}, Vehicle);

console.log(foo.getDescription()); // Will print "I am a car, I can move using wheels"

More details: Class Registry

Property mapping

export class Example{
     @DeserializeFieldName('bar')
     foo: string;
}

const result = serializer.deserialize<Example>({ bar: 'hey' }, Example);
console.log(result.foo); // Will print 'hey'

More details: DeserializeFieldName

Documentation

Everything is detailed on our documentation website.

Development

Prepare your environment

  • Install Node.js and NPM
  • Install local dev dependencies: npm install while current directory is this repo

Testing

Run npm test to run tests once or npm run test:watch to continually run tests.

Release

  • Bump the version in package.json (once the module hits 1.0 this will become automatic)
npm run release

License

MIT

serializer's People

Contributors

dependabot[bot] avatar noemi-salaun avatar supamiu avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

termex21

serializer's Issues

Add support for serialization

With the aim of proposing a fully featured library, it would be necessary to manage the serialization in addition to the deserialization.

  • Some projects may want to use this lib server side and need to serialize object instead of deserialize.
  • We can think about a complexe serialization process before sending data with some Ajax call client side.

Configure tslint properly

The main rules we want are:

  • Use const whenever it's possible.
  • Allow inferred types.
  • Single quotes for strings.
  • Spaces around braces and type declarations.
  • Triple equal.

The actual tslint.json configuration is almost fine but typedef options have to be tuned and we need to add const rule.

Clear package.json

The actual devDependency field in our package.json is the one generated from the yeoman generator, we might want to remove some libraries but we have to find out which ones are useless.

Preprocess registrations at register time

Instead of using a dumb Serializer.register() that leaves all the bulk of the processing for when the serializer is used, I think we should move most of the processing during the registration.

Currently, Serializer.register() simply fills an array and checks for some little constraints. On the other side, Serializer.deserialize() process this array each time to find the correct inheritance or other stuff.

I would prefer to do most of the preprocessing at registration time, so Serializer.deserialize() has nothing else to do but actually deserializing.

Preprocessing in the Serializer.register() can also be used to check a certain number of inheritance constraints, to throw errors without having to wait for some Serializer.deserialize() calls.

Add support for callbacks in deserialization lifecycle

We should add support for deserlization callbacks, something like

interface Deserializable {
   beforeDeserialize(event);
   afterDeserialize(event);
}

class Foo implements Deserializable {
   attr1: string;

   @DeserializeAs(Bar)
   attr2: Bar;

   beforeDeserialize(event) {
       event.json.attr1 = event.json.attr1 + '-modified';
   }

   afterDeserialize(event) {
      event.target.attr2.setSomething(event.json.something);
   }
}

We should also support function in place of class inside @DeserializeAs decorator.

const myFunc = (json) => {
    return json.someAttr + ' - ' + json.someOtherAttr;
}

class Foo {
    attr1: string;
 
    @DeserializeAs(myFunc)
    attr2: Bar;
}

All the proposed signature are fakes

Add support for attributes name mapping

We should allow to map a json field into a class attribute with a differente name.

For exemple, the json may contain "prix", and the developper want to map it to the attribute "price" inside its class.

class Foo {
   @Deserialize('prix')
   price: number;
}

Clean remaining javascript files

Some Javascript files are still in the repository, we should delete them from versioning.

The one we saw is karma.conf.js but we should check if there's no other files like this remaining.

We should define the full specs of the deserialization with inheritance

Before going further in the implementation with the risk of having to replace everything if we encounter a new unforeseen case, I think we should set the full specs of the deserialization with inheritance.

This issue should list all cases and how to manage them. This comment will be edited with the latest updates.

  • Object without its discriminator field
  • Object with unmatching discriminator value
  • Register with children that does not extends the parent
  • Register with the parent among the children
  • Inheritance with implicit matching for the parent itself
  • Recursive inheritance, with multiple levels, like grandchildren and further
  • Register with the same classe multiple time for different discriminator value
  • Register for different classes but the same discriminator value
Edit 2017-24-07
  • Remove Inheritance with explicit matching for the parent itself (same as above?) because it's the same as registering the parent
  • Add the case for multiple registration of the same classe, or the same disciminatorValue

add metadata.json file for angular's aot

Because ngc needs every dependency to be aot-compliant, we need to be aot-compliant too.

Meaning that we need to ship some metadatas for aot.

I'll investigate on it and add details on this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.