Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Convert Xd scenegraph to JSON format
export class JsonService {
private static readonly skipFields = ["parent", "constructor", "pathData"];
public convert(value: any): any {
if (this.isPlainType(value)) {
return value;
}
// custom conversion for arrays and xd arrrays
if (Array.isArray(value) || typeof value["map"] === "function") {
const collection = value.map((v: any) => this.convert(v));
return collection;
}
const keyDescriptors = this.getDescriptors(value);
const keys = Object.keys(keyDescriptors);
if (!keys.length) {
return value;
}
const json = {};
// set object class (if any)
if (Object.getPrototypeOf(value).constructor) {
const typeName = Object.getPrototypeOf(value).constructor.name;
if (typeName && typeName !== "Object") {
json["_type"] = typeName;
}
}
for (const key of keys) {
if (JsonService.skipFields.indexOf(key) > -1 || key[0] === "_") {
continue;
}
const descriptor = keyDescriptors[key];
const keyValue = this.getValue(value, key, descriptor);
if (typeof keyValue === "function") {
continue;
}
json[key] = this.convert(keyValue);
}
return json;
}
private getDescriptors(value: any): { [key: string]: PropertyDescriptor } {
let keyDescriptors: { [key: string]: PropertyDescriptor } = {};
let proto = Object.getPrototypeOf(value);
while (proto) {
const protoKeys = Object.getOwnPropertyDescriptors(proto) as { [key: string]: PropertyDescriptor };
keyDescriptors = { ...keyDescriptors, ...protoKeys };
proto = Object.getPrototypeOf(proto);
}
return keyDescriptors;
}
private isPlainType(value: any): boolean {
// skip empty values, simple types and dates
return (!value
|| ["object", "function"].indexOf(typeof value) === -1
|| value instanceof Date);
}
private getValue(entity: any, key: string, descriptor: PropertyDescriptor): any {
// console.log("getValue", key, typeof entity[key], typeof descriptor.get, !!descriptor.get);
if (typeof entity[key] === "function") {
return !!descriptor.get
? descriptor.get()
: typeof (descriptor.value === "undefined") ? entity[key] : descriptor.value;
} else {
return entity[key];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.