Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/Encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ export type EncoderOptions<ContextType = undefined> = Partial<
*/
ignoreUndefined: boolean;

/**
* If `true`, undefineds are not handled by the library and are instead
* made available to extension codecs
*
* Defaults to `false`
*/
allowUndefinedCustomEncoding: boolean;

/**
* If `true`, integer numbers are encoded as floating point numbers,
* with the `forceFloat32` option taken into account.
Expand All @@ -80,6 +88,7 @@ export class Encoder<ContextType = undefined> {
private readonly sortKeys: boolean;
private readonly forceFloat32: boolean;
private readonly ignoreUndefined: boolean;
private readonly allowUndefinedCustomEncoding: boolean;
private readonly forceIntegerToFloat: boolean;

private pos: number;
Expand All @@ -96,6 +105,7 @@ export class Encoder<ContextType = undefined> {
this.sortKeys = options?.sortKeys ?? false;
this.forceFloat32 = options?.forceFloat32 ?? false;
this.ignoreUndefined = options?.ignoreUndefined ?? false;
this.allowUndefinedCustomEncoding = options?.allowUndefinedCustomEncoding ?? false;
this.forceIntegerToFloat = options?.forceIntegerToFloat ?? false;

this.pos = 0;
Expand Down Expand Up @@ -132,7 +142,8 @@ export class Encoder<ContextType = undefined> {
throw new Error(`Too deep objects in depth ${depth}`);
}

if (object == null) {
const objectIsNil = this.allowUndefinedCustomEncoding ? object === null : object == null
if (objectIsNil) {
this.encodeNil();
} else if (typeof object === "boolean") {
this.encodeBoolean(object);
Expand Down
26 changes: 26 additions & 0 deletions test/ExtensionCodec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,32 @@ describe("ExtensionCodec", () => {
});
});

context("undefined", () => {
const extensionCodec = new ExtensionCodec();

// undefined
extensionCodec.register({
type: 0x1,
encode: (object: unknown): Uint8Array | null => {
if (object === undefined) {
return new Uint8Array(0);
}
return null;
},
decode: (data: Uint8Array) => {
if (data.length === 0) {
return undefined;
}
throw new Error("invalid data");
},
});

it("encodes and decodes undefined (synchronously)", () => {
const encoded = encode([undefined], { extensionCodec, allowUndefinedCustomEncoding: true });
assert.deepStrictEqual(decode(encoded, { extensionCodec }), [undefined]);
});
});

context("custom extensions with custom context", () => {
class Context {
public expectations: Array<any> = [];
Expand Down