@@ -35,16 +35,20 @@ import { base64urlencode } from './base64';
3535 */
3636export type Payload = Record < string , unknown > ;
3737
38+ /**
39+ * An array of tuples which represented the unprocessed JSON to be added to the Payload
40+ */
41+ export type JsonForProcessing = Array < [ keyIfEncoded : string , keyIfNotEncoded : string , json : Record < string , unknown > ] > ;
42+
43+ /**
44+ * A function which will processor the Json onto the injected PayloadBuilder
45+ */
46+ export type JsonProcessor = ( payloadBuilder : PayloadBuilder , jsonForProcessing : JsonForProcessing ) => void ;
47+
3848/**
3949 * Interface for mutable object encapsulating tracker payload
4050 */
4151export interface PayloadBuilder {
42- /**
43- * Sets whether the JSON within the payload should be base64 encoded
44- * @param base64 Toggle for base64 encoding
45- */
46- setBase64Encoding : ( base64 : boolean ) => void ;
47-
4852 /**
4953 * Adds an entry to the Payload
5054 * @param key Key for Payload dictionary entry
@@ -66,55 +70,24 @@ export interface PayloadBuilder {
6670 */
6771 addJson : ( keyIfEncoded : string , keyIfNotEncoded : string , json : Record < string , unknown > ) => void ;
6872
73+ /**
74+ * Adds a function which will be executed when building
75+ * the payload to process the JSON which has been added to this payload
76+ * @param jsonProcessor The JsonProcessor function for this builder
77+ */
78+ withJsonProcessor : ( jsonProcessor : JsonProcessor ) => void ;
79+
6980 /**
7081 * Builds and returns the Payload
7182 * @param base64Encode configures if cached json should be encoded
7283 */
7384 build : ( ) => Payload ;
7485}
7586
76- /**
77- * Is property a non-empty JSON?
78- * @param property Checks if object is non-empty json
79- */
80- export function isNonEmptyJson ( property ?: Record < string , unknown > ) : boolean {
81- if ( ! isJson ( property ) ) {
82- return false ;
83- }
84- for ( const key in property ) {
85- if ( Object . prototype . hasOwnProperty . call ( property , key ) ) {
86- return true ;
87- }
88- }
89- return false ;
90- }
91-
92- /**
93- * Is property a JSON?
94- * @param property Checks if object is json
95- */
96- export function isJson ( property ?: Record < string , unknown > ) : boolean {
97- return (
98- typeof property !== 'undefined' &&
99- property !== null &&
100- ( property . constructor === { } . constructor || property . constructor === [ ] . constructor )
101- ) ;
102- }
103-
104- /**
105- * A helper to build a Snowplow request from a set of name-value pairs, provided using the add methods.
106- * Will base64 encode JSON, if desired, on build
107- *
108- * @return The request builder, with add and build methods
109- */
11087export function payloadBuilder ( ) : PayloadBuilder {
111- const dict : Payload = { } ;
112- const jsonForEncoding : Array < [ string , string , Record < string , unknown > ] > = [ ] ;
113- let encodeBase64 : boolean = true ;
114-
115- const setBase64Encoding = ( base64 : boolean ) => {
116- encodeBase64 = base64 ;
117- } ;
88+ const dict : Payload = { } ,
89+ jsonForProcessing : JsonForProcessing = [ ] ;
90+ let processor : JsonProcessor | undefined ;
11891
11992 const add = ( key : string , value : unknown ) : void => {
12093 if ( value != null && value !== '' ) {
@@ -133,29 +106,68 @@ export function payloadBuilder(): PayloadBuilder {
133106
134107 const addJson = ( keyIfEncoded : string , keyIfNotEncoded : string , json ?: Record < string , unknown > ) : void => {
135108 if ( json && isNonEmptyJson ( json ) ) {
136- jsonForEncoding . push ( [ keyIfEncoded , keyIfNotEncoded , json ] ) ;
109+ jsonForProcessing . push ( [ keyIfEncoded , keyIfNotEncoded , json ] ) ;
137110 }
138111 } ;
139112
140- const build = ( ) : Payload => {
141- for ( const json of jsonForEncoding ) {
113+ return {
114+ add,
115+ addDict,
116+ addJson,
117+ withJsonProcessor : ( jsonProcessor ) => {
118+ processor = jsonProcessor ;
119+ } ,
120+ build : function ( ) {
121+ processor ?.( this , jsonForProcessing ) ;
122+ return dict ;
123+ } ,
124+ } ;
125+ }
126+
127+ /**
128+ * A helper to build a Snowplow request from a set of name-value pairs, provided using the add methods.
129+ * Will base64 encode JSON, if desired, on build
130+ *
131+ * @return The request builder, with add and build methods
132+ */
133+ export function payloadJsonProcessor ( encodeBase64 : boolean ) : JsonProcessor {
134+ return ( payloadBuilder : PayloadBuilder , jsonForProcessing : JsonForProcessing ) => {
135+ for ( const json of jsonForProcessing ) {
142136 const str = JSON . stringify ( json [ 2 ] ) ;
143137 if ( encodeBase64 ) {
144- add ( json [ 0 ] , base64urlencode ( str ) ) ;
138+ payloadBuilder . add ( json [ 0 ] , base64urlencode ( str ) ) ;
145139 } else {
146- add ( json [ 1 ] , str ) ;
140+ payloadBuilder . add ( json [ 1 ] , str ) ;
147141 }
148142 }
149- jsonForEncoding . length = 0 ;
150-
151- return dict ;
143+ jsonForProcessing . length = 0 ;
152144 } ;
145+ }
153146
154- return {
155- setBase64Encoding,
156- add,
157- addDict,
158- addJson,
159- build,
160- } ;
147+ /**
148+ * Is property a non-empty JSON?
149+ * @param property Checks if object is non-empty json
150+ */
151+ export function isNonEmptyJson ( property ?: Record < string , unknown > ) : boolean {
152+ if ( ! isJson ( property ) ) {
153+ return false ;
154+ }
155+ for ( const key in property ) {
156+ if ( Object . prototype . hasOwnProperty . call ( property , key ) ) {
157+ return true ;
158+ }
159+ }
160+ return false ;
161+ }
162+
163+ /**
164+ * Is property a JSON?
165+ * @param property Checks if object is json
166+ */
167+ export function isJson ( property ?: Record < string , unknown > ) : boolean {
168+ return (
169+ typeof property !== 'undefined' &&
170+ property !== null &&
171+ ( property . constructor === { } . constructor || property . constructor === [ ] . constructor )
172+ ) ;
161173}
0 commit comments