@@ -60,27 +60,7 @@ export interface DeleteChange extends Change {
6060 oldkeys : Keys ;
6161}
6262
63- const parse = ( value : any , typeOid : number ) => {
64- if ( value === null ) return null ;
65- // wal2json always outputs `bool`s as boolean, not as string, irregardless of `numeric-data-types-as-string`.
66- if ( typeOid === pg . types . builtins . BOOL ) return value ;
67- // FIXME: this should use `client.getTypeParser` or have some other non-global option to configure type parsing
68- const parser = pg . types . getTypeParser ( typeOid , "text" ) ;
69- return parser ( value ) ;
70- } ;
71-
72- export const changeToRecord = ( change : InsertChange | UpdateChange ) => {
73- const { columnnames, columnvalues, columntypeoids } = change ;
74- return columnnames . reduce < Record < string , any > > ( ( memo , name , i ) => {
75- memo [ name ] = parse ( columnvalues [ i ] , columntypeoids [ i ] ) ;
76- return memo ;
77- } , { } ) ;
78- } ;
79-
80- export const changeToPk = ( change : UpdateChange | DeleteChange ) => {
81- const { keyvalues, keytypeoids } = change . oldkeys ;
82- return keyvalues . map ( ( value , i ) => parse ( value , keytypeoids [ i ] ) ) ;
83- } ;
63+ const id = < T > ( value : T ) : T => value ;
8464
8565interface Payload {
8666 lsn : string ;
@@ -101,6 +81,8 @@ export interface LdsOptions {
10181 slotName ?: string ;
10282 /** Whether `.createSlot()` should create a temporary replication slot which will be limited to the `client` session and gets cleaned up automatically. Defaults to `false`. */
10383 temporary ?: boolean ;
84+ /** (Custom) [type parsers](https://node-postgres.com/features/queries#types) to deserialise the wal2json column string values. Pass `pg.types` to get the default type parsing. Defaults to `undefined`, that is raw values will get emitted. */
85+ types ?: pg . CustomTypesConfig ;
10486}
10587
10688export default class PgLogicalDecoding extends EventEmitter {
@@ -110,6 +92,7 @@ export default class PgLogicalDecoding extends EventEmitter {
11092 private tablePattern : string ;
11193 private pool : pg . Pool | null ;
11294 private client : Promise < pg . PoolClient > | null ;
95+ private readonly parse : ( value : any , typeOid : number ) => any ;
11396
11497 constructor ( connectionString : string , options ?: LdsOptions ) {
11598 super ( ) ;
@@ -118,10 +101,21 @@ export default class PgLogicalDecoding extends EventEmitter {
118101 tablePattern = "*.*" ,
119102 slotName = "postgraphile" ,
120103 temporary = false ,
104+ types,
121105 } = options || { } ;
122106 this . tablePattern = tablePattern ;
123107 this . slotName = slotName ;
124108 this . temporary = temporary ;
109+ this . parse = types
110+ ? ( value : any , typeOid : number ) => {
111+ if ( value === null ) return null ;
112+ // wal2json always outputs `bool`s as boolean, not as string, irregardless of `numeric-data-types-as-string`.
113+ if ( typeOid === pg . types . builtins . BOOL ) return value ;
114+ // FIXME: this should use `client.getTypeParser` or have some other non-global option to configure type parsing
115+ const parser = pg . types . getTypeParser ( typeOid , "text" ) ;
116+ return parser ( value ) ;
117+ }
118+ : id ;
125119 // We just use the pool to get better error handling
126120 this . pool = new pg . Pool ( {
127121 connectionString : this . connectionString ,
@@ -208,6 +202,23 @@ export default class PgLogicalDecoding extends EventEmitter {
208202 }
209203 }
210204
205+ public changeToRecord (
206+ change : InsertChange | UpdateChange
207+ ) : Record < string , any > {
208+ const { columnnames, columnvalues, columntypeoids } = change ;
209+ return columnnames . reduce < Record < string , any > > ( ( memo , name , i ) => {
210+ memo [ name ] = this . parse ( columnvalues [ i ] , columntypeoids [ i ] ) ;
211+ return memo ;
212+ } , { } ) ;
213+ }
214+
215+ public changeToPk ( change : UpdateChange | DeleteChange ) : any [ ] {
216+ const { keyvalues, keytypeoids } = change . oldkeys ;
217+ return this . parse == id
218+ ? keyvalues
219+ : keyvalues . map ( ( value , i ) => this . parse ( value , keytypeoids [ i ] ) ) ;
220+ }
221+
211222 public async close ( ) {
212223 if ( ! this . temporary ) {
213224 const client = await this . getClient ( ) ;
0 commit comments