typescript-flat-serializer
v1.2.0
Published
A typescript library to serialize/deserialize classes to/from string in a flat format. Supports inheritance, circular reference and more
Downloads
50
Maintainers
Readme
typescript-flat-serializer
A typescript library to serialize/deserialize classes to/from string in a flat format. Supports inheritance, circular reference and more
Summary
Why
When I was developing a electron app I needed a serializer that fill some requirements to use with IPC:
- After serialize I wanted that the object keep the methods (right prototype)
- I needed inheritance
- Supports circular reference is always good
Installation
npm install typescript-flat-serializer --save
Usage
With decorators
Preparation
If you want to use our decorators you also need to set experimentalDecorators and emitDecoratorMetadata to true into the tsconfig.json file.
For example:
{
"compilerOptions": {
...
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
...
}
}
Usage
First let's create some models
import { TSFlatCollection, TSFlatObject } from "typescript-flat-serializer";
@TSFlatObject()
export abstract class Animal {
protected constructor(public name: string) {
}
}
// This decorator NEEDS to be placed on every class that you want to serialize.
// Without this decorator the behavior will be like stringify/parse from JSON.
@TSFlatObject()
export class Dog extends Animal {
// This decorator will take care of serialize/deserialize our collection
@TSFlatCollection({collectionType: "set"})
favoriteFoods: Set<Food>;
constructor(name: string, public beautiful: boolean, favoriteFoods: Set<Food>) {
super(name);
this.favoriteFoods = favoriteFoods;
}
}
@TSFlatObject()
export class Food extends Animal {
constructor(name: string) {
super(name);
}
}
Now we only need to serialize/deserialize the animal.
import { parse, stringify } from "typescript-flat-serializer";
const foods = new Set([new Food('all')])
const animal: Animal = new Dog('Luffy', true, foods);
// Let's go serialize our animal
const str = stringify(animal)
// value of str: [{"name":"Luffy","beautiful":true,"favoriteFoods":"#_1_#","__class__":"Dog"},["#_2_#"],{"name":"all","__class__":"Food"}]
// And now we can deserialize the animal
const parsedAnimal = parse<Animal>(str);
You can find another examples of utilisation on tests.
Without decorators
First let's create some models
import { registerTSFlat } from "typescript-flat-serializer";
export abstract class Animal {
protected constructor(public name: string) {
registerTSFlat(
{
target: Animal,
}
);
}
}
export class Dog extends Animal {
favoriteFoods: Set<Food>;
constructor(name: string, public beautiful: boolean, favoriteFoods: Set<Food>) {
super(name);
registerTSFlat(
{
target: Dog,
},
{ collectionName: 'favoriteFoods', options: {collectionType: 'set'} }
)
this.favoriteFoods = favoriteFoods;
}
}
export class Food extends Animal {
constructor(name: string) {
super(name);
registerTSFlat(
{
target: Food,
},
)
}
}
Now we only need to serialize/deserialize the animal.
import {parse, stringify} from "typescript-flat-serializer";
const foods = new Set([new Food('all')])
const animal: Animal = new Dog('Luffy', true, foods);
// Let's go serialize our animal
const str = stringify(animal)
// value of str: [{"name":"Luffy","beautiful":true,"favoriteFoods":"#_1_#","__class__":"Dog"},["#_2_#"],{"name":"all","__class__":"Food"}]
// And now we can deserialize the animal
const parsedAnimal = parse<Animal>(str);
API
Decorators
@TSFlatObject
Used to make a class serializable.
Example
@TSFlatObject()
export class Dog {
}
@TSFlatCollection
Used do make a Array|Set|Map|Dictionary
Example
@TSFlatObject()
export class Dog {
@TSFlatCollection({collectionType: "map"})
placesVisited: Map<string, boolean>
}
Parameters
collectionType
Type: CollectionTypeString
Optional: false
Description: The way to specify the type of collection
@TSFlatProperty
Used modify the serialization/deserialization of a property.
Example
@TSFlatObject()
export class Dog {
@TSFlatCollection({collectionType: "map"})
@TSFlatProperty({
beforeStringify: (m) => {
m.set('Brazil', true);
}
})
placesVisited: Map<string, boolean>
}
Parameters
options
Type: TSFlatPropertyOptions
Optional: true
Description: The option to customize the serialization/deserialization of the target property.
Methods
registerTSFlat
Used do register an object and its items.
registerTSFlat<T>(objectRegistration: FlatObjectRegistration<T>, ...items: FlatItem<T>[])
Parameters
objectRegistration
Type: FlatObjectRegistration<T>
Optional: false
Description: Information about the class that we want to make serializable.
Type: FlatItem<T>[]
Optional: true
Description: Items that this class have that we want to make serializable.
stringify
Used to serialize a object.
stringify(obj: any, options?: StringifyOptions): string
Parameters
obj
Type: any
Optional: false
Description: The object that will be serialized
options
Type: StringifyOptions
Optional: true
Description: Custom options to the serialization
Return
string
parse
Used to deserialize a string into a object.
parse<T>(str: string): T
Return
T
Definitions
Types
FlatObjectRegistration
export type FlatObjectRegistration<T> = {
target: Type<T>,
options?: TSFlatObjectProperties
}
FlatItem<T>
export type FlatItem<T> = FlatPropertyRegistration<T> | FlatCollectionRegistration<T>;
FlatPropertyRegistration<T>
export type FlatPropertyRegistration<T> = {
propertyName: (keyof T), options?: TSFlatPropertyOptions,
}
FlatCollectionRegistration<T>
export type FlatCollectionRegistration<T> = {
collectionName: (keyof T), options: TSFlatCollectionOptions
}
CollectionTypeString
export type CollectionTypeString = 'array' | 'dictionary' | 'map' | 'set';
TSFlatPropertyOptions
export type PropertyTransformer = (property: any) => any;
export interface TSFlatPropertyMetadata {
beforeStringify?: PropertyTransformer;
afterParse?: PropertyTransformer;
}
export interface TSFlatPropertyOptions extends TSFlatPropertyMetadata {
}
stringifyOptions
export type StringifyOptions = {
rFDCOptions?: RFDCOptions
}
export type CustomWayOfCloningObjectMap = Map<Type<any>, (obj: any) => any>;
export type RFDCOptions = {
customWayOfCloningObject?: CustomWayOfCloningObjectMap
}
Important notes
Cloning
This library before the serialization makes a clone of the object. By default the cloning supports the types:
- Object
- Array
- Number
- String
- null
- Date
- undefined
- Buffer
- TypedArray
- Map
- Set
- Function
- AsyncFunction
- GeneratorFunction
- arguments
To support other type, like DateTime of Luxon, you should do something like that:
const customWayOfCloningObject: CustomWayOfCloningObjectMap = new Map();
const rFDCOptions: RFDCOptions = {
customWayOfCloningObject
}
customWayOfCloningObject.set(DateTime, (obj) => DateTime.fromMillis(obj.toMillis()));
const str = stringify(obj, {rFDCOptions});