@dao-xyz/borsh
Advanced tools
Comparing version 2.0.6 to 2.0.7
@@ -324,2 +324,44 @@ "use strict"; | ||
}); | ||
test("extended enum", () => { | ||
class SuperSuper { | ||
} | ||
class Super extends SuperSuper { | ||
constructor() { | ||
super(); | ||
} | ||
} | ||
let Enum0 = class Enum0 extends Super { | ||
constructor(a) { | ||
super(); | ||
this.a = a; | ||
} | ||
}; | ||
__decorate([ | ||
(0, index_1.field)({ type: "u8" }) | ||
], Enum0.prototype, "a", void 0); | ||
Enum0 = __decorate([ | ||
(0, index_1.variant)(0) | ||
], Enum0); | ||
let Enum1 = class Enum1 extends Super { | ||
constructor(b) { | ||
super(); | ||
this.b = b; | ||
} | ||
}; | ||
__decorate([ | ||
(0, index_1.field)({ type: "u8" }) | ||
], Enum1.prototype, "b", void 0); | ||
Enum1 = __decorate([ | ||
(0, index_1.variant)(1) | ||
], Enum1); | ||
const instance = new Enum1(4); | ||
// validate([Enum0, Enum1, Super, SuperSuper]); | ||
expect((0, index_1.getSchema)(Enum0)).toBeDefined(); | ||
expect((0, index_1.getSchema)(Enum1)).toBeDefined(); | ||
const serialized = (0, index_1.serialize)(instance); | ||
expect(serialized).toEqual(Buffer.from([1, 4])); | ||
const deserialied = (0, index_1.deserialize)(Buffer.from(serialized), SuperSuper, false, binary_1.BinaryReader); | ||
expect(deserialied).toBeInstanceOf(Enum1); | ||
expect(deserialied.b).toEqual(4); | ||
}); | ||
test("wrapped enum", () => { | ||
@@ -326,0 +368,0 @@ class Super { |
@@ -161,3 +161,3 @@ "use strict"; | ||
// We know that we should serialize into the variant that accounts to the first byte of the read | ||
for (const [_key, actualClazz] of getDependencies(clazz)) { | ||
for (const [_key, actualClazz] of getDependenciesRecursively(clazz)) { | ||
const variantIndex = (0, exports.getVariantIndex)(actualClazz); | ||
@@ -250,5 +250,18 @@ if (variantIndex !== undefined) { | ||
let key = JSON.stringify((0, exports.getVariantIndex)(dependency)); | ||
if (dependencies.has(key)) { | ||
if (key != undefined && dependencies.has(key)) { | ||
throw new error_1.BorshError(`Conflicting variants: Dependency ${dependencies.get(key).name} and ${dependency.name} share same variant index(es)`); | ||
} | ||
if (key == undefined) { | ||
/** | ||
* Class is not a variant but a "bridging class" i.e | ||
* class A {} | ||
* class B extends A {} | ||
* | ||
* @variant(0) | ||
* class C extends B {} | ||
* | ||
* class B has no variant even though A is a dependency on it, so it gets the key "A/B" instead | ||
*/ | ||
key = ctor.name + "/" + dependency.name; | ||
} | ||
dependencies.set(key, dependency); | ||
@@ -261,3 +274,3 @@ ctor.prototype._borsh_dependency = dependencies; | ||
} | ||
for (const [_key, dependency] of getDependencies(ctor)) { | ||
for (const [_key, dependency] of getDependenciesRecursively(ctor)) { | ||
if (!schema.has(dependency)) { | ||
@@ -272,2 +285,19 @@ return false; | ||
}; | ||
/** | ||
* Flat map class inheritance tree into hashmap where key represents variant key | ||
* @param ctor | ||
* @param mem | ||
* @returns a map of dependencies | ||
*/ | ||
const getDependenciesRecursively = (ctor, mem = new Map()) => { | ||
let dep = getDependencies(ctor); | ||
for (const [key, f] of dep) { | ||
if (mem.has(key)) { | ||
continue; | ||
} | ||
mem.set(key, f); | ||
getDependenciesRecursively(f, mem); | ||
} | ||
return mem; | ||
}; | ||
const setSchema = (ctor, schema) => { | ||
@@ -387,3 +417,3 @@ ctor.prototype._borsh_schema = schema; | ||
// Class dependencies (inheritance) | ||
getDependencies(clazz).forEach((dependency) => { | ||
getDependenciesRecursively(clazz).forEach((dependency) => { | ||
if (clazzes.find(c => c == dependency) == undefined) { | ||
@@ -390,0 +420,0 @@ dependencies.add(dependency); |
{ | ||
"name": "@dao-xyz/borsh", | ||
"version": "2.0.6", | ||
"version": "2.0.7", | ||
"readme": "README.md", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/dao-xyz/borsh-ts#README", |
@@ -350,2 +350,50 @@ import BN from "bn.js"; | ||
test("extended enum", () => { | ||
class SuperSuper {} | ||
class Super extends SuperSuper { | ||
constructor() { | ||
super(); | ||
} | ||
} | ||
@variant(0) | ||
class Enum0 extends Super { | ||
@field({ type: "u8" }) | ||
public a: number; | ||
constructor(a: number) { | ||
super(); | ||
this.a = a; | ||
} | ||
} | ||
@variant(1) | ||
class Enum1 extends Super { | ||
@field({ type: "u8" }) | ||
public b: number; | ||
constructor(b: number) { | ||
super(); | ||
this.b = b; | ||
} | ||
} | ||
const instance = new Enum1(4); | ||
// validate([Enum0, Enum1, Super, SuperSuper]); | ||
expect(getSchema(Enum0)).toBeDefined(); | ||
expect(getSchema(Enum1)).toBeDefined(); | ||
const serialized = serialize(instance); | ||
expect(serialized).toEqual(Buffer.from([1, 4])); | ||
const deserialied = deserialize( | ||
Buffer.from(serialized), | ||
SuperSuper, | ||
false, | ||
BinaryReader | ||
); | ||
expect(deserialied).toBeInstanceOf(Enum1); | ||
expect((deserialied as Enum1).b).toEqual(4); | ||
}); | ||
test("wrapped enum", () => { | ||
@@ -352,0 +400,0 @@ class Super {} |
@@ -180,3 +180,3 @@ import bs58 from "bs58"; | ||
// We know that we should serialize into the variant that accounts to the first byte of the read | ||
for (const [_key, actualClazz] of getDependencies(clazz)) { | ||
for (const [_key, actualClazz] of getDependenciesRecursively(clazz)) { | ||
const variantIndex = getVariantIndex(actualClazz); | ||
@@ -290,5 +290,18 @@ if (variantIndex !== undefined) { | ||
let key = JSON.stringify(getVariantIndex(dependency)); | ||
if (dependencies.has(key)) { | ||
if (key != undefined && dependencies.has(key)) { | ||
throw new BorshError(`Conflicting variants: Dependency ${dependencies.get(key).name} and ${dependency.name} share same variant index(es)`) | ||
} | ||
if (key == undefined) { | ||
/** | ||
* Class is not a variant but a "bridging class" i.e | ||
* class A {} | ||
* class B extends A {} | ||
* | ||
* @variant(0) | ||
* class C extends B {} | ||
* | ||
* class B has no variant even though A is a dependency on it, so it gets the key "A/B" instead | ||
*/ | ||
key = ctor.name + "/" + dependency.name; | ||
} | ||
dependencies.set(key, dependency); | ||
@@ -303,3 +316,3 @@ ctor.prototype._borsh_dependency = dependencies; | ||
for (const [_key, dependency] of getDependencies(ctor)) { | ||
for (const [_key, dependency] of getDependenciesRecursively(ctor)) { | ||
if (!schema.has(dependency)) { | ||
@@ -316,4 +329,22 @@ return false; | ||
/** | ||
* Flat map class inheritance tree into hashmap where key represents variant key | ||
* @param ctor | ||
* @param mem | ||
* @returns a map of dependencies | ||
*/ | ||
const getDependenciesRecursively = (ctor: Function, mem: Map<string, Function> = new Map()): Map<string, Function> => { | ||
let dep = getDependencies(ctor); | ||
for (const [key, f] of dep) { | ||
if (mem.has(key)) { | ||
continue; | ||
} | ||
mem.set(key, f); | ||
getDependenciesRecursively(f, mem); | ||
} | ||
return mem | ||
} | ||
const setSchema = (ctor: Function, schema: StructKind) => { | ||
@@ -450,3 +481,3 @@ ctor.prototype._borsh_schema = schema; | ||
// Class dependencies (inheritance) | ||
getDependencies(clazz).forEach((dependency) => { | ||
getDependenciesRecursively(clazz).forEach((dependency) => { | ||
if (clazzes.find(c => c == dependency) == undefined) { | ||
@@ -453,0 +484,0 @@ dependencies.add(dependency); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
274580
4902