11import { Data , List , Message , Struct } from "capnp-ts" ;
2- import { Config } from "./sserve-conf" ;
2+ import { Config , kVoid } from "./sserve-conf" ;
33import { Config as CapnpConfig } from "./sserve-conf.capnp.js" ;
44
55function 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