@engage_so/core 2.1.1 → 2.2.1

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/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/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- interface Key {
1
+ export interface Key {
2
2
  key?: string;
3
3
  secret?: string;
4
4
  }
5
- interface EventParameter {
5
+ export interface EventParameter {
6
6
  event: string;
7
7
  value?: string | number | Date | boolean;
8
8
  properties?: {
@@ -10,23 +10,41 @@ interface EventParameter {
10
10
  };
11
11
  timestamp?: string | number | Date;
12
12
  }
13
- type UserAttrParams = {
13
+ export interface UserAttrParams {
14
14
  [key: string]: string | number | Date | boolean;
15
- };
16
- type UserIdentifyParams = UserAttrParams & {
15
+ }
16
+ export type UserIdentifyParams = UserAttrParams & {
17
17
  id: string;
18
18
  };
19
- type Methods = 'POST' | 'PUT' | 'DELETE';
20
- export declare function request(url: string, params: Record<string, any> | null, method: Methods): object;
19
+ type Methods = 'POST' | 'PUT' | 'DELETE' | 'GET';
20
+ export declare function request(url: string, params: Record<string, any> | null | undefined, method?: Methods): Promise<object>;
21
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 {};
22
+ export declare function identify(user: UserIdentifyParams): Promise<object>;
23
+ export declare function addAttribute(attributes: UserAttrParams): Promise<object>;
24
+ export declare function addAttribute(uid: string, attributes: UserAttrParams): Promise<object>;
25
+ export declare function track(data: EventParameter): Promise<object>;
26
+ export declare function track(uid: string, data: EventParameter): Promise<object>;
27
+ export declare function merge(destinationUid: string): Promise<object>;
28
+ export declare function merge(sourceUid: string, destinationUid: string): Promise<object>;
29
+ export declare function addToAccount(uid: string, accountId: string, role?: string): Promise<object>;
30
+ export declare function removeFromAccount(accountId: string): Promise<object>;
31
+ export declare function removeFromAccount(uid: string, accountId: string): Promise<object>;
32
+ export declare function changeAccountRole(accountId: string, role: string): Promise<object>;
33
+ export declare function changeAccountRole(uid: string, accountId: string, role: string): Promise<object>;
34
+ export declare function convertToCustomer(): Promise<object>;
35
+ export declare function convertToAccount(): Promise<object>;
36
+ declare const EngageSDK: {
37
+ init: typeof init;
38
+ identify: typeof identify;
39
+ addAttribute: typeof addAttribute;
40
+ track: typeof track;
41
+ merge: typeof merge;
42
+ addToAccount: typeof addToAccount;
43
+ removeFromAccount: typeof removeFromAccount;
44
+ changeAccountRole: typeof changeAccountRole;
45
+ convertToCustomer: typeof convertToCustomer;
46
+ convertToAccount: typeof convertToAccount;
47
+ request: typeof request;
48
+ };
49
+ export default EngageSDK;
32
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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,gBAwB1E;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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AACD,MAAM,WAAW,cAAc;IAC7B,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,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;CAChD;AACD,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAQhE,KAAK,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAA;AA6DhD,wBAAsB,OAAO,CAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpI;AAED,wBAAgB,IAAI,CAAE,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI,CA4B7C;AAGD,wBAAsB,QAAQ,CAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBzE;AAGD,wBAAsB,YAAY,CAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAChF,wBAAsB,YAAY,CAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAwC7F,wBAAsB,KAAK,CAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACnE,wBAAsB,KAAK,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAmChF,wBAAsB,KAAK,CAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACrE,wBAAsB,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AA2BxF,wBAAsB,YAAY,CAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlG;AAGD,wBAAsB,iBAAiB,CAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5E,wBAAsB,iBAAiB,CAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAuBzF,wBAAsB,iBAAiB,CAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAC1F,wBAAsB,iBAAiB,CAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AA6BvG,wBAAsB,iBAAiB,IAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAO3D,wBAAsB,gBAAgB,IAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAO1D,QAAA,MAAM,SAAS;;;;;;;;;;;;CAYd,CAAA;AAGD,eAAe,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -28,8 +28,24 @@ if (typeof btoa === 'undefined') {
28
28
  // type UserAttrParams = Omit<UserIdentifyParams, 'id'>
29
29
  // const rootURL = 'https://api.engage.so/v1'
30
30
  let auth = '';
31
+ let currentUserId = '';
31
32
  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
33
  const apiRoot = 'https://api.engage.so/v1';
34
+ function isNull(v) {
35
+ return (v === null || v === undefined);
36
+ }
37
+ function isNullString(v) {
38
+ return (v === null || v === undefined || v === '');
39
+ }
40
+ function resolveUserId(uid) {
41
+ if (!isNullString(uid)) {
42
+ return uid;
43
+ }
44
+ if (isNullString(currentUserId)) {
45
+ throw new error_1.EngageError('User ID missing. Call identify() first or provide a uid parameter.');
46
+ }
47
+ return currentUserId;
48
+ }
33
49
  function _request(url, params, method) {
34
50
  return __awaiter(this, void 0, void 0, function* () {
35
51
  try {
@@ -38,11 +54,11 @@ function _request(url, params, method) {
38
54
  headers: {
39
55
  'Content-Type': 'application/json;charset=utf-8',
40
56
  Authorization: `Basic ${auth}`
41
- },
57
+ }
42
58
  // throwHttpErrors: false,
43
59
  // prefixUrl: rootURL
44
60
  };
45
- if (params) {
61
+ if (!isNull(params)) {
46
62
  o.body = JSON.stringify(params);
47
63
  }
48
64
  // const response = await ky(url, o)
@@ -50,7 +66,7 @@ function _request(url, params, method) {
50
66
  const body = yield response.json();
51
67
  let error = 'API connection error';
52
68
  if (!response.ok) {
53
- if (body && body.error) {
69
+ if (typeof (body === null || body === void 0 ? void 0 : body.error) === 'string') {
54
70
  error = body.error;
55
71
  }
56
72
  return { error };
@@ -64,47 +80,52 @@ function _request(url, params, method) {
64
80
  }
65
81
  // Alias of _request method
66
82
  // Same with _request for now but can later have modifications
67
- function request(url, params, method) {
68
- return _request(url, params, method);
83
+ function request(url, params, method = 'GET') {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ return yield _request(url, params, method);
86
+ });
69
87
  }
70
88
  exports.request = request;
71
89
  function init(key) {
72
- if (!key) {
90
+ var _a, _b;
91
+ if (isNull(key)) {
73
92
  throw new error_1.EngageError('You need to pass in your API key(s).');
74
93
  }
94
+ // Clear any stored user ID when reinitializing
95
+ currentUserId = '';
75
96
  const options = {
76
- key: undefined,
97
+ key: '',
77
98
  secret: ''
78
99
  };
79
100
  if (typeof key === 'string') {
101
+ if (key === '') {
102
+ throw new error_1.EngageError('`key` is empty.');
103
+ }
80
104
  options.key = key;
81
105
  }
82
106
  else {
83
- if (!key.key) {
107
+ if (isNullString(key.key)) {
84
108
  throw new error_1.EngageError('`key` missing in object.');
85
109
  }
86
- if (key.key) {
87
- options.key = `${key.key}`;
88
- }
89
- if (key.secret) {
90
- options.secret = `${key.secret}`;
110
+ options.key = key.key;
111
+ if (!isNullString(key.secret)) {
112
+ options.secret = key.secret;
91
113
  }
92
114
  }
93
115
  // Set auth
94
- // auth = Buffer.from(`${options.key}:${options.secret}`).toString('base64')
95
- auth = btoa(`${options.key}:${options.secret}`);
116
+ auth = btoa(`${(_a = options.key) !== null && _a !== void 0 ? _a : ''}:${(_b = options.secret) !== null && _b !== void 0 ? _b : ''}`);
96
117
  }
97
118
  exports.init = init;
98
119
  // Data tracking
99
120
  function identify(user) {
100
121
  return __awaiter(this, void 0, void 0, function* () {
101
- if (!user) {
122
+ if (isNull(user)) {
102
123
  throw new error_1.EngageError('You need to pass an object with at least an id.');
103
124
  }
104
- if (!user.id) {
125
+ if (isNullString(user.id)) {
105
126
  throw new error_1.EngageError('ID missing.');
106
127
  }
107
- if (user.email && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
128
+ if (!isNull(user.email) && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
108
129
  throw new error_1.EngageError('Email invalid.');
109
130
  }
110
131
  const params = {};
@@ -117,72 +138,106 @@ function identify(user) {
117
138
  params.meta[k] = user[k];
118
139
  }
119
140
  }
120
- return _request(`/users/${user.id}`, params, 'PUT');
141
+ // Store the user ID for use in other functions
142
+ currentUserId = user.id;
143
+ return yield _request(`/users/${user.id}`, params, 'PUT');
121
144
  });
122
145
  }
123
146
  exports.identify = identify;
124
- function addAttribute(uid, attributes) {
147
+ function addAttribute(uidOrAttributes, attributes) {
125
148
  return __awaiter(this, void 0, void 0, function* () {
126
- if (!uid) {
127
- throw new error_1.EngageError('User ID missing.');
149
+ let uid;
150
+ let attrs;
151
+ // Handle overloaded parameters
152
+ if (typeof uidOrAttributes === 'string') {
153
+ uid = resolveUserId(uidOrAttributes);
154
+ if (isNull(attributes)) {
155
+ throw new error_1.EngageError('Attributes missing when uid is provided.');
156
+ }
157
+ attrs = attributes;
128
158
  }
129
- if (!attributes) {
159
+ else {
160
+ uid = resolveUserId();
161
+ attrs = uidOrAttributes;
162
+ }
163
+ if (isNull(attrs)) {
130
164
  throw new error_1.EngageError('Attributes missing.');
131
165
  }
132
- if (!Object.keys(attributes).length) {
166
+ if (Object.keys(attrs).length === 0) {
133
167
  throw new error_1.EngageError('Attributes missing.');
134
168
  }
135
169
  const params = {};
136
170
  params.meta = {};
137
- for (const k in attributes) {
171
+ for (const k in attrs) {
138
172
  if (notMeta.includes(k)) {
139
- params[k] = attributes[k];
173
+ params[k] = attrs[k];
140
174
  }
141
175
  else {
142
- params.meta[k] = attributes[k];
176
+ params.meta[k] = attrs[k];
143
177
  }
144
178
  }
145
- if (!Object.keys(params.meta).length) {
179
+ if (Object.keys(params.meta).length === 0) {
146
180
  delete params.meta;
147
181
  }
148
- return _request(`/users/${uid}`, params, 'PUT');
182
+ return yield _request(`/users/${uid}`, params, 'PUT');
149
183
  });
150
184
  }
151
185
  exports.addAttribute = addAttribute;
152
- function track(uid, data) {
186
+ function track(uidOrData, data) {
153
187
  return __awaiter(this, void 0, void 0, function* () {
154
- if (!uid) {
155
- throw new error_1.EngageError('User ID missing.');
188
+ let uid;
189
+ let eventData;
190
+ // Handle overloaded parameters
191
+ if (typeof uidOrData === 'string') {
192
+ uid = resolveUserId(uidOrData);
193
+ if (isNull(data)) {
194
+ throw new error_1.EngageError('Event data missing when uid is provided.');
195
+ }
196
+ eventData = data;
156
197
  }
157
- if (!data) {
198
+ else {
199
+ uid = resolveUserId();
200
+ eventData = uidOrData;
201
+ }
202
+ if (isNull(eventData)) {
158
203
  throw new error_1.EngageError('Event data missing.');
159
204
  }
160
- if (typeof data === 'string') {
161
- data = {
162
- event: data,
205
+ if (typeof eventData === 'string') {
206
+ eventData = {
207
+ event: eventData,
163
208
  value: true
164
209
  };
165
210
  }
166
211
  else {
167
- if (!Object.keys(data).length) {
212
+ if (Object.keys(eventData).length === 0) {
168
213
  throw new error_1.EngageError('Attributes missing.');
169
214
  }
170
215
  }
171
- return _request(`/users/${uid}/events`, data, 'POST');
216
+ return yield _request(`/users/${uid}/events`, eventData, 'POST');
172
217
  });
173
218
  }
174
219
  exports.track = track;
175
- function merge(sourceUid, destinationUid) {
220
+ function merge(sourceOrDestinationUid, destinationUid) {
176
221
  return __awaiter(this, void 0, void 0, function* () {
177
- if (!sourceUid) {
178
- throw new error_1.EngageError('Source ID missing.');
222
+ let sourceUid;
223
+ let destUid;
224
+ // Handle overloaded parameters
225
+ if (isNullString(destinationUid)) {
226
+ // Called with one parameter: merge(destinationUid)
227
+ sourceUid = resolveUserId();
228
+ destUid = sourceOrDestinationUid;
229
+ }
230
+ else {
231
+ // Called with two parameters: merge(sourceUid, destinationUid)
232
+ sourceUid = resolveUserId(sourceOrDestinationUid);
233
+ destUid = destinationUid;
179
234
  }
180
- if (!destinationUid) {
235
+ if (isNullString(destUid)) {
181
236
  throw new error_1.EngageError('Destination ID missing.');
182
237
  }
183
- return _request(`/users/merge`, {
238
+ return yield _request('/users/merge', {
184
239
  source: sourceUid,
185
- destination: destinationUid
240
+ destination: destUid
186
241
  }, 'POST');
187
242
  });
188
243
  }
@@ -190,67 +245,102 @@ exports.merge = merge;
190
245
  // Account functions
191
246
  function addToAccount(uid, accountId, role) {
192
247
  return __awaiter(this, void 0, void 0, function* () {
193
- if (!uid) {
248
+ if (isNullString(uid)) {
194
249
  throw new error_1.EngageError('User ID missing.');
195
250
  }
196
- if (!accountId) {
251
+ if (isNullString(accountId)) {
197
252
  throw new error_1.EngageError('Account ID missing.');
198
253
  }
199
- if (role && typeof role !== 'string') {
254
+ if (!isNull(role) && typeof role !== 'string') {
200
255
  throw new error_1.EngageError('Role should be a text.');
201
256
  }
202
257
  const g = {
203
258
  id: accountId
204
259
  };
205
- if (role) {
260
+ if (!isNullString(role)) {
206
261
  g.role = role;
207
262
  }
208
- return _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST');
263
+ return yield _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST');
209
264
  });
210
265
  }
211
266
  exports.addToAccount = addToAccount;
212
- function removeFromAccount(uid, accountId) {
267
+ function removeFromAccount(uidOrAccountId, accountId) {
213
268
  return __awaiter(this, void 0, void 0, function* () {
214
- if (!uid) {
215
- throw new error_1.EngageError('User ID missing.');
269
+ let uid;
270
+ let acctId;
271
+ // Handle overloaded parameters
272
+ if (isNullString(accountId)) {
273
+ // Called with one parameter: removeFromAccount(accountId)
274
+ uid = resolveUserId();
275
+ acctId = uidOrAccountId;
276
+ }
277
+ else {
278
+ // Called with two parameters: removeFromAccount(uid, accountId)
279
+ uid = resolveUserId(uidOrAccountId);
280
+ acctId = accountId;
216
281
  }
217
- if (!accountId) {
282
+ if (isNullString(acctId)) {
218
283
  throw new error_1.EngageError('Account ID missing.');
219
284
  }
220
- return _request(`/users/${uid}/accounts/${accountId}`, null, 'DELETE');
285
+ return yield _request(`/users/${uid}/accounts/${acctId}`, null, 'DELETE');
221
286
  });
222
287
  }
223
288
  exports.removeFromAccount = removeFromAccount;
224
- function changeAccountRole(uid, accountId, role) {
289
+ function changeAccountRole(uidOrAccountId, accountIdOrRole, role) {
225
290
  return __awaiter(this, void 0, void 0, function* () {
226
- if (!uid) {
227
- throw new error_1.EngageError('User ID missing.');
291
+ let uid;
292
+ let accountId;
293
+ let newRole;
294
+ // Handle overloaded parameters
295
+ if (isNullString(role)) {
296
+ // Called with two parameters: changeAccountRole(accountId, role)
297
+ uid = resolveUserId();
298
+ accountId = uidOrAccountId;
299
+ newRole = accountIdOrRole;
228
300
  }
229
- if (!accountId) {
301
+ else {
302
+ // Called with three parameters: changeAccountRole(uid, accountId, role)
303
+ uid = resolveUserId(uidOrAccountId);
304
+ accountId = accountIdOrRole;
305
+ newRole = role;
306
+ }
307
+ if (isNullString(accountId)) {
230
308
  throw new error_1.EngageError('Account ID missing.');
231
309
  }
232
- if (!role) {
310
+ if (isNullString(newRole)) {
233
311
  throw new error_1.EngageError('New role missing.');
234
312
  }
235
- return _request(`/users/${uid}/accounts/${accountId}`, { role }, 'PUT');
313
+ return yield _request(`/users/${uid}/accounts/${accountId}`, { role: newRole }, 'PUT');
236
314
  });
237
315
  }
238
316
  exports.changeAccountRole = changeAccountRole;
239
317
  function convertToCustomer(uid) {
240
318
  return __awaiter(this, void 0, void 0, function* () {
241
- if (!uid) {
242
- throw new error_1.EngageError('User ID missing.');
243
- }
244
- return _request(`/users/${uid}/convert`, { type: 'customer' }, 'POST');
319
+ const userId = resolveUserId(uid);
320
+ return yield _request(`/users/${userId}/convert`, { type: 'customer' }, 'POST');
245
321
  });
246
322
  }
247
323
  exports.convertToCustomer = convertToCustomer;
248
324
  function convertToAccount(uid) {
249
325
  return __awaiter(this, void 0, void 0, function* () {
250
- if (!uid) {
251
- throw new error_1.EngageError('User ID missing.');
252
- }
253
- return _request(`/users/${uid}/convert`, { type: 'account' }, 'POST');
326
+ const userId = resolveUserId(uid);
327
+ return yield _request(`/users/${userId}/convert`, { type: 'account' }, 'POST');
254
328
  });
255
329
  }
256
330
  exports.convertToAccount = convertToAccount;
331
+ // Create an object containing all exports for easy access
332
+ const EngageSDK = {
333
+ init,
334
+ identify,
335
+ addAttribute,
336
+ track,
337
+ merge,
338
+ addToAccount,
339
+ removeFromAccount,
340
+ changeAccountRole,
341
+ convertToCustomer,
342
+ convertToAccount,
343
+ request
344
+ };
345
+ // Export as default for import EngageSDK syntax
346
+ exports.default = EngageSDK;
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@engage_so/core",
3
- "version": "2.1.1",
4
- "description": "Engage JS core.",
3
+ "version": "2.2.1",
4
+ "description": "Engage JavaScript SDK (core)",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist/",
9
+ "README.md"
10
+ ],
7
11
  "scripts": {
8
12
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
9
- "build": "tsc -p tsconfig.json",
10
- "prepublishOnly": "npm run build"
11
- },
12
- "publishConfig": {
13
- "access": "public"
13
+ "build": "rm -rf dist && tsc -p tsconfig.json",
14
+ "prepare": "npm run build"
14
15
  },
15
16
  "author": "Engage",
16
17
  "license": "MIT",
@@ -23,8 +24,6 @@
23
24
  "ts-standard": "^12.0.2"
24
25
  },
25
26
  "dependencies": {
26
- "buffer": "^6.0.3",
27
27
  "cross-fetch": "^4.0.0"
28
- },
29
- "gitHead": "6900dcf5defb812e5182bca56762860c838f5266"
28
+ }
30
29
  }
package/.eslintignore DELETED
@@ -1,3 +0,0 @@
1
- dist
2
- node_modules
3
- tests
package/jest.config.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- transform: {
3
- '^.+\\.ts?$': ['ts-jest', { diagnostics: false }]
4
- },
5
- testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$',
6
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
7
- };
package/src/error.ts DELETED
@@ -1,6 +0,0 @@
1
- export class EngageError extends Error {
2
- constructor (message: string) {
3
- super(message)
4
- this.name = 'EngageError'
5
- }
6
- }
package/src/index.ts DELETED
@@ -1,241 +0,0 @@
1
- import { Buffer } from 'buffer'
2
- import fetch from 'cross-fetch'
3
- import { EngageError } from './error'
4
-
5
- if (typeof btoa === 'undefined') {
6
- global.btoa = function (str) {
7
- return Buffer.from(str).toString('base64')
8
- }
9
- }
10
-
11
- interface Key {
12
- key?: string
13
- secret?: string
14
- }
15
- interface EventParameter {
16
- event: string
17
- value?: string | number | Date | boolean
18
- properties?: {
19
- [key: string]: string | number | Date | boolean
20
- }
21
- timestamp?: string | number | Date
22
- }
23
- type UserAttrParams = {
24
- [key: string]: string | number | Date | boolean
25
- }
26
- type UserIdentifyParams = UserAttrParams & { id: string }
27
- type DataParameters = {
28
- [key: string]: string | number | Date | boolean
29
- } & {
30
- meta?: {
31
- [key: string]: string | number | Date | boolean
32
- }
33
- }
34
- type Methods = 'POST' | 'PUT' | 'DELETE'
35
- // type UserIdentifyParams = {
36
- // id: string
37
- // [key: string]: string | number | Date | boolean
38
- // }
39
- // type UserAttrParams = Omit<UserIdentifyParams, 'id'>
40
-
41
- // const rootURL = 'https://api.engage.so/v1'
42
- let auth: string = ''
43
- 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
- const apiRoot = 'https://api.engage.so/v1'
45
-
46
- async function _request (url: string, params: Record<string, any> | null, method: Methods) {
47
- try {
48
- const o: any = {
49
- method,
50
- headers: {
51
- 'Content-Type': 'application/json;charset=utf-8',
52
- Authorization: `Basic ${auth}`
53
- },
54
- // throwHttpErrors: false,
55
- // prefixUrl: rootURL
56
- }
57
- if (params) {
58
- o.body = JSON.stringify(params)
59
- }
60
- // const response = await ky(url, o)
61
- const response = await fetch(`${apiRoot}${url}`, o)
62
- const body: any = await response.json()
63
- let error = 'API connection error'
64
- if (!response.ok) {
65
- if (body && body.error) {
66
- error = body.error
67
- }
68
- return { error }
69
- }
70
- return body
71
- } catch (e) {
72
- return { error: 'API connection error' }
73
- }
74
- }
75
- // Alias of _request method
76
- // 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)
79
- }
80
-
81
- export function init (key: Key | string) {
82
- if (!key) {
83
- throw new EngageError('You need to pass in your API key(s).')
84
- }
85
- const options: Key = {
86
- key: undefined,
87
- secret: ''
88
- }
89
- if (typeof key === 'string') {
90
- options.key = key
91
- } else {
92
- if (!key.key) {
93
- throw new EngageError('`key` missing in object.')
94
- }
95
- if (key.key) {
96
- options.key = `${key.key}`
97
- }
98
- if (key.secret) {
99
- options.secret = `${key.secret}`
100
- }
101
- }
102
- // Set auth
103
- // auth = Buffer.from(`${options.key}:${options.secret}`).toString('base64')
104
- auth = btoa(`${options.key}:${options.secret}`)
105
- }
106
-
107
- // Data tracking
108
- export async function identify (user: UserIdentifyParams) {
109
- if (!user) {
110
- throw new EngageError('You need to pass an object with at least an id.')
111
- }
112
- if (!user.id) {
113
- throw new EngageError('ID missing.')
114
- }
115
- if (user.email && (typeof user.email !== 'string' || !/^\S+@\S+$/.test(user.email))) {
116
- throw new EngageError('Email invalid.')
117
- }
118
- const params: DataParameters = {}
119
- params.meta = {}
120
- for (const k in user) {
121
- if (k === 'id' || notMeta.includes(k)) {
122
- params[k] = user[k]
123
- } else {
124
- params.meta[k] = user[k]
125
- }
126
- }
127
-
128
- return _request(`/users/${user.id}`, params, 'PUT')
129
- }
130
- export async function addAttribute (uid: string, attributes: UserAttrParams) {
131
- if (!uid) {
132
- throw new EngageError('User ID missing.')
133
- }
134
- if (!attributes) {
135
- throw new EngageError('Attributes missing.')
136
- }
137
- if (!Object.keys(attributes).length) {
138
- throw new EngageError('Attributes missing.')
139
- }
140
- const params: DataParameters = {}
141
- params.meta = {}
142
- for (const k in attributes) {
143
- if (notMeta.includes(k)) {
144
- params[k] = attributes[k]
145
- } else {
146
- params.meta[k] = attributes[k]
147
- }
148
- }
149
- if (!Object.keys(params.meta).length) {
150
- delete params.meta
151
- }
152
-
153
- return _request(`/users/${uid}`, params, 'PUT')
154
- }
155
- export async function track (uid: string, data: EventParameter) {
156
- if (!uid) {
157
- throw new EngageError('User ID missing.')
158
- }
159
- if (!data) {
160
- throw new EngageError('Event data missing.')
161
- }
162
- if (typeof data === 'string') {
163
- data = {
164
- event: data,
165
- value: true
166
- }
167
- } else {
168
- if (!Object.keys(data).length) {
169
- throw new EngageError('Attributes missing.')
170
- }
171
- }
172
-
173
- return _request(`/users/${uid}/events`, data, 'POST')
174
- }
175
-
176
- export async function merge (sourceUid: string, destinationUid: string) {
177
- if (!sourceUid) {
178
- throw new EngageError('Source ID missing.')
179
- }
180
- if (!destinationUid) {
181
- throw new EngageError('Destination ID missing.')
182
- }
183
-
184
- return _request(`/users/merge`, {
185
- source: sourceUid,
186
- destination: destinationUid
187
- }, 'POST')
188
- }
189
-
190
- // Account functions
191
- export async function addToAccount(uid: string, accountId: string, role: string) {
192
- if (!uid) {
193
- throw new EngageError('User ID missing.')
194
- }
195
- if (!accountId) {
196
- throw new EngageError('Account ID missing.')
197
- }
198
- if (role && typeof role !== 'string') {
199
- throw new EngageError('Role should be a text.')
200
- }
201
- const g: Record<string, string> = {
202
- id: accountId
203
- }
204
- if (role) {
205
- g.role = role
206
- }
207
- return _request(`/users/${uid}/accounts`, { accounts: [g] }, 'POST')
208
- }
209
- export async function removeFromAccount (uid: string, accountId: string){
210
- if (!uid) {
211
- throw new EngageError('User ID missing.')
212
- }
213
- if (!accountId) {
214
- throw new EngageError('Account ID missing.')
215
- }
216
- return _request(`/users/${uid}/accounts/${accountId}`, null, 'DELETE')
217
- }
218
- export async function changeAccountRole (uid: string, accountId: string, role: string) {
219
- if (!uid) {
220
- throw new EngageError('User ID missing.')
221
- }
222
- if (!accountId) {
223
- throw new EngageError('Account ID missing.')
224
- }
225
- if (!role) {
226
- throw new EngageError('New role missing.')
227
- }
228
- return _request(`/users/${uid}/accounts/${accountId}`, { role }, 'PUT')
229
- }
230
- export async function convertToCustomer (uid: string) {
231
- if (!uid) {
232
- throw new EngageError('User ID missing.')
233
- }
234
- return _request(`/users/${uid}/convert`, { type: 'customer' }, 'POST')
235
- }
236
- export async function convertToAccount (uid: string) {
237
- if (!uid) {
238
- throw new EngageError('User ID missing.')
239
- }
240
- return _request(`/users/${uid}/convert`, { type: 'account' }, 'POST')
241
- }
@@ -1,231 +0,0 @@
1
- import * as Engage from '../src/index'
2
- const id = 'uzl38704@omeie.com'
3
- const sid = 'a6236e83-f7c1-4003-8e1a-951f6e1d5c60'
4
- const gid = '7d1a5e27-5a6b-4b38-a8bd-e59b8a1b2f41'
5
-
6
- describe('Init', () => {
7
- test('should throw if no parameters sent', () => {
8
- expect(() => {
9
- Engage.init()
10
- }).toThrow('API')
11
- })
12
- test('should throw if parameter is empty object', () => {
13
- expect(() => {
14
- Engage.init({})
15
- }).toThrow('key')
16
- })
17
- test('should throw if empty key sent', () => {
18
- expect(() => {
19
- Engage.init('')
20
- }).toThrow()
21
- })
22
- test('should not throw if key/secret is sent', () => {
23
- expect(() => {
24
- Engage.init({
25
- key: process.env.KEY,
26
- secret: process.env.SECRET
27
- })
28
- }).not.toThrow()
29
- })
30
- })
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
- describe('Add attribute', () => {
81
- test('should throw if no parameter passed', async () => {
82
- await expect(Engage.addAttribute()).rejects.toThrow('id')
83
- })
84
- test('should throw if no data attribute passed', async () => {
85
- await expect(Engage.addAttribute(id)).rejects.toThrow(/attributes/i)
86
- })
87
- test('should throw if empty object passed', async () => {
88
- await expect(Engage.addAttribute(id, {})).rejects.toThrow(/attributes/i)
89
- })
90
- test('should resolve if parameters passed', async () => {
91
- await expect(Engage.addAttribute(sid, {
92
- first_name: 'Opeyemi',
93
- active: true,
94
- created_at: '2020-08-11'
95
- })).resolves.toMatchObject({
96
- uid: sid,
97
- first_name: 'Opeyemi'
98
- })
99
- })
100
- test('should turn to account if has is_account', async () => {
101
- await expect(Engage.addAttribute(id, {
102
- is_account: true
103
- })).resolves.toMatchObject({
104
- is_account: true
105
- })
106
- })
107
- test('should turn to user if is_account is not added', async () => {
108
- await expect(Engage.addAttribute(id, {
109
- is_account: false
110
- })).resolves.toMatchObject({
111
- is_account: false
112
- })
113
- })
114
- })
115
-
116
- describe('Track', () => {
117
- test('should throw if no parameter passed', async () => {
118
- await expect(Engage.track()).rejects.toThrow('ID')
119
- })
120
- test('should throw if no data attribute passed', async () => {
121
- await expect(Engage.track(id)).rejects.toThrow(/data/i)
122
- })
123
- test('should throw if empty object passed', async () => {
124
- await expect(Engage.track(id, {})).rejects.toThrow(/attributes/i)
125
- })
126
- test('should pass if string property passed', async () => {
127
- await expect(Engage.track(id, 'loggedin')).resolves.toMatchObject({
128
- status: 'ok'
129
- })
130
- })
131
- test('should pass if right parameters passed', async () => {
132
- await expect(Engage.track(id, {
133
- event: 'played',
134
- value: 'vid_133',
135
- timestamp: '2020-05-30T09:30:10Z'
136
- })).resolves.toMatchObject({
137
- status: 'ok'
138
- })
139
- })
140
- test('should resolve if other variant passed', async () => {
141
- await expect(Engage.track(id, {
142
- event: 'loggedin',
143
- properties: {
144
- ip: '127.0.0.1',
145
- referral: 'localhost'
146
- }
147
- })).resolves.toMatchObject({
148
- status: 'ok'
149
- })
150
- })
151
- })
152
-
153
- describe('Merge users', () => {
154
- test('should throw if no source id', async () => {
155
- await expect(Engage.merge()).rejects.toThrow(/id/i)
156
- })
157
- test('should throw if no destination id', async () => {
158
- await expect(Engage.merge(id)).rejects.toThrow(/id/i)
159
- })
160
- test('should merge if all is well', async () => {
161
- await expect(Engage.merge(sid, id)).resolves.toMatchObject({
162
- status: 'queued'
163
- })
164
- })
165
- })
166
-
167
- describe('Convert to account', () => {
168
- test('should convert to account', async () => {
169
- await expect(Engage.convertToAccount(gid)).resolves.toMatchObject({
170
- is_account: true
171
- })
172
- })
173
- })
174
-
175
- describe('Convert to customer', () => {
176
- test('should convert to customer', async () => {
177
- await expect(Engage.convertToCustomer(gid)).resolves.toMatchObject({
178
- is_account: false
179
- })
180
- })
181
- })
182
-
183
- describe('Add to account', () => {
184
- test('should throw if no account id added', async () => {
185
- await expect(Engage.addToAccount(id)).rejects.toThrow(/id/i)
186
- })
187
- test('should throw if role and role not string', async () => {
188
- await expect(Engage.addToAccount(id, gid, [ 'something' ])).rejects.toThrow(/Role/)
189
- })
190
- test('should pass if account id added', async () => {
191
- await expect(Engage.addToAccount(id, gid)).resolves.toMatchObject({
192
- accounts: [{
193
- id: gid
194
- }]
195
- })
196
- })
197
- })
198
-
199
- describe('Change account role', () => {
200
- test('should throw if no parameters', async () => {
201
- await expect(Engage.changeAccountRole()).rejects.toThrow(/missing/)
202
- })
203
- test('should throw if no account id', async () => {
204
- await expect(Engage.changeAccountRole(id)).rejects.toThrow(/missing/)
205
- })
206
- test('should throw if no role', async () => {
207
- await expect(Engage.changeAccountRole(id, gid)).rejects.toThrow(/missing/)
208
- })
209
- test('should pass if all parameters set', async () => {
210
- await expect(Engage.changeAccountRole(id, gid, 'owner')).resolves.toMatchObject({
211
- accounts: [{
212
- id: gid,
213
- role: 'owner'
214
- }]
215
- })
216
- })
217
- })
218
-
219
- describe('Remove from account', () => {
220
- test('should throw if no parameters', async () => {
221
- await expect(Engage.removeFromAccount()).rejects.toThrow(/missing/)
222
- })
223
- test('should throw if no account id', async () => {
224
- await expect(Engage.removeFromAccount(id)).rejects.toThrow(/missing/)
225
- })
226
- test('should pass if all parameters set', async () => {
227
- await expect(Engage.removeFromAccount(id, gid)).resolves.toMatchObject({
228
- accounts: []
229
- })
230
- })
231
- })
package/tsconfig.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2015",
4
- "module": "NodeNext",
5
- "declaration": true,
6
- "declarationMap": true,
7
- "outDir": "./dist",
8
- "esModuleInterop": true,
9
- "forceConsistentCasingInFileNames": true,
10
- "strict": true,
11
- "skipLibCheck": true
12
- },
13
- "exclude": [
14
- "node_modules",
15
- "tests",
16
- "dist"
17
- ]
18
- }