@customerio/cdp-analytics-core 0.0.0-test-oidc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/LICENSE.MD +22 -0
  2. package/README.md +3 -0
  3. package/dist/cjs/analytics/dispatch.js +54 -0
  4. package/dist/cjs/analytics/dispatch.js.map +1 -0
  5. package/dist/cjs/analytics/index.js +3 -0
  6. package/dist/cjs/analytics/index.js.map +1 -0
  7. package/dist/cjs/callback/index.js +46 -0
  8. package/dist/cjs/callback/index.js.map +1 -0
  9. package/dist/cjs/connection/index.js +16 -0
  10. package/dist/cjs/connection/index.js.map +1 -0
  11. package/dist/cjs/context/index.js +87 -0
  12. package/dist/cjs/context/index.js.map +1 -0
  13. package/dist/cjs/emitter/index.js +66 -0
  14. package/dist/cjs/emitter/index.js.map +1 -0
  15. package/dist/cjs/emitter/interface.js +3 -0
  16. package/dist/cjs/emitter/interface.js.map +1 -0
  17. package/dist/cjs/events/index.js +154 -0
  18. package/dist/cjs/events/index.js.map +1 -0
  19. package/dist/cjs/events/interfaces.js +3 -0
  20. package/dist/cjs/events/interfaces.js.map +1 -0
  21. package/dist/cjs/index.js +25 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/logger/index.js +62 -0
  24. package/dist/cjs/logger/index.js.map +1 -0
  25. package/dist/cjs/plugins/index.js +3 -0
  26. package/dist/cjs/plugins/index.js.map +1 -0
  27. package/dist/cjs/priority-queue/backoff.js +10 -0
  28. package/dist/cjs/priority-queue/backoff.js.map +1 -0
  29. package/dist/cjs/priority-queue/index.js +92 -0
  30. package/dist/cjs/priority-queue/index.js.map +1 -0
  31. package/dist/cjs/queue/delivery.js +69 -0
  32. package/dist/cjs/queue/delivery.js.map +1 -0
  33. package/dist/cjs/queue/event-queue.js +340 -0
  34. package/dist/cjs/queue/event-queue.js.map +1 -0
  35. package/dist/cjs/stats/index.js +96 -0
  36. package/dist/cjs/stats/index.js.map +1 -0
  37. package/dist/cjs/task/task-group.js +24 -0
  38. package/dist/cjs/task/task-group.js.map +1 -0
  39. package/dist/cjs/user/index.js +3 -0
  40. package/dist/cjs/user/index.js.map +1 -0
  41. package/dist/cjs/utils/bind-all.js +18 -0
  42. package/dist/cjs/utils/bind-all.js.map +1 -0
  43. package/dist/cjs/utils/environment.js +12 -0
  44. package/dist/cjs/utils/environment.js.map +1 -0
  45. package/dist/cjs/utils/get-global.js +21 -0
  46. package/dist/cjs/utils/get-global.js.map +1 -0
  47. package/dist/cjs/utils/group-by.js +28 -0
  48. package/dist/cjs/utils/group-by.js.map +1 -0
  49. package/dist/cjs/utils/has-properties.js +13 -0
  50. package/dist/cjs/utils/has-properties.js.map +1 -0
  51. package/dist/cjs/utils/is-plain-object.js +28 -0
  52. package/dist/cjs/utils/is-plain-object.js.map +1 -0
  53. package/dist/cjs/utils/is-thenable.js +15 -0
  54. package/dist/cjs/utils/is-thenable.js.map +1 -0
  55. package/dist/cjs/utils/p-while.js +25 -0
  56. package/dist/cjs/utils/p-while.js.map +1 -0
  57. package/dist/cjs/utils/pick.js +10 -0
  58. package/dist/cjs/utils/pick.js.map +1 -0
  59. package/dist/cjs/utils/ts-helpers.js +3 -0
  60. package/dist/cjs/utils/ts-helpers.js.map +1 -0
  61. package/dist/cjs/validation/assertions.js +51 -0
  62. package/dist/cjs/validation/assertions.js.map +1 -0
  63. package/dist/cjs/validation/helpers.js +26 -0
  64. package/dist/cjs/validation/helpers.js.map +1 -0
  65. package/dist/esm/analytics/dispatch.js +49 -0
  66. package/dist/esm/analytics/dispatch.js.map +1 -0
  67. package/dist/esm/analytics/index.js +2 -0
  68. package/dist/esm/analytics/index.js.map +1 -0
  69. package/dist/esm/callback/index.js +40 -0
  70. package/dist/esm/callback/index.js.map +1 -0
  71. package/dist/esm/connection/index.js +11 -0
  72. package/dist/esm/connection/index.js.map +1 -0
  73. package/dist/esm/context/index.js +84 -0
  74. package/dist/esm/context/index.js.map +1 -0
  75. package/dist/esm/emitter/index.js +63 -0
  76. package/dist/esm/emitter/index.js.map +1 -0
  77. package/dist/esm/emitter/interface.js +2 -0
  78. package/dist/esm/emitter/interface.js.map +1 -0
  79. package/dist/esm/events/index.js +151 -0
  80. package/dist/esm/events/index.js.map +1 -0
  81. package/dist/esm/events/interfaces.js +2 -0
  82. package/dist/esm/events/interfaces.js.map +1 -0
  83. package/dist/esm/index.js +19 -0
  84. package/dist/esm/index.js.map +1 -0
  85. package/dist/esm/logger/index.js +59 -0
  86. package/dist/esm/logger/index.js.map +1 -0
  87. package/dist/esm/plugins/index.js +2 -0
  88. package/dist/esm/plugins/index.js.map +1 -0
  89. package/dist/esm/priority-queue/backoff.js +6 -0
  90. package/dist/esm/priority-queue/backoff.js.map +1 -0
  91. package/dist/esm/priority-queue/index.js +89 -0
  92. package/dist/esm/priority-queue/index.js.map +1 -0
  93. package/dist/esm/queue/delivery.js +64 -0
  94. package/dist/esm/queue/delivery.js.map +1 -0
  95. package/dist/esm/queue/event-queue.js +337 -0
  96. package/dist/esm/queue/event-queue.js.map +1 -0
  97. package/dist/esm/stats/index.js +93 -0
  98. package/dist/esm/stats/index.js.map +1 -0
  99. package/dist/esm/task/task-group.js +20 -0
  100. package/dist/esm/task/task-group.js.map +1 -0
  101. package/dist/esm/user/index.js +2 -0
  102. package/dist/esm/user/index.js.map +1 -0
  103. package/dist/esm/utils/bind-all.js +14 -0
  104. package/dist/esm/utils/bind-all.js.map +1 -0
  105. package/dist/esm/utils/environment.js +7 -0
  106. package/dist/esm/utils/environment.js.map +1 -0
  107. package/dist/esm/utils/get-global.js +17 -0
  108. package/dist/esm/utils/get-global.js.map +1 -0
  109. package/dist/esm/utils/group-by.js +24 -0
  110. package/dist/esm/utils/group-by.js.map +1 -0
  111. package/dist/esm/utils/has-properties.js +9 -0
  112. package/dist/esm/utils/has-properties.js.map +1 -0
  113. package/dist/esm/utils/is-plain-object.js +24 -0
  114. package/dist/esm/utils/is-plain-object.js.map +1 -0
  115. package/dist/esm/utils/is-thenable.js +11 -0
  116. package/dist/esm/utils/is-thenable.js.map +1 -0
  117. package/dist/esm/utils/p-while.js +21 -0
  118. package/dist/esm/utils/p-while.js.map +1 -0
  119. package/dist/esm/utils/pick.js +6 -0
  120. package/dist/esm/utils/pick.js.map +1 -0
  121. package/dist/esm/utils/ts-helpers.js +2 -0
  122. package/dist/esm/utils/ts-helpers.js.map +1 -0
  123. package/dist/esm/validation/assertions.js +46 -0
  124. package/dist/esm/validation/assertions.js.map +1 -0
  125. package/dist/esm/validation/helpers.js +18 -0
  126. package/dist/esm/validation/helpers.js.map +1 -0
  127. package/dist/types/analytics/dispatch.d.ts +20 -0
  128. package/dist/types/analytics/dispatch.d.ts.map +1 -0
  129. package/dist/types/analytics/index.d.ts +12 -0
  130. package/dist/types/analytics/index.d.ts.map +1 -0
  131. package/dist/types/callback/index.d.ts +11 -0
  132. package/dist/types/callback/index.d.ts.map +1 -0
  133. package/dist/types/connection/index.d.ts +3 -0
  134. package/dist/types/connection/index.d.ts.map +1 -0
  135. package/dist/types/context/index.d.ts +44 -0
  136. package/dist/types/context/index.d.ts.map +1 -0
  137. package/dist/types/emitter/index.d.ts +25 -0
  138. package/dist/types/emitter/index.d.ts.map +1 -0
  139. package/dist/types/emitter/interface.d.ts +27 -0
  140. package/dist/types/emitter/interface.d.ts.map +1 -0
  141. package/dist/types/events/index.d.ts +31 -0
  142. package/dist/types/events/index.d.ts.map +1 -0
  143. package/dist/types/events/interfaces.d.ts +379 -0
  144. package/dist/types/events/interfaces.d.ts.map +1 -0
  145. package/dist/types/index.d.ts +19 -0
  146. package/dist/types/index.d.ts.map +1 -0
  147. package/dist/types/logger/index.d.ts +19 -0
  148. package/dist/types/logger/index.d.ts.map +1 -0
  149. package/dist/types/plugins/index.d.ts +25 -0
  150. package/dist/types/plugins/index.d.ts.map +1 -0
  151. package/dist/types/priority-queue/backoff.d.ts +13 -0
  152. package/dist/types/priority-queue/backoff.d.ts.map +1 -0
  153. package/dist/types/priority-queue/index.d.ts +25 -0
  154. package/dist/types/priority-queue/index.d.ts.map +1 -0
  155. package/dist/types/queue/delivery.d.ts +5 -0
  156. package/dist/types/queue/delivery.d.ts.map +1 -0
  157. package/dist/types/queue/event-queue.d.ts +43 -0
  158. package/dist/types/queue/event-queue.d.ts.map +1 -0
  159. package/dist/types/stats/index.d.ts +34 -0
  160. package/dist/types/stats/index.d.ts.map +1 -0
  161. package/dist/types/task/task-group.d.ts +6 -0
  162. package/dist/types/task/task-group.d.ts.map +1 -0
  163. package/dist/types/user/index.d.ts +6 -0
  164. package/dist/types/user/index.d.ts.map +1 -0
  165. package/dist/types/utils/bind-all.d.ts +4 -0
  166. package/dist/types/utils/bind-all.d.ts.map +1 -0
  167. package/dist/types/utils/environment.d.ts +3 -0
  168. package/dist/types/utils/environment.d.ts.map +1 -0
  169. package/dist/types/utils/get-global.d.ts +2 -0
  170. package/dist/types/utils/get-global.d.ts.map +1 -0
  171. package/dist/types/utils/group-by.d.ts +4 -0
  172. package/dist/types/utils/group-by.d.ts.map +1 -0
  173. package/dist/types/utils/has-properties.d.ts +4 -0
  174. package/dist/types/utils/has-properties.d.ts.map +1 -0
  175. package/dist/types/utils/is-plain-object.d.ts +2 -0
  176. package/dist/types/utils/is-plain-object.d.ts.map +1 -0
  177. package/dist/types/utils/is-thenable.d.ts +6 -0
  178. package/dist/types/utils/is-thenable.d.ts.map +1 -0
  179. package/dist/types/utils/p-while.d.ts +2 -0
  180. package/dist/types/utils/p-while.d.ts.map +1 -0
  181. package/dist/types/utils/pick.d.ts +2 -0
  182. package/dist/types/utils/pick.d.ts.map +1 -0
  183. package/dist/types/utils/ts-helpers.d.ts +13 -0
  184. package/dist/types/utils/ts-helpers.d.ts.map +1 -0
  185. package/dist/types/validation/assertions.d.ts +8 -0
  186. package/dist/types/validation/assertions.d.ts.map +1 -0
  187. package/dist/types/validation/helpers.d.ts +7 -0
  188. package/dist/types/validation/helpers.d.ts.map +1 -0
  189. package/package.json +40 -0
  190. package/src/analytics/dispatch.ts +58 -0
  191. package/src/analytics/index.ts +11 -0
  192. package/src/callback/index.ts +51 -0
  193. package/src/connection/index.ts +13 -0
  194. package/src/context/index.ts +123 -0
  195. package/src/emitter/index.ts +65 -0
  196. package/src/emitter/interface.ts +31 -0
  197. package/src/events/index.ts +285 -0
  198. package/src/events/interfaces.ts +453 -0
  199. package/src/index.ts +18 -0
  200. package/src/logger/index.ts +74 -0
  201. package/src/plugins/index.ts +43 -0
  202. package/src/priority-queue/backoff.ts +24 -0
  203. package/src/priority-queue/index.ts +103 -0
  204. package/src/queue/delivery.ts +73 -0
  205. package/src/queue/event-queue.ts +320 -0
  206. package/src/stats/index.ts +88 -0
  207. package/src/task/task-group.ts +31 -0
  208. package/src/user/index.ts +7 -0
  209. package/src/utils/bind-all.ts +19 -0
  210. package/src/utils/environment.ts +7 -0
  211. package/src/utils/get-global.ts +16 -0
  212. package/src/utils/group-by.ts +30 -0
  213. package/src/utils/has-properties.ts +7 -0
  214. package/src/utils/is-plain-object.ts +26 -0
  215. package/src/utils/is-thenable.ts +9 -0
  216. package/src/utils/p-while.ts +12 -0
  217. package/src/utils/pick.ts +8 -0
  218. package/src/utils/ts-helpers.ts +13 -0
  219. package/src/validation/assertions.ts +54 -0
  220. package/src/validation/helpers.ts +27 -0
