@@ -35,16 +35,20 @@ import { base64urlencode } from './base64';
35
35
*/
36
36
export type Payload = Record < string , unknown > ;
37
37
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
+
38
48
/**
39
49
* Interface for mutable object encapsulating tracker payload
40
50
*/
41
51
export 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
-
48
52
/**
49
53
* Adds an entry to the Payload
50
54
* @param key Key for Payload dictionary entry
@@ -66,55 +70,24 @@ export interface PayloadBuilder {
66
70
*/
67
71
addJson : ( keyIfEncoded : string , keyIfNotEncoded : string , json : Record < string , unknown > ) => void ;
68
72
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
+
69
80
/**
70
81
* Builds and returns the Payload
71
82
* @param base64Encode configures if cached json should be encoded
72
83
*/
73
84
build : ( ) => Payload ;
74
85
}
75
86
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
- */
110
87
export 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 ;
118
91
119
92
const add = ( key : string , value : unknown ) : void => {
120
93
if ( value != null && value !== '' ) {
@@ -133,29 +106,68 @@ export function payloadBuilder(): PayloadBuilder {
133
106
134
107
const addJson = ( keyIfEncoded : string , keyIfNotEncoded : string , json ?: Record < string , unknown > ) : void => {
135
108
if ( json && isNonEmptyJson ( json ) ) {
136
- jsonForEncoding . push ( [ keyIfEncoded , keyIfNotEncoded , json ] ) ;
109
+ jsonForProcessing . push ( [ keyIfEncoded , keyIfNotEncoded , json ] ) ;
137
110
}
138
111
} ;
139
112
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 ) {
142
136
const str = JSON . stringify ( json [ 2 ] ) ;
143
137
if ( encodeBase64 ) {
144
- add ( json [ 0 ] , base64urlencode ( str ) ) ;
138
+ payloadBuilder . add ( json [ 0 ] , base64urlencode ( str ) ) ;
145
139
} else {
146
- add ( json [ 1 ] , str ) ;
140
+ payloadBuilder . add ( json [ 1 ] , str ) ;
147
141
}
148
142
}
149
- jsonForEncoding . length = 0 ;
150
-
151
- return dict ;
143
+ jsonForProcessing . length = 0 ;
152
144
} ;
145
+ }
153
146
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
+ ) ;
161
173
}
0 commit comments