8000 Merge pull request #1 from dankmo/custom-conversion · hubcarl/json-typescript-mapper@f1673b1 · GitHub
[go: up one dir, main page]

Skip to content

Commit f1673b1

Browse files
authored
Merge pull request jf3096#1 from dankmo/custom-conversion
Serialize feature and custom conversion support.
2 parents 9c6ad3b + c956038 commit f1673b1

File tree

9 files changed

+436
-5
lines changed

9 files changed

+436
-5
lines changed

index.js

Lines changed: 33 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import {isTargetType, isPrimitiveOrPrimitiveClass, isArrayOrArrayClass} from './
88
*/
99
const JSON_META_DATA_KEY = 'JsonProperty';
1010

11+
export interface ICustomConverter {
12+
fromJson(data: any): any;
13+
toJson(data: any): any;
14+
}
15+
1116
/**
1217
* IDecoratorMetaData<T>
1318
* DecoratorConstraint
@@ -16,7 +21,9 @@ const JSON_META_DATA_KEY = 'JsonProperty';
1621
*/
1722
export interface IDecoratorMetaData<T> {
1823
name?: string,
19-
clazz?: {new(): T}
24+
clazz?: {new(): T},
25+
customConverter?: ICustomConverter,
26+
excludeToJson?: boolean
2027
}
2128

2229
/**
@@ -51,6 +58,7 @@ export function JsonProperty<T>(metadata?: IDecoratorMetaData<T>|string): (targe
5158
else {
5259
throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata)
5360
}
61+
5462
return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData);
5563
}
5664

@@ -154,11 +162,52 @@ export function deserialize<T>(Clazz: {new(): T}, json: Object): T {
154162
* get decoratorMetaData, structure: { name?:string, clazz?:{ new():T } }
155163
*/
156164
let decoratorMetaData = getJsonProperty(instance, key);
165+
157166
/**
158167
* pass value to instance
159168
*/
160-
instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key];
169+
if (decoratorMetaData && decoratorMetaData.customConverter) {
170+
instance[key] = decoratorMetaData.customConverter.fromJson(json[decoratorMetaData.name || key]);
171+
} else {
172+
instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key];
173+
}
174+
161175
});
162176

163177
return instance;
164178
}
179+
180+
export function serialize(instance: any): any {
181+
182+
if (!isTargetType(instance, 'object') || isArrayOrArrayClass(instance)) {
183+
return instance;
184+
}
185+
186+
const obj = {};
187+
Object.keys(instance).forEach(key => {
188+
const metadata = getJsonProperty(instance, key);
189+
obj[metadata && metadata.name ? metadata.name : key] = serializeProperty(metadata, instance[key]);
190+
});
191+
return obj;
192+
}
193+
194+
function serializeProperty(metadata: IDecoratorMetaData<any>, prop: any): any {
195+
196+
if (!metadata || metadata.excludeToJson === true) {
197+
return;
198+
}
199+
200+
if (metadata.customConverter) {
201+
return metadata.customConverter.toJson(prop);
202+
}
203+
204+
if (!metadata.clazz) {
205+
return prop;
206+
}
207+
208+
if (isArrayOrArrayClass(prop)) {
209+
return prop.map(propItem => serialize(propItem));
210+
}
211+
212+
return serialize(prop);
213+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"mocha": "2.0.1"
1313
},
1414
"scripts": {
15-
"test": "mocha ./spec/index.js"
15+
"test": "mocha ./spec/*.js"
1616
},
1717
"description": "For single page application, data sources are obtained from API server. Instead of directly using api data, we \r definitely require an adapter layer to transform data as needed. Furthermore, \r the adapter inverse the the data dependency from API server(API Server is considered uncontrollable and \r highly unreliable as data structure may be edit by backend coder for some specific purposes)to our adapter \r which becomes reliable. Thus, this library is created as the adapter make use of es7 reflect decorator.",
1818
"main": "index.js",
@@ -34,4 +34,4 @@
3434
"url": "https://github.com/jf3096/json-typescript-mapper/issues"
3535
},
3636
"homepage": "https://github.com/jf3096/json-typescript-mapper#readme"
37-
}
37+
}

spec/common/dateconverter.js

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/common/dateconverter.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {ICustomConverter} from '../../index';
2+
3+
const dateConverter: ICustomConverter = {
4+
fromJson(data: any): any {
5+
return new Date(data);
6+
},
7+
8+
toJson(data: any): any {
9+
return 'some-date';
10+
}
11+
};
12+
13+
export default dateConverter;

spec/index.js

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import {expect} from 'chai';
22
import {deserialize, JsonProperty} from '../index';
3+
import dateConverter from './common/dateconverter'
34

45
class Student {
56
@JsonProperty('name')
67
fullName: string;
78

9+
@JsonProperty({name: 'dob', customConverter: dateConverter})
10+
dateOfBirth: Date = undefined;
11+
812
constructor() {
913
this.fullName = void 0;
1014
}
@@ -168,4 +172,15 @@ describe('index()', function () {
168172
const person = deserialize(Person, json);
169173
expect(person.name).to.be.equals(void 0);
170174
});
175+
176+
it('should use a custom converter if available', function () {
177+
const json = {
178+
"name": "John Doe",
179+
dob: "1995-11-10"
180+
};
181+
const student = deserialize(Student, json);
182+
expect(student.fullName).to.be.equals('John Doe');
183+
expect(student.dateOfBirth).to.be.instanceof(Date);
184+
expect(student.dateOfBirth.toString()).to.equal(new Date("1995-11-10").toString());
185+
});
171186
});

0 commit comments

Comments
 (0)
0