@engage_so/core 2.0.10 → 2.2.0
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.
- package/.github/workflows/test.yml +75 -0
- package/README.md +14 -0
- package/jest.config.js +1 -1
- package/package.json +5 -10
- package/src/index.ts +204 -81
- package/tests/index.test.ts +50 -50
- package/tests/oop.test.ts +41 -0
- package/tests/overloads.test.ts +133 -0
- package/tests/overriding.test.ts +121 -0
- package/tsconfig.json +2 -3
- package/.eslintignore +0 -3
- package/dist/error.d.ts +0 -4
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -10
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -257
@@ -0,0 +1,75 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
workflow_dispatch: # Allow manual trigger
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
node-version: [18.x, 20.x, 22.x]
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- name: Checkout code
|
20
|
+
uses: actions/checkout@v4
|
21
|
+
|
22
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
23
|
+
uses: actions/setup-node@v4
|
24
|
+
with:
|
25
|
+
node-version: ${{ matrix.node-version }}
|
26
|
+
cache: 'npm'
|
27
|
+
|
28
|
+
- name: Install dependencies
|
29
|
+
run: npm ci
|
30
|
+
|
31
|
+
- name: Build project
|
32
|
+
run: npm run build
|
33
|
+
|
34
|
+
- name: Run tests
|
35
|
+
run: npm test
|
36
|
+
env:
|
37
|
+
KEY: ${{ secrets.ENGAGE_API_KEY }}
|
38
|
+
SECRET: ${{ secrets.ENGAGE_API_SECRET }}
|
39
|
+
|
40
|
+
- name: Upload test results
|
41
|
+
uses: actions/upload-artifact@v4
|
42
|
+
if: always()
|
43
|
+
with:
|
44
|
+
name: test-results-node-${{ matrix.node-version }}
|
45
|
+
path: |
|
46
|
+
coverage/
|
47
|
+
test-results.xml
|
48
|
+
retention-days: 7
|
49
|
+
|
50
|
+
build-check:
|
51
|
+
runs-on: ubuntu-latest
|
52
|
+
|
53
|
+
steps:
|
54
|
+
- name: Checkout code
|
55
|
+
uses: actions/checkout@v4
|
56
|
+
|
57
|
+
- name: Setup Node.js
|
58
|
+
uses: actions/setup-node@v4
|
59
|
+
with:
|
60
|
+
node-version: '20.x'
|
61
|
+
cache: 'npm'
|
62
|
+
|
63
|
+
- name: Install dependencies
|
64
|
+
run: npm ci
|
65
|
+
|
66
|
+
- name: Build project
|
67
|
+
run: npm run build
|
68
|
+
|
69
|
+
- name: Check build output
|
70
|
+
run: |
|
71
|
+
echo "Checking if dist files were created..."
|
72
|
+
ls -la dist/
|
73
|
+
echo "Checking TypeScript declaration files..."
|
74
|
+
ls -la dist/*.d.ts
|
75
|
+
echo "Build successful!"
|
package/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Engage JavaScript SDK
|
2
|
+
|
3
|
+
Engage is all you need to deliver personalized customer messaging and marketing automation through email, SMS and in-app messaging. The JavaScript SDK allows you to automatically capture user attributes and actions on your site or application.
|
4
|
+
|
5
|
+
[Learn more about the JavaScript SDK](https://docs.engage.so/en-us/a/62bbdd2f5bfea4dca4834046-javascript)
|
6
|
+
|
7
|
+
## Getting Started
|
8
|
+
|
9
|
+
- [Create an Engage account](https://engage.so/) and setup an account to get your API key
|
10
|
+
- Follow the [integration guide](https://docs.engage.so/en-us/a/62bbdd2f5bfea4dca4834046-javascript)
|
11
|
+
|
12
|
+
## License
|
13
|
+
|
14
|
+
MIT
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"name": "@engage_so/core",
|
3
|
-
"version": "2.0
|
4
|
-
"description": "Engage
|
3
|
+
"version": "2.2.0",
|
4
|
+
"description": "Engage JavaScript SDK (core)",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"types": "./dist/index.d.ts",
|
7
7
|
"scripts": {
|
8
8
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
9
|
-
"build": "tsc -p tsconfig.json",
|
10
|
-
"
|
11
|
-
},
|
12
|
-
"publishConfig": {
|
13
|
-
"access": "public"
|
9
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
10
|
+
"prepare": "npm run build"
|
14
11
|
},
|
15
12
|
"author": "Engage",
|
16
13
|
"license": "MIT",
|
@@ -23,8 +20,6 @@
|
|
23
20
|
"ts-standard": "^12.0.2"
|
24
21
|
},
|
25
22
|
"dependencies": {
|
26
|
-
"buffer": "^6.0.3",
|
27
23
|
"cross-fetch": "^4.0.0"
|
28
|
-
}
|
29
|
-
"gitHead": "707f8f2a8d6b697d26395f5d25885f75bee3e355"
|
24
|
+
}
|
30
25
|
}
|
package/src/index.ts
CHANGED
@@ -8,11 +8,11 @@ if (typeof btoa === 'undefined') {
|
|
8
8
|
}
|
9
9
|
}
|
10
10
|
|
11
|
-
interface Key {
|
11
|
+
export interface Key {
|
12
12
|
key?: string
|
13
13
|
secret?: string
|
14
14
|
}
|
15
|
-
interface EventParameter {
|
15
|
+
export interface EventParameter {
|
16
16
|
event: string
|
17
17
|
value?: string | number | Date | boolean
|
18
18
|
properties?: {
|
@@ -20,10 +20,10 @@ interface EventParameter {
|
|
20
20
|
}
|
21
21
|
timestamp?: string | number | Date
|
22
22
|
}
|
23
|
-
|
23
|
+
export interface UserAttrParams {
|
24
24
|
[key: string]: string | number | Date | boolean
|
25
25
|
}
|
26
|
-
type UserIdentifyParams = UserAttrParams & { id: string }
|
26
|
+
export type UserIdentifyParams = UserAttrParams & { id: string }
|
27
27
|
type DataParameters = {
|
28
28
|
[key: string]: string | number | Date | boolean
|
29
29
|
} & {
|
@@ -31,7 +31,7 @@ type DataParameters = {
|
|
31
31
|
[key: string]: string | number | Date | boolean
|
32
32
|
}
|
33
33
|
}
|
34
|
-
type Methods = 'POST' | 'PUT' | 'DELETE'
|
34
|
+
type Methods = 'POST' | 'PUT' | 'DELETE' | 'GET'
|
35
35
|
// type UserIdentifyParams = {
|
36
36
|
// id: string
|
37
37
|
// [key: string]: string | number | Date | boolean
|
@@ -40,21 +40,39 @@ type Methods = 'POST' | 'PUT' | 'DELETE'
|
|
40
40
|
|
41
41
|
// const rootURL = 'https://api.engage.so/v1'
|
42
42
|
let auth: string = ''
|
43
|
+
let currentUserId: string = ''
|
43
44
|
const notMeta = ['created_at', 'is_account', 'number', 'device_token', 'device_platform', 'email', 'first_name', 'last_name', 'tz', 'app_version', 'app_build', 'app_last_active']
|
44
45
|
const apiRoot = 'https://api.engage.so/v1'
|
45
46
|
|
46
|
-
|
47
|
+
function isNull (v: any | null | undefined): boolean {
|
48
|
+
return (v === null || v === undefined)
|
49
|
+
}
|
50
|
+
function isNullString (v: string | null | undefined): boolean {
|
51
|
+
return (v === null || v === undefined || v === '')
|
52
|
+
}
|
53
|
+
|
54
|
+
function resolveUserId (uid?: string): string {
|
55
|
+
if (!isNullString(uid)) {
|
56
|
+
return uid as string
|
57
|
+
}
|
58
|
+
if (isNullString(currentUserId)) {
|
59
|
+
throw new EngageError('User ID missing. Call identify() first or provide a uid parameter.')
|
60
|
+
}
|
61
|
+
return currentUserId
|
62
|
+
}
|
63
|
+
|
64
|
+
async function _request (url: string, params: Record<string, any> | null | undefined, method: Methods): Promise<object> {
|
47
65
|
try {
|
48
66
|
const o: any = {
|
49
67
|
method,
|
50
68
|
headers: {
|
51
69
|
'Content-Type': 'application/json;charset=utf-8',
|
52
70
|
Authorization: `Basic ${auth}`
|
53
|
-
}
|
71
|
+
}
|
54
72
|
// throwHttpErrors: false,
|
55
73
|
// prefixUrl: rootURL
|
56
74
|
}
|
57
|
-
if (params) {
|
75
|
+
if (!isNull(params)) {
|
58
76
|
o.body = JSON.stringify(params)
|
59
77
|
}
|
60
78
|
// const response = await ky(url, o)
|
@@ -62,7 +80,7 @@ async function _request (url: string, params: Record<string, any> | null, method
|
|
62
80
|
const body: any = await response.json()
|
63
81
|
let error = 'API connection error'
|
64
82
|
if (!response.ok) {
|
65
|
-
if (body
|
83
|
+
if (typeof body?.error === 'string') {
|
66
84
|
error = body.error
|
67
85
|
}
|
68
86
|
return { error }
|
@@ -74,45 +92,49 @@ async function _request (url: string, params: Record<string, any> | null, method
|
|
74
92
|
}
|
75
93
|
// Alias of _request method
|
76
94
|
// Same with _request for now but can later have modifications
|
77
|
-
export function request (url: string, params: Record<string, any> | null, method: Methods): object {
|
78
|
-
return _request(url, params, method)
|
95
|
+
export async function request (url: string, params: Record<string, any> | null | undefined, method: Methods = 'GET'): Promise<object> {
|
96
|
+
return await _request(url, params, method)
|
79
97
|
}
|
80
98
|
|
81
|
-
export function init (key: Key | string) {
|
82
|
-
if (
|
99
|
+
export function init (key: Key | string): void {
|
100
|
+
if (isNull(key)) {
|
83
101
|
throw new EngageError('You need to pass in your API key(s).')
|
84
102
|
}
|
103
|
+
|
104
|
+
// Clear any stored user ID when reinitializing
|
105
|
+
currentUserId = ''
|
106
|
+
|
85
107
|
const options: Key = {
|
86
|
-
key:
|
108
|
+
key: '',
|
87
109
|
secret: ''
|
88
110
|
}
|
89
111
|
if (typeof key === 'string') {
|
112
|
+
if (key === '') {
|
113
|
+
throw new EngageError('`key` is empty.')
|
114
|
+
}
|
90
115
|
options.key = key
|
91
116
|
} else {
|
92
|
-
if (
|
117
|
+
if (isNullString(key.key)) {
|
93
118
|
throw new EngageError('`key` missing in object.')
|
94
119
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
if (key.secret) {
|
99
|
-
options.secret = `${key.secret}`
|
120
|
+
options.key = key.key
|
121
|
+
if (!isNullString(key.secret)) {
|
122
|
+
options.secret = key.secret
|
100
123
|
}
|
101
124
|
}
|
102
125
|
// Set auth
|
103
|
-
|
104
|
-
auth = btoa(`${options.key}:${options.secret}`)
|
126
|
+
auth = btoa(`${options.key ?? ''}:${options.secret ?? ''}`)
|
105
127
|
}
|
106
128
|
|
107
129
|
// Data tracking
|
108
|
-
export async function identify (user: UserIdentifyParams) {
|
109
|
-
if (
|
130
|
+
export async function identify (user: UserIdentifyParams): Promise<object> {
|
131
|
+
if (isNull(user)) {
|
110
132
|
throw new EngageError('You need to pass an object with at least an id.')
|
111
133
|
}
|
112
|
-
if (
|
134
|
+
if (isNullString(user.id)) {
|
113
135
|
throw new EngageError('ID missing.')
|
114
136
|
}
|
115
|
-
if (user.email && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
|
137
|
+
if (!isNull(user.email) && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
|
116
138
|
throw new EngageError('Email invalid.')
|
117
139
|
}
|
118
140
|
const params: DataParameters = {}
|
@@ -125,118 +147,219 @@ export async function identify (user: UserIdentifyParams) {
|
|
125
147
|
}
|
126
148
|
}
|
127
149
|
|
128
|
-
|
150
|
+
// Store the user ID for use in other functions
|
151
|
+
currentUserId = user.id
|
152
|
+
|
153
|
+
return await _request(`/users/${user.id}`, params, 'PUT')
|
129
154
|
}
|
130
|
-
|
131
|
-
|
132
|
-
|
155
|
+
|
156
|
+
// Overloaded function signatures for addAttribute
|
157
|
+
export async function addAttribute (attributes: UserAttrParams): Promise<object>
|
158
|
+
export async function addAttribute (uid: string, attributes: UserAttrParams): Promise<object>
|
159
|
+
export async function addAttribute (uidOrAttributes: string | UserAttrParams, attributes?: UserAttrParams): Promise<object> {
|
160
|
+
let uid: string
|
161
|
+
let attrs: UserAttrParams
|
162
|
+
|
163
|
+
// Handle overloaded parameters
|
164
|
+
if (typeof uidOrAttributes === 'string') {
|
165
|
+
uid = resolveUserId(uidOrAttributes)
|
166
|
+
if (isNull(attributes)) {
|
167
|
+
throw new EngageError('Attributes missing when uid is provided.')
|
168
|
+
}
|
169
|
+
attrs = attributes as UserAttrParams
|
170
|
+
} else {
|
171
|
+
uid = resolveUserId()
|
172
|
+
attrs = uidOrAttributes
|
133
173
|
}
|
134
|
-
|
174
|
+
|
175
|
+
if (isNull(attrs)) {
|
135
176
|
throw new EngageError('Attributes missing.')
|
136
177
|
}
|
137
|
-
if (
|
178
|
+
if (Object.keys(attrs).length === 0) {
|
138
179
|
throw new EngageError('Attributes missing.')
|
139
180
|
}
|
140
181
|
const params: DataParameters = {}
|
141
182
|
params.meta = {}
|
142
|
-
for (const k in
|
183
|
+
for (const k in attrs) {
|
143
184
|
if (notMeta.includes(k)) {
|
144
|
-
params[k] =
|
185
|
+
params[k] = attrs[k]
|
145
186
|
} else {
|
146
|
-
params.meta[k] =
|
147
|
-
Object.assign(params.meta, k, attributes[k])
|
187
|
+
params.meta[k] = attrs[k]
|
148
188
|
}
|
149
189
|
}
|
150
|
-
if (Object.keys(params.meta).length) {
|
190
|
+
if (Object.keys(params.meta).length === 0) {
|
151
191
|
delete params.meta
|
152
192
|
}
|
153
193
|
|
154
|
-
return _request(`/users/${uid}`, params, 'PUT')
|
194
|
+
return await _request(`/users/${uid}`, params, 'PUT')
|
155
195
|
}
|
156
|
-
|
157
|
-
|
158
|
-
|
196
|
+
|
197
|
+
// Overloaded function signatures for track
|
198
|
+
export async function track (data: EventParameter): Promise<object>
|
199
|
+
export async function track (uid: string, data: EventParameter): Promise<object>
|
200
|
+
export async function track (uidOrData: string | EventParameter, data?: EventParameter): Promise<object> {
|
201
|
+
let uid: string
|
202
|
+
let eventData: EventParameter
|
203
|
+
|
204
|
+
// Handle overloaded parameters
|
205
|
+
if (typeof uidOrData === 'string') {
|
206
|
+
uid = resolveUserId(uidOrData)
|
207
|
+
if (isNull(data)) {
|
208
|
+
throw new EngageError('Event data missing when uid is provided.')
|
209
|
+
}
|
210
|
+
eventData = data as EventParameter
|
211
|
+
} else {
|
212
|
+
uid = resolveUserId()
|
213
|
+
eventData = uidOrData
|
159
214
|
}
|
160
|
-
|
215
|
+
|
216
|
+
if (isNull(eventData)) {
|
161
217
|
throw new EngageError('Event data missing.')
|
162
218
|
}
|
163
|
-
if (typeof
|
164
|
-
|
165
|
-
event:
|
219
|
+
if (typeof eventData === 'string') {
|
220
|
+
eventData = {
|
221
|
+
event: eventData,
|
166
222
|
value: true
|
167
223
|
}
|
168
224
|
} else {
|
169
|
-
if (
|
225
|
+
if (Object.keys(eventData).length === 0) {
|
170
226
|
throw new EngageError('Attributes missing.')
|
171
227
|
}
|
172
228
|
}
|
173
229
|
|
174
|
-
return _request(`/users/${uid}/events`,
|
230
|
+
return await _request(`/users/${uid}/events`, eventData, 'POST')
|
175
231
|
}
|
176
232
|
|
177
|
-
|
178
|
-
|
179
|
-
|
233
|
+
// Overloaded function signatures for merge
|
234
|
+
export async function merge (destinationUid: string): Promise<object>
|
235
|
+
export async function merge (sourceUid: string, destinationUid: string): Promise<object>
|
236
|
+
export async function merge (sourceOrDestinationUid: string, destinationUid?: string): Promise<object> {
|
237
|
+
let sourceUid: string
|
238
|
+
let destUid: string
|
239
|
+
|
240
|
+
// Handle overloaded parameters
|
241
|
+
if (isNullString(destinationUid)) {
|
242
|
+
// Called with one parameter: merge(destinationUid)
|
243
|
+
sourceUid = resolveUserId()
|
244
|
+
destUid = sourceOrDestinationUid
|
245
|
+
} else {
|
246
|
+
// Called with two parameters: merge(sourceUid, destinationUid)
|
247
|
+
sourceUid = resolveUserId(sourceOrDestinationUid)
|
248
|
+
destUid = destinationUid as string
|
180
249
|
}
|
181
|
-
|
250
|
+
|
251
|
+
if (isNullString(destUid)) {
|
182
252
|
throw new EngageError('Destination ID missing.')
|
183
253
|
}
|
184
254
|
|
185
|
-
return _request(
|
255
|
+
return await _request('/users/merge', {
|
186
256
|
source: sourceUid,
|
187
|
-
destination:
|
257
|
+
destination: destUid
|
188
258
|
}, 'POST')
|
189
259
|
}
|
190
260
|
|
191
261
|
// Account functions
|
192
|
-
export async function addToAccount(uid: string, accountId: string, role
|
193
|
-
if (
|
262
|
+
export async function addToAccount (uid: string, accountId: string, role?: string): Promise<object> {
|
263
|
+
if (isNullString(uid)) {
|
194
264
|
throw new EngageError('User ID missing.')
|
195
265
|
}
|
196
|
-
if (
|
266
|
+
if (isNullString(accountId)) {
|
197
267
|
throw new EngageError('Account ID missing.')
|
198
268
|
}
|
199
|
-
if (role && typeof role !== 'string') {
|
269
|
+
if (!isNull(role) && typeof role !== 'string') {
|
200
270
|
throw new EngageError('Role should be a text.')
|
201
271
|
}
|
202
272
|
const g: Record<string, string> = {
|
203
273
|
id: accountId
|
204
274
|
}
|
205
|
-
if (role) {
|
206
|
-
g.role = role
|
275
|
+
if (!isNullString(role)) {
|
276
|
+
g.role = role as string
|
207
277
|
}
|
208
|
-
return _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST')
|
278
|
+
return await _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST')
|
209
279
|
}
|
210
|
-
|
211
|
-
|
212
|
-
|
280
|
+
|
281
|
+
// Overloaded function signatures for removeFromAccount
|
282
|
+
export async function removeFromAccount (accountId: string): Promise<object>
|
283
|
+
export async function removeFromAccount (uid: string, accountId: string): Promise<object>
|
284
|
+
export async function removeFromAccount (uidOrAccountId: string, accountId?: string): Promise<object> {
|
285
|
+
let uid: string
|
286
|
+
let acctId: string
|
287
|
+
|
288
|
+
// Handle overloaded parameters
|
289
|
+
if (isNullString(accountId)) {
|
290
|
+
// Called with one parameter: removeFromAccount(accountId)
|
291
|
+
uid = resolveUserId()
|
292
|
+
acctId = uidOrAccountId
|
293
|
+
} else {
|
294
|
+
// Called with two parameters: removeFromAccount(uid, accountId)
|
295
|
+
uid = resolveUserId(uidOrAccountId)
|
296
|
+
acctId = accountId as string
|
213
297
|
}
|
214
|
-
|
298
|
+
|
299
|
+
if (isNullString(acctId)) {
|
215
300
|
throw new EngageError('Account ID missing.')
|
216
301
|
}
|
217
|
-
return _request(`/users/${uid}/accounts/${
|
302
|
+
return await _request(`/users/${uid}/accounts/${acctId}`, null, 'DELETE')
|
218
303
|
}
|
219
|
-
|
220
|
-
|
221
|
-
|
304
|
+
|
305
|
+
// Overloaded function signatures for changeAccountRole
|
306
|
+
export async function changeAccountRole (accountId: string, role: string): Promise<object>
|
307
|
+
export async function changeAccountRole (uid: string, accountId: string, role: string): Promise<object>
|
308
|
+
export async function changeAccountRole (uidOrAccountId: string, accountIdOrRole: string, role?: string): Promise<object> {
|
309
|
+
let uid: string
|
310
|
+
let accountId: string
|
311
|
+
let newRole: string
|
312
|
+
|
313
|
+
// Handle overloaded parameters
|
314
|
+
if (isNullString(role)) {
|
315
|
+
// Called with two parameters: changeAccountRole(accountId, role)
|
316
|
+
uid = resolveUserId()
|
317
|
+
accountId = uidOrAccountId
|
318
|
+
newRole = accountIdOrRole
|
319
|
+
} else {
|
320
|
+
// Called with three parameters: changeAccountRole(uid, accountId, role)
|
321
|
+
uid = resolveUserId(uidOrAccountId)
|
322
|
+
accountId = accountIdOrRole
|
323
|
+
newRole = role as string
|
222
324
|
}
|
223
|
-
|
325
|
+
|
326
|
+
if (isNullString(accountId)) {
|
224
327
|
throw new EngageError('Account ID missing.')
|
225
328
|
}
|
226
|
-
if (
|
329
|
+
if (isNullString(newRole)) {
|
227
330
|
throw new EngageError('New role missing.')
|
228
331
|
}
|
229
|
-
return _request(`/users/${uid}/accounts/${accountId}`, { role }, 'PUT')
|
332
|
+
return await _request(`/users/${uid}/accounts/${accountId}`, { role: newRole }, 'PUT')
|
230
333
|
}
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
334
|
+
|
335
|
+
// Overloaded function signatures for convertToCustomer
|
336
|
+
export async function convertToCustomer (): Promise<object>
|
337
|
+
export async function convertToCustomer (uid?: string): Promise<object> {
|
338
|
+
const userId = resolveUserId(uid)
|
339
|
+
return await _request(`/users/${userId}/convert`, { type: 'customer' }, 'POST')
|
236
340
|
}
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
341
|
+
|
342
|
+
// Overloaded function signatures for convertToAccount
|
343
|
+
export async function convertToAccount (): Promise<object>
|
344
|
+
export async function convertToAccount (uid?: string): Promise<object> {
|
345
|
+
const userId = resolveUserId(uid)
|
346
|
+
return await _request(`/users/${userId}/convert`, { type: 'account' }, 'POST')
|
242
347
|
}
|
348
|
+
|
349
|
+
// Create an object containing all exports for easy access
|
350
|
+
const EngageSDK = {
|
351
|
+
init,
|
352
|
+
identify,
|
353
|
+
addAttribute,
|
354
|
+
track,
|
355
|
+
merge,
|
356
|
+
addToAccount,
|
357
|
+
removeFromAccount,
|
358
|
+
changeAccountRole,
|
359
|
+
convertToCustomer,
|
360
|
+
convertToAccount,
|
361
|
+
request
|
362
|
+
}
|
363
|
+
|
364
|
+
// Export as default for import EngageSDK syntax
|
365
|
+
export default EngageSDK
|
package/tests/index.test.ts
CHANGED
@@ -29,57 +29,9 @@ describe('Init', () => {
|
|
29
29
|
})
|
30
30
|
})
|
31
31
|
|
32
|
-
describe('Identify', () => {
|
33
|
-
test('should throw if no parameter passed', async () => {
|
34
|
-
await expect(Engage.identify()).rejects.toThrow('object')
|
35
|
-
})
|
36
|
-
test('should throw if empty string passed', async () => {
|
37
|
-
await expect(Engage.identify('')).rejects.toThrow('id')
|
38
|
-
})
|
39
|
-
test('should throw if empty object passed', async () => {
|
40
|
-
await expect(Engage.identify({})).rejects.toThrow(/id/i)
|
41
|
-
})
|
42
|
-
test('should not throw if no email passed', async () => {
|
43
|
-
await expect(() => {
|
44
|
-
Engage.identify({ id: gid })
|
45
|
-
}).not.toThrow()
|
46
|
-
})
|
47
|
-
test('should throw if invalid email passed', async () => {
|
48
|
-
await expect(Engage.identify({
|
49
|
-
id,
|
50
|
-
email: 'invalid'
|
51
|
-
})).rejects.toThrow(/email/i)
|
52
|
-
})
|
53
|
-
test('should work if id and email passed', async () => {
|
54
|
-
await expect(Engage.identify({
|
55
|
-
id,
|
56
|
-
email: 'fickledreams@yahoo.com'
|
57
|
-
})).resolves.toMatchObject({
|
58
|
-
uid: id,
|
59
|
-
email: 'fickledreams@yahoo.com'
|
60
|
-
})
|
61
|
-
})
|
62
|
-
test('should turn to account if has is_account', async () => {
|
63
|
-
await expect(Engage.identify({
|
64
|
-
id,
|
65
|
-
is_account: true
|
66
|
-
})).resolves.toMatchObject({
|
67
|
-
is_account: true
|
68
|
-
})
|
69
|
-
})
|
70
|
-
test('should turn to user if is_account is false', async () => {
|
71
|
-
await expect(Engage.identify({
|
72
|
-
id,
|
73
|
-
is_account: false
|
74
|
-
})).resolves.toMatchObject({
|
75
|
-
is_account: false
|
76
|
-
})
|
77
|
-
})
|
78
|
-
})
|
79
|
-
|
80
32
|
describe('Add attribute', () => {
|
81
33
|
test('should throw if no parameter passed', async () => {
|
82
|
-
await expect(Engage.addAttribute()).rejects.toThrow(
|
34
|
+
await expect(Engage.addAttribute()).rejects.toThrow(/id/i)
|
83
35
|
})
|
84
36
|
test('should throw if no data attribute passed', async () => {
|
85
37
|
await expect(Engage.addAttribute(id)).rejects.toThrow(/attributes/i)
|
@@ -115,7 +67,7 @@ describe('Add attribute', () => {
|
|
115
67
|
|
116
68
|
describe('Track', () => {
|
117
69
|
test('should throw if no parameter passed', async () => {
|
118
|
-
await expect(Engage.track()).rejects.toThrow(
|
70
|
+
await expect(Engage.track()).rejects.toThrow(/id/i)
|
119
71
|
})
|
120
72
|
test('should throw if no data attribute passed', async () => {
|
121
73
|
await expect(Engage.track(id)).rejects.toThrow(/data/i)
|
@@ -229,3 +181,51 @@ describe('Remove from account', () => {
|
|
229
181
|
})
|
230
182
|
})
|
231
183
|
})
|
184
|
+
|
185
|
+
describe('Identify', () => {
|
186
|
+
test('should throw if no parameter passed', async () => {
|
187
|
+
await expect(Engage.identify()).rejects.toThrow('object')
|
188
|
+
})
|
189
|
+
test('should throw if empty string passed', async () => {
|
190
|
+
await expect(Engage.identify('')).rejects.toThrow('ID')
|
191
|
+
})
|
192
|
+
test('should throw if empty object passed', async () => {
|
193
|
+
await expect(Engage.identify({})).rejects.toThrow('ID')
|
194
|
+
})
|
195
|
+
test('should not throw if no email passed', async () => {
|
196
|
+
await expect(() => {
|
197
|
+
Engage.identify({ id: gid })
|
198
|
+
}).not.toThrow()
|
199
|
+
})
|
200
|
+
test('should throw if invalid email passed', async () => {
|
201
|
+
await expect(Engage.identify({
|
202
|
+
id,
|
203
|
+
email: 'invalid'
|
204
|
+
})).rejects.toThrow(/email/i)
|
205
|
+
})
|
206
|
+
test('should work if id and email passed', async () => {
|
207
|
+
await expect(Engage.identify({
|
208
|
+
id,
|
209
|
+
email: 'fickledreams@yahoo.com'
|
210
|
+
})).resolves.toMatchObject({
|
211
|
+
uid: id,
|
212
|
+
email: 'fickledreams@yahoo.com'
|
213
|
+
})
|
214
|
+
})
|
215
|
+
test('should turn to account if has is_account', async () => {
|
216
|
+
await expect(Engage.identify({
|
217
|
+
id,
|
218
|
+
is_account: true
|
219
|
+
})).resolves.toMatchObject({
|
220
|
+
is_account: true
|
221
|
+
})
|
222
|
+
})
|
223
|
+
test('should turn to user if is_account is false', async () => {
|
224
|
+
await expect(Engage.identify({
|
225
|
+
id,
|
226
|
+
is_account: false
|
227
|
+
})).resolves.toMatchObject({
|
228
|
+
is_account: false
|
229
|
+
})
|
230
|
+
})
|
231
|
+
})
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import * as Engage from '../src/index'
|
2
|
+
import EngageSDK from '../src/index'
|
3
|
+
|
4
|
+
describe('Object-Oriented Pattern', () => {
|
5
|
+
describe('Functional style imports', () => {
|
6
|
+
test('should work with named import init', () => {
|
7
|
+
expect(() => {
|
8
|
+
Engage.init('test-key')
|
9
|
+
}).not.toThrow()
|
10
|
+
})
|
11
|
+
|
12
|
+
test('should work with destructured init', () => {
|
13
|
+
const { init } = Engage
|
14
|
+
expect(() => {
|
15
|
+
init('test-key-2')
|
16
|
+
}).not.toThrow()
|
17
|
+
})
|
18
|
+
})
|
19
|
+
|
20
|
+
describe('Static class style imports', () => {
|
21
|
+
test('should work with default import init', () => {
|
22
|
+
expect(() => {
|
23
|
+
EngageSDK.init('test-key')
|
24
|
+
}).not.toThrow()
|
25
|
+
})
|
26
|
+
|
27
|
+
test('should have all expected methods on default export', () => {
|
28
|
+
expect(typeof EngageSDK.init).toBe('function')
|
29
|
+
expect(typeof EngageSDK.identify).toBe('function')
|
30
|
+
expect(typeof EngageSDK.addAttribute).toBe('function')
|
31
|
+
expect(typeof EngageSDK.track).toBe('function')
|
32
|
+
expect(typeof EngageSDK.merge).toBe('function')
|
33
|
+
expect(typeof EngageSDK.addToAccount).toBe('function')
|
34
|
+
expect(typeof EngageSDK.removeFromAccount).toBe('function')
|
35
|
+
expect(typeof EngageSDK.changeAccountRole).toBe('function')
|
36
|
+
expect(typeof EngageSDK.convertToCustomer).toBe('function')
|
37
|
+
expect(typeof EngageSDK.convertToAccount).toBe('function')
|
38
|
+
expect(typeof EngageSDK.request).toBe('function')
|
39
|
+
})
|
40
|
+
})
|
41
|
+
})
|
@@ -0,0 +1,133 @@
|
|
1
|
+
import * as Engage from '../src/index'
|
2
|
+
|
3
|
+
describe('Function Overloads', () => {
|
4
|
+
beforeEach(() => {
|
5
|
+
// Initialize SDK before each test
|
6
|
+
Engage.init({ key: 'test-key', secret: 'test-secret' })
|
7
|
+
})
|
8
|
+
|
9
|
+
describe('Identify and stored user ID', () => {
|
10
|
+
test('should store user ID when identify is called', async () => {
|
11
|
+
await expect(Engage.identify({ id: 'test-user-123', email: 'test@example.com' }))
|
12
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
13
|
+
})
|
14
|
+
})
|
15
|
+
|
16
|
+
describe('addAttribute overloads', () => {
|
17
|
+
test('should work with uid parameter', async () => {
|
18
|
+
await expect(Engage.addAttribute('test-user-123', { name: 'John' }))
|
19
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
20
|
+
})
|
21
|
+
|
22
|
+
test('should work without uid parameter after identify', async () => {
|
23
|
+
// First identify to store user ID
|
24
|
+
await Engage.identify({ id: 'test-user-123', email: 'test@example.com' })
|
25
|
+
|
26
|
+
// Then use addAttribute without uid
|
27
|
+
await expect(Engage.addAttribute({ name: 'John' }))
|
28
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
29
|
+
})
|
30
|
+
|
31
|
+
test('should throw error if no stored uid and no uid provided', async () => {
|
32
|
+
// Reset any stored user ID by re-initializing
|
33
|
+
Engage.init({ key: 'test-key', secret: 'test-secret' })
|
34
|
+
|
35
|
+
await expect(Engage.addAttribute({ name: 'John' }))
|
36
|
+
.rejects.toThrow('User ID missing. Call identify() first or provide a uid parameter.')
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
describe('track overloads', () => {
|
41
|
+
test('should work with uid parameter', async () => {
|
42
|
+
await expect(Engage.track('test-user-123', { event: 'login' }))
|
43
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
44
|
+
})
|
45
|
+
|
46
|
+
test('should work without uid parameter after identify', async () => {
|
47
|
+
// First identify to store user ID
|
48
|
+
await Engage.identify({ id: 'test-user-123', email: 'test@example.com' })
|
49
|
+
|
50
|
+
// Then use track without uid
|
51
|
+
await expect(Engage.track({ event: 'login' }))
|
52
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
53
|
+
})
|
54
|
+
|
55
|
+
test('should throw error if no stored uid and no uid provided', async () => {
|
56
|
+
// Reset any stored user ID by re-initializing
|
57
|
+
Engage.init({ key: 'test-key', secret: 'test-secret' })
|
58
|
+
|
59
|
+
await expect(Engage.track({ event: 'login' }))
|
60
|
+
.rejects.toThrow('User ID missing. Call identify() first or provide a uid parameter.')
|
61
|
+
})
|
62
|
+
})
|
63
|
+
|
64
|
+
describe('convertToCustomer overloads', () => {
|
65
|
+
test('should work with uid parameter', async () => {
|
66
|
+
await expect((Engage.convertToCustomer as any)('test-user-123'))
|
67
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
68
|
+
})
|
69
|
+
|
70
|
+
test('should work without uid parameter after identify', async () => {
|
71
|
+
// First identify to store user ID
|
72
|
+
await Engage.identify({ id: 'test-user-123', email: 'test@example.com' })
|
73
|
+
|
74
|
+
// Then use convertToCustomer without uid
|
75
|
+
await expect(Engage.convertToCustomer())
|
76
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
77
|
+
})
|
78
|
+
|
79
|
+
test('should throw error if no stored uid and no uid provided', async () => {
|
80
|
+
// Reset any stored user ID by re-initializing
|
81
|
+
Engage.init({ key: 'test-key', secret: 'test-secret' })
|
82
|
+
|
83
|
+
await expect(Engage.convertToCustomer())
|
84
|
+
.rejects.toThrow('User ID missing. Call identify() first or provide a uid parameter.')
|
85
|
+
})
|
86
|
+
})
|
87
|
+
|
88
|
+
describe('merge overloads', () => {
|
89
|
+
test('should work with both source and destination uid', async () => {
|
90
|
+
await expect(Engage.merge('source-user', 'dest-user'))
|
91
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
92
|
+
})
|
93
|
+
|
94
|
+
test('should work with destination uid only after identify', async () => {
|
95
|
+
// First identify to store user ID (source)
|
96
|
+
await Engage.identify({ id: 'source-user', email: 'test@example.com' })
|
97
|
+
|
98
|
+
// Then merge with destination only
|
99
|
+
await expect(Engage.merge('dest-user'))
|
100
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
101
|
+
})
|
102
|
+
|
103
|
+
test('should throw error if no stored uid and only destination provided', async () => {
|
104
|
+
// Reset any stored user ID by re-initializing
|
105
|
+
Engage.init({ key: 'test-key', secret: 'test-secret' })
|
106
|
+
|
107
|
+
await expect(Engage.merge('dest-user'))
|
108
|
+
.rejects.toThrow('User ID missing. Call identify() first or provide a uid parameter.')
|
109
|
+
})
|
110
|
+
})
|
111
|
+
|
112
|
+
describe('account management overloads', () => {
|
113
|
+
test('removeFromAccount should work with both signatures', async () => {
|
114
|
+
await expect(Engage.removeFromAccount('user-id', 'account-id'))
|
115
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
116
|
+
|
117
|
+
// After identify
|
118
|
+
await Engage.identify({ id: 'user-id', email: 'test@example.com' })
|
119
|
+
await expect(Engage.removeFromAccount('account-id'))
|
120
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
121
|
+
})
|
122
|
+
|
123
|
+
test('changeAccountRole should work with both signatures', async () => {
|
124
|
+
await expect(Engage.changeAccountRole('user-id', 'account-id', 'owner'))
|
125
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
126
|
+
|
127
|
+
// After identify
|
128
|
+
await Engage.identify({ id: 'user-id', email: 'test@example.com' })
|
129
|
+
await expect(Engage.changeAccountRole('account-id', 'owner'))
|
130
|
+
.resolves.toMatchObject({ error: expect.any(String) })
|
131
|
+
})
|
132
|
+
})
|
133
|
+
})
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import * as Engage from '../src/index'
|
2
|
+
import EngageSDK from '../src/index'
|
3
|
+
|
4
|
+
describe('Method Overriding', () => {
|
5
|
+
describe('Individual function exports', () => {
|
6
|
+
test('should allow access to original init function', () => {
|
7
|
+
expect(() => {
|
8
|
+
Engage.init('test-key')
|
9
|
+
}).not.toThrow()
|
10
|
+
})
|
11
|
+
|
12
|
+
test('should allow method overriding by replacing function', async () => {
|
13
|
+
// Save original function
|
14
|
+
const originalTrack = Engage.track
|
15
|
+
|
16
|
+
// Create a mock function to override with
|
17
|
+
const customTrack = jest.fn().mockImplementation(async (uidOrData: any, data?: any) => {
|
18
|
+
// Call original function for proper behavior
|
19
|
+
const result = await originalTrack(uidOrData, data)
|
20
|
+
// Add custom flag to result
|
21
|
+
return { ...result, customFlag: 'overridden' }
|
22
|
+
})
|
23
|
+
|
24
|
+
// Override the function
|
25
|
+
;(Engage as any).track = customTrack
|
26
|
+
|
27
|
+
// Test the overridden function
|
28
|
+
try {
|
29
|
+
const result = await (Engage as any).track('user123', { event: 'test-event' })
|
30
|
+
expect(result).toHaveProperty('customFlag', 'overridden')
|
31
|
+
expect(customTrack).toHaveBeenCalledWith('user123', { event: 'test-event' })
|
32
|
+
} catch (error) {
|
33
|
+
// Expected to fail due to API authentication, but should still call our custom function
|
34
|
+
expect(customTrack).toHaveBeenCalledWith('user123', { event: 'test-event' })
|
35
|
+
}
|
36
|
+
|
37
|
+
// Restore original function
|
38
|
+
;(Engage as any).track = originalTrack
|
39
|
+
})
|
40
|
+
|
41
|
+
test('should maintain function reference integrity', () => {
|
42
|
+
const trackFunction = Engage.track
|
43
|
+
expect(typeof trackFunction).toBe('function')
|
44
|
+
expect(trackFunction).toBe(Engage.track)
|
45
|
+
})
|
46
|
+
})
|
47
|
+
|
48
|
+
describe('Default export overriding', () => {
|
49
|
+
test('should work with default export init', () => {
|
50
|
+
expect(() => {
|
51
|
+
EngageSDK.init('test-key-2')
|
52
|
+
}).not.toThrow()
|
53
|
+
})
|
54
|
+
|
55
|
+
test('should allow method overriding on default export', async () => {
|
56
|
+
// Save original function
|
57
|
+
const originalIdentify = EngageSDK.identify
|
58
|
+
|
59
|
+
// Create a mock function
|
60
|
+
const customIdentify = jest.fn().mockImplementation(async (user: any) => {
|
61
|
+
const result = await originalIdentify(user)
|
62
|
+
return { ...result, customProcessed: true }
|
63
|
+
})
|
64
|
+
|
65
|
+
// Override the function
|
66
|
+
;(EngageSDK as any).identify = customIdentify
|
67
|
+
|
68
|
+
// Test the overridden function
|
69
|
+
try {
|
70
|
+
const result = await (EngageSDK as any).identify({ id: 'test-user', email: 'test@example.com' })
|
71
|
+
expect(result).toHaveProperty('customProcessed', true)
|
72
|
+
expect(customIdentify).toHaveBeenCalledWith({ id: 'test-user', email: 'test@example.com' })
|
73
|
+
} catch (error) {
|
74
|
+
// Expected to fail due to API authentication, but should still call our custom function
|
75
|
+
expect(customIdentify).toHaveBeenCalledWith({ id: 'test-user', email: 'test@example.com' })
|
76
|
+
}
|
77
|
+
|
78
|
+
// Restore original function
|
79
|
+
;(EngageSDK as any).identify = originalIdentify
|
80
|
+
})
|
81
|
+
|
82
|
+
test('should have consistent function references between named and default exports', () => {
|
83
|
+
expect(typeof EngageSDK.init).toBe('function')
|
84
|
+
expect(typeof EngageSDK.track).toBe('function')
|
85
|
+
expect(typeof EngageSDK.identify).toBe('function')
|
86
|
+
})
|
87
|
+
})
|
88
|
+
|
89
|
+
describe('Overriding behavior validation', () => {
|
90
|
+
test('should allow chaining of overridden methods', async () => {
|
91
|
+
const originalAddAttribute = Engage.addAttribute
|
92
|
+
|
93
|
+
// First override
|
94
|
+
const firstOverride = jest.fn().mockImplementation(async (uidOrAttrs: any, attrs?: any) => {
|
95
|
+
const result = await (originalAddAttribute as any)(uidOrAttrs, attrs)
|
96
|
+
return { ...result, step1: 'complete' }
|
97
|
+
})
|
98
|
+
|
99
|
+
// Second override that calls first override
|
100
|
+
const secondOverride = jest.fn().mockImplementation(async (uidOrAttrs: any, attrs?: any) => {
|
101
|
+
const result = await firstOverride(uidOrAttrs, attrs)
|
102
|
+
return { ...result, step2: 'complete' }
|
103
|
+
})
|
104
|
+
|
105
|
+
;(Engage as any).addAttribute = secondOverride
|
106
|
+
|
107
|
+
try {
|
108
|
+
await (Engage as any).addAttribute('test-user', { name: 'Test' })
|
109
|
+
expect(secondOverride).toHaveBeenCalled()
|
110
|
+
expect(firstOverride).toHaveBeenCalled()
|
111
|
+
} catch (error) {
|
112
|
+
// Expected to fail but should still call our functions
|
113
|
+
expect(secondOverride).toHaveBeenCalled()
|
114
|
+
expect(firstOverride).toHaveBeenCalled()
|
115
|
+
}
|
116
|
+
|
117
|
+
// Restore
|
118
|
+
;(Engage as any).addAttribute = originalAddAttribute
|
119
|
+
})
|
120
|
+
})
|
121
|
+
})
|
package/tsconfig.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"module": "NodeNext",
|
5
5
|
"declaration": true,
|
6
6
|
"declarationMap": true,
|
7
|
-
"outDir": "./dist",
|
7
|
+
"outDir": "./dist/",
|
8
8
|
"esModuleInterop": true,
|
9
9
|
"forceConsistentCasingInFileNames": true,
|
10
10
|
"strict": true,
|
@@ -12,7 +12,6 @@
|
|
12
12
|
},
|
13
13
|
"exclude": [
|
14
14
|
"node_modules",
|
15
|
-
"tests"
|
16
|
-
"dist"
|
15
|
+
"tests"
|
17
16
|
]
|
18
17
|
}
|
package/.eslintignore
DELETED
package/dist/error.d.ts
DELETED
package/dist/error.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI7B"}
|
package/dist/error.js
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.EngageError = void 0;
|
4
|
-
class EngageError extends Error {
|
5
|
-
constructor(message) {
|
6
|
-
super(message);
|
7
|
-
this.name = 'EngageError';
|
8
|
-
}
|
9
|
-
}
|
10
|
-
exports.EngageError = EngageError;
|
package/dist/index.d.ts
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
interface Key {
|
2
|
-
key?: string;
|
3
|
-
secret?: string;
|
4
|
-
}
|
5
|
-
interface EventParameter {
|
6
|
-
event: string;
|
7
|
-
value?: string | number | Date | boolean;
|
8
|
-
properties?: {
|
9
|
-
[key: string]: string | number | Date | boolean;
|
10
|
-
};
|
11
|
-
timestamp?: string | number | Date;
|
12
|
-
}
|
13
|
-
type UserAttrParams = {
|
14
|
-
[key: string]: string | number | Date | boolean;
|
15
|
-
};
|
16
|
-
type UserIdentifyParams = UserAttrParams & {
|
17
|
-
id: string;
|
18
|
-
};
|
19
|
-
type Methods = 'POST' | 'PUT' | 'DELETE';
|
20
|
-
export declare function request(url: string, params: Record<string, any> | null, method: Methods): object;
|
21
|
-
export declare function init(key: Key | string): void;
|
22
|
-
export declare function identify(user: UserIdentifyParams): Promise<any>;
|
23
|
-
export declare function addAttribute(uid: string, attributes: UserAttrParams): Promise<any>;
|
24
|
-
export declare function track(uid: string, data: EventParameter): Promise<any>;
|
25
|
-
export declare function merge(sourceUid: string, destinationUid: string): Promise<any>;
|
26
|
-
export declare function addToAccount(uid: string, accountId: string, role: string): Promise<any>;
|
27
|
-
export declare function removeFromAccount(uid: string, accountId: string): Promise<any>;
|
28
|
-
export declare function changeAccountRole(uid: string, accountId: string, role: string): Promise<any>;
|
29
|
-
export declare function convertToCustomer(uid: string): Promise<any>;
|
30
|
-
export declare function convertToAccount(uid: string): Promise<any>;
|
31
|
-
export {};
|
32
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,UAAU,GAAG;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AACD,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;IACxC,UAAU,CAAC,EAAE;QACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;KAChD,CAAA;IACD,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CACnC;AACD,KAAK,cAAc,GAAG;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;CAChD,CAAA;AACD,KAAK,kBAAkB,GAAG,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAQzD,KAAK,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAA;AA2CxC,wBAAgB,OAAO,CAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAEjG;AAED,wBAAgB,IAAI,CAAE,GAAG,EAAE,GAAG,GAAG,MAAM,QAwBtC;AAGD,wBAAsB,QAAQ,CAAE,IAAI,EAAE,kBAAkB,gBAqBvD;AACD,wBAAsB,YAAY,CAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,gBAyB1E;AACD,wBAAsB,KAAK,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,gBAmB7D;AAED,wBAAsB,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAYrE;AAGD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,gBAiB9E;AACD,wBAAsB,iBAAiB,CAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAQtE;AACD,wBAAsB,iBAAiB,CAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,gBAWpF;AACD,wBAAsB,iBAAiB,CAAE,GAAG,EAAE,MAAM,gBAKnD;AACD,wBAAsB,gBAAgB,CAAE,GAAG,EAAE,MAAM,gBAKlD"}
|
package/dist/index.js
DELETED
@@ -1,257 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
-
});
|
10
|
-
};
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
-
};
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
-
exports.convertToAccount = exports.convertToCustomer = exports.changeAccountRole = exports.removeFromAccount = exports.addToAccount = exports.merge = exports.track = exports.addAttribute = exports.identify = exports.init = exports.request = void 0;
|
16
|
-
const buffer_1 = require("buffer");
|
17
|
-
const cross_fetch_1 = __importDefault(require("cross-fetch"));
|
18
|
-
const error_1 = require("./error");
|
19
|
-
if (typeof btoa === 'undefined') {
|
20
|
-
global.btoa = function (str) {
|
21
|
-
return buffer_1.Buffer.from(str).toString('base64');
|
22
|
-
};
|
23
|
-
}
|
24
|
-
// type UserIdentifyParams = {
|
25
|
-
// id: string
|
26
|
-
// [key: string]: string | number | Date | boolean
|
27
|
-
// }
|
28
|
-
// type UserAttrParams = Omit<UserIdentifyParams, 'id'>
|
29
|
-
// const rootURL = 'https://api.engage.so/v1'
|
30
|
-
let auth = '';
|
31
|
-
const notMeta = ['created_at', 'is_account', 'number', 'device_token', 'device_platform', 'email', 'first_name', 'last_name', 'tz', 'app_version', 'app_build', 'app_last_active'];
|
32
|
-
const apiRoot = 'https://api.engage.so/v1';
|
33
|
-
function _request(url, params, method) {
|
34
|
-
return __awaiter(this, void 0, void 0, function* () {
|
35
|
-
try {
|
36
|
-
const o = {
|
37
|
-
method,
|
38
|
-
headers: {
|
39
|
-
'Content-Type': 'application/json;charset=utf-8',
|
40
|
-
Authorization: `Basic ${auth}`
|
41
|
-
},
|
42
|
-
// throwHttpErrors: false,
|
43
|
-
// prefixUrl: rootURL
|
44
|
-
};
|
45
|
-
if (params) {
|
46
|
-
o.body = JSON.stringify(params);
|
47
|
-
}
|
48
|
-
// const response = await ky(url, o)
|
49
|
-
const response = yield (0, cross_fetch_1.default)(`${apiRoot}${url}`, o);
|
50
|
-
const body = yield response.json();
|
51
|
-
let error = 'API connection error';
|
52
|
-
if (!response.ok) {
|
53
|
-
if (body && body.error) {
|
54
|
-
error = body.error;
|
55
|
-
}
|
56
|
-
return { error };
|
57
|
-
}
|
58
|
-
return body;
|
59
|
-
}
|
60
|
-
catch (e) {
|
61
|
-
return { error: 'API connection error' };
|
62
|
-
}
|
63
|
-
});
|
64
|
-
}
|
65
|
-
// Alias of _request method
|
66
|
-
// Same with _request for now but can later have modifications
|
67
|
-
function request(url, params, method) {
|
68
|
-
return _request(url, params, method);
|
69
|
-
}
|
70
|
-
exports.request = request;
|
71
|
-
function init(key) {
|
72
|
-
if (!key) {
|
73
|
-
throw new error_1.EngageError('You need to pass in your API key(s).');
|
74
|
-
}
|
75
|
-
const options = {
|
76
|
-
key: undefined,
|
77
|
-
secret: ''
|
78
|
-
};
|
79
|
-
if (typeof key === 'string') {
|
80
|
-
options.key = key;
|
81
|
-
}
|
82
|
-
else {
|
83
|
-
if (!key.key) {
|
84
|
-
throw new error_1.EngageError('`key` missing in object.');
|
85
|
-
}
|
86
|
-
if (key.key) {
|
87
|
-
options.key = `${key.key}`;
|
88
|
-
}
|
89
|
-
if (key.secret) {
|
90
|
-
options.secret = `${key.secret}`;
|
91
|
-
}
|
92
|
-
}
|
93
|
-
// Set auth
|
94
|
-
// auth = Buffer.from(`${options.key}:${options.secret}`).toString('base64')
|
95
|
-
auth = btoa(`${options.key}:${options.secret}`);
|
96
|
-
}
|
97
|
-
exports.init = init;
|
98
|
-
// Data tracking
|
99
|
-
function identify(user) {
|
100
|
-
return __awaiter(this, void 0, void 0, function* () {
|
101
|
-
if (!user) {
|
102
|
-
throw new error_1.EngageError('You need to pass an object with at least an id.');
|
103
|
-
}
|
104
|
-
if (!user.id) {
|
105
|
-
throw new error_1.EngageError('ID missing.');
|
106
|
-
}
|
107
|
-
if (user.email && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
|
108
|
-
throw new error_1.EngageError('Email invalid.');
|
109
|
-
}
|
110
|
-
const params = {};
|
111
|
-
params.meta = {};
|
112
|
-
for (const k in user) {
|
113
|
-
if (k === 'id' || notMeta.includes(k)) {
|
114
|
-
params[k] = user[k];
|
115
|
-
}
|
116
|
-
else {
|
117
|
-
params.meta[k] = user[k];
|
118
|
-
}
|
119
|
-
}
|
120
|
-
return _request(`/users/${user.id}`, params, 'PUT');
|
121
|
-
});
|
122
|
-
}
|
123
|
-
exports.identify = identify;
|
124
|
-
function addAttribute(uid, attributes) {
|
125
|
-
return __awaiter(this, void 0, void 0, function* () {
|
126
|
-
if (!uid) {
|
127
|
-
throw new error_1.EngageError('User ID missing.');
|
128
|
-
}
|
129
|
-
if (!attributes) {
|
130
|
-
throw new error_1.EngageError('Attributes missing.');
|
131
|
-
}
|
132
|
-
if (!Object.keys(attributes).length) {
|
133
|
-
throw new error_1.EngageError('Attributes missing.');
|
134
|
-
}
|
135
|
-
const params = {};
|
136
|
-
params.meta = {};
|
137
|
-
for (const k in attributes) {
|
138
|
-
if (notMeta.includes(k)) {
|
139
|
-
params[k] = attributes[k];
|
140
|
-
}
|
141
|
-
else {
|
142
|
-
params.meta[k] = attributes[k];
|
143
|
-
Object.assign(params.meta, k, attributes[k]);
|
144
|
-
}
|
145
|
-
}
|
146
|
-
if (Object.keys(params.meta).length) {
|
147
|
-
delete params.meta;
|
148
|
-
}
|
149
|
-
return _request(`/users/${uid}`, params, 'PUT');
|
150
|
-
});
|
151
|
-
}
|
152
|
-
exports.addAttribute = addAttribute;
|
153
|
-
function track(uid, data) {
|
154
|
-
return __awaiter(this, void 0, void 0, function* () {
|
155
|
-
if (!uid) {
|
156
|
-
throw new error_1.EngageError('User ID missing.');
|
157
|
-
}
|
158
|
-
if (!data) {
|
159
|
-
throw new error_1.EngageError('Event data missing.');
|
160
|
-
}
|
161
|
-
if (typeof data === 'string') {
|
162
|
-
data = {
|
163
|
-
event: data,
|
164
|
-
value: true
|
165
|
-
};
|
166
|
-
}
|
167
|
-
else {
|
168
|
-
if (!Object.keys(data).length) {
|
169
|
-
throw new error_1.EngageError('Attributes missing.');
|
170
|
-
}
|
171
|
-
}
|
172
|
-
return _request(`/users/${uid}/events`, data, 'POST');
|
173
|
-
});
|
174
|
-
}
|
175
|
-
exports.track = track;
|
176
|
-
function merge(sourceUid, destinationUid) {
|
177
|
-
return __awaiter(this, void 0, void 0, function* () {
|
178
|
-
if (!sourceUid) {
|
179
|
-
throw new error_1.EngageError('Source ID missing.');
|
180
|
-
}
|
181
|
-
if (!destinationUid) {
|
182
|
-
throw new error_1.EngageError('Destination ID missing.');
|
183
|
-
}
|
184
|
-
return _request(`/users/merge`, {
|
185
|
-
source: sourceUid,
|
186
|
-
destination: destinationUid
|
187
|
-
}, 'POST');
|
188
|
-
});
|
189
|
-
}
|
190
|
-
exports.merge = merge;
|
191
|
-
// Account functions
|
192
|
-
function addToAccount(uid, accountId, role) {
|
193
|
-
return __awaiter(this, void 0, void 0, function* () {
|
194
|
-
if (!uid) {
|
195
|
-
throw new error_1.EngageError('User ID missing.');
|
196
|
-
}
|
197
|
-
if (!accountId) {
|
198
|
-
throw new error_1.EngageError('Account ID missing.');
|
199
|
-
}
|
200
|
-
if (role && typeof role !== 'string') {
|
201
|
-
throw new error_1.EngageError('Role should be a text.');
|
202
|
-
}
|
203
|
-
const g = {
|
204
|
-
id: accountId
|
205
|
-
};
|
206
|
-
if (role) {
|
207
|
-
g.role = role;
|
208
|
-
}
|
209
|
-
return _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST');
|
210
|
-
});
|
211
|
-
}
|
212
|
-
exports.addToAccount = addToAccount;
|
213
|
-
function removeFromAccount(uid, accountId) {
|
214
|
-
return __awaiter(this, void 0, void 0, function* () {
|
215
|
-
if (!uid) {
|
216
|
-
throw new error_1.EngageError('User ID missing.');
|
217
|
-
}
|
218
|
-
if (!accountId) {
|
219
|
-
throw new error_1.EngageError('Account ID missing.');
|
220
|
-
}
|
221
|
-
return _request(`/users/${uid}/accounts/${accountId}`, null, 'DELETE');
|
222
|
-
});
|
223
|
-
}
|
224
|
-
exports.removeFromAccount = removeFromAccount;
|
225
|
-
function changeAccountRole(uid, accountId, role) {
|
226
|
-
return __awaiter(this, void 0, void 0, function* () {
|
227
|
-
if (!uid) {
|
228
|
-
throw new error_1.EngageError('User ID missing.');
|
229
|
-
}
|
230
|
-
if (!accountId) {
|
231
|
-
throw new error_1.EngageError('Account ID missing.');
|
232
|
-
}
|
233
|
-
if (!role) {
|
234
|
-
throw new error_1.EngageError('New role missing.');
|
235
|
-
}
|
236
|
-
return _request(`/users/${uid}/accounts/${accountId}`, { role }, 'PUT');
|
237
|
-
});
|
238
|
-
}
|
239
|
-
exports.changeAccountRole = changeAccountRole;
|
240
|
-
function convertToCustomer(uid) {
|
241
|
-
return __awaiter(this, void 0, void 0, function* () {
|
242
|
-
if (!uid) {
|
243
|
-
throw new error_1.EngageError('User ID missing.');
|
244
|
-
}
|
245
|
-
return _request(`/users/${uid}/convert`, { type: 'customer' }, 'POST');
|
246
|
-
});
|
247
|
-
}
|
248
|
-
exports.convertToCustomer = convertToCustomer;
|
249
|
-
function convertToAccount(uid) {
|
250
|
-
return __awaiter(this, void 0, void 0, function* () {
|
251
|
-
if (!uid) {
|
252
|
-
throw new error_1.EngageError('User ID missing.');
|
253
|
-
}
|
254
|
-
return _request(`/users/${uid}/convert`, { type: 'account' }, 'POST');
|
255
|
-
});
|
256
|
-
}
|
257
|
-
exports.convertToAccount = convertToAccount;
|