ts_serialize
A zero dependency library for serializing data.
ts_serialize
can help you with:
- converting camelCase class members to snake_case JSON properties for use with a REST API
- excluding internal fields from REST API payloads
- converting data types to an internal format, for expamle:
Date
’s
Supported Serialize Types
Installing
Deno
Add the https://github.com/gamebridgeai/ts_serialize.git#v1.0.0
to your deps.ts
file and export what you need.
Node
Add the URL to your package.json
file in dependencies
{
"dependencies": {
"ts_serialize": "git+https://github.com/gamebridgeai/ts_serialize.git#v1.0.0"
}
}
Usage
Basic
Import Serializable
and SerializeProperty
, extend Serializable
with your class
and use the SerializeProperty
decorator on any properties you want serialized.
Passing a string as an argument to SerializeProperty
causes the property to use
that name as the key when serialized.
class Test extends Serializable<Test> {
@SerializeProperty()
propertyOne = "Hello";
@SerializeProperty("property_two")
propertyTwo = "World!";
notSerialized = "not-serialized";
}
assert(new Test().toJson(), `{"propertyOne":"Hello","property_two":"World!"}`);
const test = new Test().fromJson(
`{"propertyOne":"From","property_two":"Json!", "notSerialized": "changed" }`
);
assertEquals(test.propertyOne, "From");
assertEquals(test.propertyTwo, "Json!");
assertEquals(test.notSerialized, "not-serialized");
Advanced
SerializeProperty
also excepts an options object with the properties:
serializedName
(Optional) {string} - Used as the key in the serialized objecttoJsonStrategy
(Optional) {ToJsonStrategy} - Function orToJsonStrategy
used when serializingfromJsonStrategy
(Optional) {FromJsonStrategy} - Function orFromJsonStrategy
used when deserializing
Strategies
Strategies
are functions or a composed list of functions to execute on the values when
serializing or deserializing. The functions take one argument which is the value to process.
const myCustomFromJsonStrategy = (v: string): string => BigInt(v);
const myCustomToJsonStrategy = (v: BigInt): string => v.toString();
class Test extends Serializable<Test> {
@SerializeProperty({
serializedName: "big_int",
fromJsonStrategy: myCustomFromJsonStrategy,
toJsonStrategy: myCustomToJsonStrategy,
})
bigInt!: BigInt;
}
const mockObj = new Test().fromJson(`{"big_int":"9007199254740991"}`);
assertEquals(mockObj.bigInt.toString(), "9007199254740991");
assertEquals(mockObj.toJson(), "9007199254740991");
Dates
Dates can use the fromJsonStrategy
to revive a serilaized string into a Date object. ts_serialize
provides a ISODateFromJson
function to parse ISO Dates.
class Test extends Serializable<Test> {
@SerializeProperty({
fromJsonStrategy: ISODateFromJson,
})
date!: Date;
}
const mockObj = new Test().fromJson(`{"date":"2020-06-04T19:01:47.831Z"}`);
assert(mockObj.date instanceof Date);
assertEquals(mockObj.date.getFullYear(), 2020);
createDateStrategy()
can be use to make
a reviving date strategy. Pass a regex to make your own.
const fromJsonStrategy = createDateStrategy(/^(\d{4})-(\d{2})-(\d{2})$/);
class Test extends Serializable<Test> {
@SerializeProperty({ fromJsonStratege })
date!: Date;
}
const mockObj = new Test().fromJson(`{"date":"2099-11-25"}`);
assert(mockObj.date instanceof Date);
assertEquals(mockObj.date.getFullYear(), 2099);
Inheritance
Inherited classes override the key when serializing. If you override a propery any value used for that key will be overridden by the child value. With collisions the child always overides the parent
class Test1 extends Serializable<Test1> {
@SerializeProperty("serialize_me")
serializeMe = "nice1";
}
class Test2 extends Test1 {
@SerializeProperty("serialize_me")
serializeMeInstead = "nice2";
}
const test = new Test2();
assertEquals(test.serializeMe, "nice1");
assertEquals(test.serializeMeInstead, "nice2");
assertEquals(test.toJson(), `{"serialize_me":"nice2"}`);
Nested Class Serialization
ToJson:
class Test1 extends Serializable<Test1> {
@SerializeProperty("serialize_me_1")
serializeMe = "nice1";
}
class Test2 extends Serializable<Test2> {
@SerializeProperty({
serializedKey: "serialize_me_2",
})
nested: Test1 = new Test1();
}
const test = new Test2();
assertEquals(test.toJson(), `{"serialize_me_2":{"serialize_me_1":"nice1"}}`);
FromJson:
class Test1 extends Serializable<Test1> {
@SerializeProperty("serialize_me_1")
serializeMe = "nice1";
}
class Test2 extends Serializable<Test2> {
@SerializeProperty({
serializedKey: "serialize_me_2",
fromJsonStrategy: (json) => new Test1().fromJson(json),
})
nested!: Test1;
}
const test = new Test2();
test.fromJson(`{"serialize_me_2": { "serialize_me_1":"custom value"}}`);
assertEquals(test.nested.serializeMe, "custom value");
Mulitple strategy functions
toJsonStrategy
and fromJsonStrategy
also have provided functions with the same name
to build out strategies with multiple functions.
const addWord = (word: string) => (v: string) => `${v} ${word}`;
const shout = (v: string) => `${v}!!!`;
const fromJsonStrategy = fromJsonStrategy(addWord("World"), shout);
class Test extends Serializable<Test> {
@SerializeProperty({ fromJsonStrategy })
property!: string;
}
assertEquals(new Test().fromJson(`{"property":"Hello"}`), "Hello World!!!");
Built With
- Deno :sauropod:
Contributing
Please read CONTRIBUTING.md for details on our code of conduct and DEVELOPMENT.md for setting up an environment to submit pull requests to us.
Versioning
We use SemVer for versioning.
Authors
- Scott Hardy - Initial work - @shardyMBAI 🐸
- Chris Dufour - Initial work - @ChrisDufourMB 🍕 🐈 :crown:
See also the list of contributors who participated in this project.
License
This project is licensed under the MIT License - see the LICENSE file for details
Acknowledgments
- MindBridge for support
- Parsing Dates with JSON for knowledge
- OAK Server as a project structure example