Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit a7417a7

Browse files
authored
Fix capnproto serialisation of undefined values, closes #371 (#377)
1 parent 4aa7199 commit a7417a7

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

packages/tre/src/runtime/config/index.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Data, List, Message, Struct } from "capnp-ts";
2-
import { Config } from "./sserve-conf";
2+
import { Config, kVoid } from "./sserve-conf";
33
import { Config as CapnpConfig } from "./sserve-conf.capnp.js";
44

55
function capitalize<S extends string>(str: S): Capitalize<S> {
@@ -8,10 +8,14 @@ function capitalize<S extends string>(str: S): Capitalize<S> {
88
) as Capitalize<S>;
99
}
1010

11-
// TODO(important): this will fail if someone sets `{ script: undefined }` or
12-
// something manually, where we're expecting an optional string, need a better
13-
// solution
14-
function encodeCapnpStruct(obj: any, struct: Struct, padding = "") {
11+
// Dynamically encode a capnp struct based on keys and the types of values.
12+
// `obj` should be an instance of a type in `./sserve-conf.ts`. The safety of
13+
// this function relies on getting `./sserve-conf.ts` correct, TypeScript's type
14+
// safety guarantees, and us validating all user input with zod.
15+
//
16+
// TODO: generate `./sserve-conf.ts` and corresponding encoders automatically
17+
// from the `.capnp` file.
18+
function encodeCapnpStruct(obj: any, struct: Struct) {
1519
const anyStruct = struct as any;
1620
for (const [key, value] of Object.entries(obj)) {
1721
const capitalized = capitalize(key);
@@ -22,17 +26,19 @@ function encodeCapnpStruct(obj: any, struct: Struct, padding = "") {
2226
const newList: List<any> = anyStruct[`init${capitalized}`](value.length);
2327
for (let i = 0; i < value.length; i++) {
2428
if (typeof value[i] === "object") {
25-
encodeCapnpStruct(value[i], newList.get(i), padding + " ");
29+
encodeCapnpStruct(value[i], newList.get(i));
2630
} else {
2731
newList.set(i, value[i]);
2832
}
2933
}
3034
} else if (typeof value === "object") {
3135
const newStruct: Struct = anyStruct[`init${capitalized}`]();
32-
encodeCapnpStruct(value, newStruct, padding + " ");
33-
} else {
34-
// TODO: could we catch here if value is actually undefined, but meant to
35-
// be a different type
36+
encodeCapnpStruct(value, newStruct);
37+
} else if (value === kVoid) {
38+
anyStruct[`set${capitalized}`]();
39+
} else if (value !== undefined) {
40+
// Ignore all `undefined` values, explicitly `undefined` values should use
41+
// kVoid symbol instead.
3642
anyStruct[`set${capitalized}`](value);
3743
}
3844
}

0 commit comments

Comments
 (0)