@@ -0,0 +1,285 @@
1
+ export * from './interfaces'
2
+ import { dset } from 'dset'
3
+ import { ID, User } from '../user'
4
+ import {
5
+ Integrations,
6
+ EventProperties,
7
+ CoreCustomerioEvent,
8
+ CoreOptions,
9
+ CoreExtraContext,
10
+ UserTraits,
11
+ GroupTraits,
12
+ } from './interfaces'
13
+ import { pickBy } from '../utils/pick'
14
+ import { validateEvent } from '../validation/assertions'
15
+ import type { RemoveIndexSignature } from '../utils/ts-helpers'
16
+
17
+ interface EventFactorySettings {
18
+ createMessageId: () => string
19
+ user?: User
20
+ }
21
+
22
+ /**
23
+ * This is currently only used by node.js, but the original idea was to have something that could be shared between browser and node.
24
+ * Unfortunately, there are some differences in the way the two environments handle events, so this is not currently shared.
25
+ */
26
+ export class EventFactory {
27
+ createMessageId: EventFactorySettings['createMessageId']
28
+ user?: User
29
+
30
+ constructor(settings: EventFactorySettings) {
31
+ this.user = settings.user
32
+ this.createMessageId = settings.createMessageId
33
+ }
34
+
35
+ track(
36
+ event: string,
37
+ properties?: EventProperties,
38
+ options?: CoreOptions,
39
+ globalIntegrations?: Integrations
40
+ ) {
41
+ return this.normalize({
42
+ ...this.baseEvent(),
43
+ event,
44
+ type: 'track',
45
+ properties: properties ?? {}, // TODO: why is this not a shallow copy like everywhere else?
46
+ options: { ...options },
47
+ integrations: { ...globalIntegrations },
48
+ })
49
+ }
50
+
51
+ page(
52
+ category: string | null,
53
+ page: string | null,
54
+ properties?: EventProperties,
55
+ options?: CoreOptions,
56
+ globalIntegrations?: Integrations
57
+ ): CoreCustomerioEvent {
58
+ const event: CoreCustomerioEvent = {
59
+ type: 'page',
60
+ properties: { ...properties },
61
+ options: { ...options },
62
+ integrations: { ...globalIntegrations },
63
+ }
64
+
65
+ if (category !== null) {
66
+ event.category = category
67
+ event.properties = event.properties ?? {}
68
+ event.properties.category = category
69
+ }
70
+
71
+ if (page !== null) {
72
+ event.name = page
73
+ }
74
+
75
+ return this.normalize({
76
+ ...this.baseEvent(),
77
+ ...event,
78
+ })
79
+ }
80
+
81
+ screen(
82
+ category: string | null,
83
+ screen: string | null,
84
+ properties?: EventProperties,
85
+ options?: CoreOptions,
86
+ globalIntegrations?: Integrations
87
+ ): CoreCustomerioEvent {
88
+ const event: CoreCustomerioEvent = {
89
+ type: 'screen',
90
+ properties: { ...properties },
91
+ options: { ...options },
92
+ integrations: { ...globalIntegrations },
93
+ }
94
+
95
+ if (category !== null) {
96
+ event.category = category
97
+ }
98
+
99
+ if (screen !== null) {
100
+ event.name = screen
101
+ }
102
+
103
+ return this.normalize({
104
+ ...this.baseEvent(),
105
+ ...event,
106
+ })
107
+ }
108
+
109
+ identify(
110
+ userId: ID,
111
+ traits?: UserTraits,
112
+ options?: CoreOptions,
113
+ globalIntegrations?: Integrations
114
+ ): CoreCustomerioEvent {
115
+ return this.normalize({
116
+ ...this.baseEvent(),
117
+ type: 'identify',
118
+ userId,
119
+ traits: traits ?? {},
120
+ options: { ...options },
121
+ integrations: globalIntegrations,
122
+ })
123
+ }
124
+
125
+ group(
126
+ groupId: ID,
127
+ traits?: GroupTraits,
128
+ options?: CoreOptions,
129
+ globalIntegrations?: Integrations
130
+ ): CoreCustomerioEvent {
131
+ return this.normalize({
132
+ ...this.baseEvent(),
133
+ type: 'group',
134
+ traits: traits ?? {},
135
+ options: { ...options }, // this spreading is intentional
136
+ integrations: { ...globalIntegrations }, //
137
+ groupId,
138
+ })
139
+ }
140
+
141
+ alias(
142
+ to: string,
143
+ from: string | null, // TODO: can we make this undefined?
144
+ options?: CoreOptions,
145
+ globalIntegrations?: Integrations
146
+ ): CoreCustomerioEvent {
147
+ const base: CoreCustomerioEvent = {
148
+ userId: to,
149
+ type: 'alias',
150
+ options: { ...options },
151
+ integrations: { ...globalIntegrations },
152
+ }
153
+
154
+ if (from !== null) {
155
+ base.previousId = from
156
+ }
157
+
158
+ if (to === undefined) {
159
+ return this.normalize({
160
+ ...base,
161
+ ...this.baseEvent(),
162
+ })
163
+ }
164
+
165
+ return this.normalize({
166
+ ...this.baseEvent(),
167
+ ...base,
168
+ })
169
+ }
170
+
171
+ private baseEvent(): Partial<CoreCustomerioEvent> {
172
+ const base: Partial<CoreCustomerioEvent> = {
173
+ integrations: {},
174
+ options: {},
175
+ }
176
+
177
+ if (!this.user) return base
178
+
179
+ const user = this.user
180
+
181
+ if (user.id()) {
182
+ base.userId = user.id()
183
+ }
184
+
185
+ if (user.anonymousId()) {
186
+ base.anonymousId = user.anonymousId()
187
+ }
188
+
189
+ return base
190
+ }
191
+
192
+ /**
193
+ * Builds the context part of an event based on "foreign" keys that
194
+ * are provided in the `Options` parameter for an Event
195
+ */
196
+ private context(
197
+ options: CoreOptions
198
+ ): [CoreExtraContext, Partial<CoreCustomerioEvent>] {
199
+ type CoreOptionKeys = keyof RemoveIndexSignature<CoreOptions>
200
+ /**
201
+ * If the event options are known keys from this list, we move them to the top level of the event.
202
+ * Any other options are moved to context.
203
+ */
204
+ const eventOverrideKeys: CoreOptionKeys[] = [
205
+ 'userId',
206
+ 'anonymousId',
207
+ 'timestamp',
208
+ 'messageId',
209
+ ]
210
+
211
+ delete options['integrations']
212
+ const providedOptionsKeys = Object.keys(options) as Exclude<
213
+ CoreOptionKeys,
214
+ 'integrations'
215
+ >[]
216
+
217
+ const context = options.context ?? {}
218
+ const eventOverrides = {}
219
+
220
+ providedOptionsKeys.forEach((key) => {
221
+ if (key === 'context') {
222
+ return
223
+ }
224
+
225
+ if (eventOverrideKeys.includes(key)) {
226
+ dset(eventOverrides, key, options[key])
227
+ } else {
228
+ dset(context, key, options[key])
229
+ }
230
+ })
231
+
232
+ return [context, eventOverrides]
233
+ }
234
+
235
+ public normalize(event: CoreCustomerioEvent): CoreCustomerioEvent {
236
+ const integrationBooleans = Object.keys(event.integrations ?? {}).reduce(
237
+ (integrationNames, name) => {
238
+ return {
239
+ ...integrationNames,
240
+ [name]: Boolean(event.integrations?.[name]),
241
+ }
242
+ },
243
+ {} as Record<string, boolean>
244
+ )
245
+
246
+ // filter out any undefined options
247
+ event.options = pickBy(event.options || {}, (_, value) => {
248
+ return value !== undefined
249
+ })
250
+
251
+ // This is pretty trippy, but here's what's going on:
252
+ // - a) We don't pass initial integration options as part of the event, only if they're true or false
253
+ // - b) We do accept per integration overrides (like integrations.Amplitude.sessionId) at the event level
254
+ // Hence the need to convert base integration options to booleans, but maintain per event integration overrides
255
+ const allIntegrations = {
256
+ // Base config integrations object as booleans
257
+ ...integrationBooleans,
258
+
259
+ // Per event overrides, for things like amplitude sessionId, for example
260
+ ...event.options?.integrations,
261
+ }
262
+
263
+ const [context, overrides] = event.options
264
+ ? this.context(event.options)
265
+ : []
266
+
267
+ const { options, ...rest } = event
268
+
269
+ const body = {
270
+ timestamp: new Date(),
271
+ ...rest,
272
+ integrations: allIntegrations,
273
+ context,
274
+ ...overrides,
275
+ }
276
+
277
+ const evt: CoreCustomerioEvent = {
278
+ ...body,
279
+ messageId: options.messageId || this.createMessageId(),
280
+ }
281
+
282
+ validateEvent(evt)
283
+ return evt
284
+ }
285
+ }
@@ -0,0 +1,453 @@
1
+ import { CoreContext } from '../context'
2
+ import { ID } from '../user'
3
+ import { DeepNullable } from '../utils/ts-helpers'
4
+
5
+ export type Callback<Ctx extends CoreContext = CoreContext> = (
6
+ ctx: Ctx
7
+ ) => Promise<unknown> | unknown
8
+
9
+ export type CustomerioEventType =
10
+ | 'track'
11
+ | 'page'
12
+ | 'identify'
13
+ | 'group'
14
+ | 'alias'
15
+ | 'screen'
16
+
17
+ export type JSONPrimitive = string | number | boolean | null
18
+ export type JSONValue = JSONPrimitive | JSONObject | JSONArray
19
+ export type JSONObject = { [member: string]: JSONValue }
20
+ export type JSONArray = JSONValue[]
21
+
22
+ export type EventProperties = Record<string, any>
23
+
24
+ export type Integrations = {
25
+ All?: boolean
26
+ [integration: string]: boolean | JSONObject | undefined
27
+ }
28
+
29
+ export interface CoreOptions {
30
+ integrations?: Integrations
31
+ timestamp?: Timestamp
32
+ context?: CoreExtraContext
33
+ anonymousId?: string
34
+ userId?: string
35
+ traits?: Traits
36
+ /**
37
+ * Override the messageId. Under normal circumstances, this is not recommended -- but necessary for deduping events.
38
+ *
39
+ * **Currently, This option only works in `@customerio/cdp-analytics-node`.**
40
+ */
41
+ messageId?: string
42
+ // ugh, this is ugly, but we allow literally any property to be passed to options (which get spread onto the event)
43
+ [key: string]: any
44
+ }
45
+
46
+ /**
47
+ * Context is a dictionary of extra information that provides useful context about a datapoint, for example the user’s ip address or locale. You should only use Context fields for their intended meaning.
48
+ */
49
+ export interface CoreExtraContext {
50
+ /**
51
+ * This is usually used to flag an .identify() call to just update the trait, rather than "last seen".
52
+ */
53
+ active?: boolean
54
+
55
+ /**
56
+ * Current user's IP address.
57
+ */
58
+ ip?: string
59
+
60
+ /**
61
+ * Locale string for the current user, for example en-US.
62
+ * @example en-US
63
+ */
64
+ locale?: string
65
+ /**
66
+ * Dictionary of information about the user’s current location.
67
+ */
68
+ location?: {
69
+ /**
70
+ * @example San Francisco
71
+ */
72
+ city?: string
73
+ /**
74
+ * @example United States
75
+ */
76
+ country?: string
77
+ /**
78
+ * @example 40.2964197
79
+ */
80
+ latitude?: string
81
+ /**
82
+ * @example -76.9411617
83
+ */
84
+ longitude?: string
85
+ /**
86
+ * @example CA
87
+ */
88
+ region?: string
89
+ /**
90
+ * @example 100
91
+ */
92
+ speed?: number
93
+ }
94
+
95
+ /**
96
+ * Dictionary of information about the current web page.
97
+ */
98
+ page?: {
99
+ /**
100
+ * @example /academy/
101
+ */
102
+ path?: string
103
+ /**
104
+ * @example https://www.foo.com/
105
+ */
106
+ referrer?: string
107
+ /**
108
+ * @example projectId=123
109
+ */
110
+ search?: string
111
+ /**
112
+ * @example Analytics Academy
113
+ */
114
+ title?: string
115
+ /**
116
+ * @example https://foobar.com/academy/
117
+ */
118
+ url?: string
119
+ }
120
+
121
+ /**
122
+ * User agent of the device making the request.
123
+ */
124
+ userAgent?: string
125
+
126
+ /**
127
+ * Information about the current library.
128
+ *
129
+ * **Automatically filled out by the library.**
130
+ *
131
+ * This type should probably be "never"
132
+ */
133
+ library?: {
134
+ /**
135
+ * @example analytics-node-next/latest
136
+ */
137
+ name: string
138
+ /**
139
+ * @example "1.43.1"
140
+ */
141
+ version: string
142
+ }
143
+
144
+ /**
145
+ * This is useful in cases where you need to track an event,
146
+ * but also associate information from a previous identify call.
147
+ * You should fill this object the same way you would fill traits in an identify call.
148
+ */
149
+ traits?: Traits
150
+
151
+ /**
152
+ * Dictionary of information about the campaign that resulted in the API call, containing name, source, medium, term, content, and any other custom UTM parameter.
153
+ */
154
+ campaign?: {
155
+ name: string
156
+ term: string
157
+ source: string
158
+ medium: string
159
+ content: string
160
+ }
161
+
162
+ /**
163
+ * Dictionary of information about the way the user was referred to the website or app.
164
+ */
165
+ referrer?: {
166
+ type?: string
167
+ name?: string
168
+ url?: string
169
+ link?: string
170
+
171
+ id?: string // undocumented
172
+ btid?: string // undocumented?
173
+ urid?: string // undocumented?
174
+ }
175
+
176
+ amp?: {
177
+ // undocumented?
178
+ id: string
179
+ }
180
+
181
+ [key: string]: any
182
+ }
183
+
184
+ export interface CoreCustomerioEvent {
185
+ messageId?: string
186
+ type: CustomerioEventType
187
+
188
+ // page specific
189
+ category?: string
190
+ name?: string
191
+
192
+ properties?: EventProperties
193
+
194
+ traits?: Traits // Traits is only defined in 'identify' and 'group', even if it can be passed in other calls.
195
+
196
+ integrations?: Integrations
197
+ context?: CoreExtraContext
198
+ options?: CoreOptions
199
+
200
+ userId?: ID
201
+ anonymousId?: ID
202
+ groupId?: ID
203
+ previousId?: ID
204
+
205
+ event?: string
206
+
207
+ writeKey?: string
208
+
209
+ sentAt?: Date
210
+
211
+ _metadata?: CustomerioEventMetadata
212
+
213
+ timestamp?: Timestamp
214
+ }
215
+
216
+ export interface CustomerioEventMetadata {
217
+ failedInitializations?: unknown[]
218
+ bundled?: string[]
219
+ unbundled?: string[]
220
+ nodeVersion?: string
221
+ bundledConfigIds?: string[]
222
+ unbundledConfigIds?: string[]
223
+ bundledIds?: string[]
224
+ }
225
+
226
+ export type Timestamp = Date | string
227
+
228
+ /**
229
+ * A Plan allows users to specify events and which destinations they would like them to be sent to
230
+ */
231
+ export interface Plan {
232
+ track?: TrackPlan
233
+ identify?: TrackPlan
234
+ group?: TrackPlan
235
+ }
236
+
237
+ export interface TrackPlan {
238
+ [key: string]: PlanEvent | undefined
239
+ // __default SHOULD always exist, but marking as optional for extra safety.
240
+ __default?: PlanEvent
241
+ }
242
+
243
+ export interface PlanEvent {
244
+ /**
245
+ * Whether or not this plan event is enabled
246
+ */
247
+ enabled: boolean
248
+ /**
249
+ * Which integrations the plan event applies to
250
+ */
251
+ integrations?: {
252
+ [key: string]: boolean
253
+ }
254
+ }
255
+
256
+ type DbId = string | number // TODO: the docs says that this can only be a string?
257
+ type PhoneNumber = string | number // TODO: the docs say this can only be a string?
258
+
259
+ /**
260
+ * Traits are pieces of information you know about a group.
261
+ */
262
+ type BaseGroupTraits = DeepNullable<{
263
+ /**
264
+ * Street address of a group.
265
+ */
266
+ address?: BaseUserTraits['address']
267
+
268
+ /**
269
+ * URL to an avatar image for the group.
270
+ */
271
+ avatar?: BaseUserTraits['avatar']
272
+
273
+ /**
274
+ * Date the group's account was first created. We recommend ISO-8601 date strings.
275
+ */
276
+ createdAt?: BaseUserTraits['createdAt']
277
+
278
+ /**
279
+ * Description of a group
280
+ */
281
+ description?: BaseUserTraits['description']
282
+ /**
283
+ * Email address of group.
284
+ */
285
+ email?: BaseUserTraits['email']
286
+ /**
287
+ * Number of employees of a group, typically used for companies.
288
+ */
289
+ employees?: string | number // TODO: the docs says that this must be a string?
290
+
291
+ /**
292
+ * Unique ID in your database for a group.
293
+ */
294
+ id?: BaseUserTraits['id']
295
+
296
+ /**
297
+ * Industry a group is part of.
298
+ */
299
+ industry?: BaseUserTraits['industry']
300
+
301
+ /**
302
+ * Name of a group.
303
+ */
304
+ name?: BaseUserTraits['name']
305
+
306
+ /**
307
+ * Phone number of a group
308
+ */
309
+ phone?: BaseUserTraits['phone']
310
+
311
+ /**
312
+ * Website of a group.
313
+ */
314
+ website?: BaseUserTraits['website']
315
+
316
+ /**
317
+ * Plan that a group is in.
318
+ */
319
+ plan?: BaseUserTraits['plan']
320
+ }>
321
+
322
+ /**
323
+ * Traits are pieces of information you know about a user.
324
+ */
325
+ type BaseUserTraits = DeepNullable<{
326
+ /**
327
+ * Unique ID in your database for a user
328
+ */
329
+ id?: DbId
330
+
331
+ /**
332
+ * Industry a user works in
333
+ */
334
+ industry?: string
335
+
336
+ /**
337
+ * First name of a user.
338
+ */
339
+ firstName?: string
340
+
341
+ /**
342
+ * Last name of a user.
343
+ */
344
+ lastName?: string
345
+
346
+ /**
347
+ * Full name of a user. If you only pass a first and last name we will automatically fill in the full name for you.
348
+ */
349
+ name?: string
350
+
351
+ /**
352
+ * Phone number of a user
353
+ */
354
+ phone?: PhoneNumber
355
+
356
+ /**
357
+ * Title of a user, usually related to their position at a specific company.
358
+ * @example VP of Engineering
359
+ */
360
+ title?: string
361
+
362
+ /**
363
+ * User's username. This should be unique to each user, like the usernames of Twitter or GitHub.
364
+ */
365
+ username?: string
366
+
367
+ /**
368
+ * Website of a user.
369
+ */
370
+ website?: string
371
+
372
+ /**
373
+ * Street address of a user.
374
+ */
375
+ address?: {
376
+ city?: string
377
+ country?: string
378
+ postalCode?: string
379
+ state?: string
380
+ street?: string
381
+ }
382
+ /**
383
+ * Age of a user.
384
+ */
385
+ age?: number
386
+
387
+ /**
388
+ * URL to an avatar image for the user.
389
+ */
390
+ avatar?: string
391
+
392
+ /**
393
+ * User's birthday.
394
+ */
395
+ birthday?: Timestamp
396
+
397
+ /**
398
+ * User's company.
399
+ */
400
+ company?: {
401
+ name?: string
402
+ id?: DbId
403
+ industry?: BaseUserTraits['industry']
404
+ employee_count?: number
405
+ plan?: BaseUserTraits['plan']
406
+ }
407
+
408
+ /**
409
+ Plan that a user is in.
410
+
411
+ * @example enterprise
412
+ */
413
+ plan?: string
414
+
415
+ /**
416
+ * Date the user's account was first created. We recommend using ISO-8601 date strings.
417
+ */
418
+ createdAt?: Timestamp
419
+
420
+ /**
421
+ * Description of user, such as bio.
422
+ */
423
+ description?: string
424
+
425
+ /**
426
+ * Email address of a user.
427
+ */
428
+ email?: string
429
+
430
+ /**
431
+ * @example female
432
+ */
433
+ gender?: string
434
+ }>
435
+
436
+ /**
437
+ * Traits are pieces of information you know about a group.
438
+ */
439
+ export type GroupTraits = BaseGroupTraits & {
440
+ [customTrait: string]: any
441
+ }
442
+
443
+ /**
444
+ * Traits are pieces of information you know about a user.
445
+ */
446
+ export type UserTraits = BaseUserTraits & {
447
+ [customTrait: string]: any
448
+ }
449
+
450
+ /**
451
+ * Traits are pieces of information you know about a user or group.
452
+ */
453
+ export type Traits = UserTraits | GroupTraits