@bentonow/bento-node-sdk 0.2.1 → 1.0.4

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 (75) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +494 -1077
  3. package/dist/index.d.ts +9 -9
  4. package/dist/index.js +1273 -5
  5. package/dist/sdk/batch/enums.d.ts +8 -8
  6. package/dist/sdk/batch/errors.d.ts +18 -18
  7. package/dist/sdk/batch/events.d.ts +71 -71
  8. package/dist/sdk/batch/index.d.ts +55 -55
  9. package/dist/sdk/batch/types.d.ts +37 -37
  10. package/dist/sdk/broadcasts/index.d.ts +25 -0
  11. package/dist/sdk/broadcasts/types.d.ts +28 -0
  12. package/dist/sdk/client/errors.d.ts +9 -6
  13. package/dist/sdk/client/index.d.ts +74 -64
  14. package/dist/sdk/client/types.d.ts +3 -3
  15. package/dist/sdk/commands/enums.d.ts +12 -12
  16. package/dist/sdk/commands/index.d.ts +79 -79
  17. package/dist/sdk/commands/types.d.ts +32 -32
  18. package/dist/sdk/email-templates/index.d.ts +21 -0
  19. package/dist/sdk/email-templates/types.d.ts +23 -0
  20. package/dist/sdk/enums.d.ts +12 -9
  21. package/dist/sdk/errors.d.ts +2 -2
  22. package/dist/sdk/experimental/index.d.ts +75 -57
  23. package/dist/sdk/experimental/types.d.ts +71 -41
  24. package/dist/sdk/fields/index.d.ts +29 -29
  25. package/dist/sdk/fields/types.d.ts +17 -17
  26. package/dist/sdk/forms/index.d.ts +14 -14
  27. package/dist/sdk/forms/types.d.ts +28 -28
  28. package/dist/sdk/index.d.ts +11 -8
  29. package/dist/sdk/interfaces.d.ts +13 -13
  30. package/dist/sdk/sequences/index.d.ts +13 -0
  31. package/dist/sdk/sequences/types.d.ts +18 -0
  32. package/dist/sdk/stats/index.d.ts +24 -0
  33. package/dist/sdk/stats/types.d.ts +26 -0
  34. package/dist/sdk/subscribers/index.d.ts +20 -20
  35. package/dist/sdk/subscribers/types.d.ts +25 -25
  36. package/dist/sdk/tags/index.d.ts +20 -20
  37. package/dist/sdk/tags/types.d.ts +17 -17
  38. package/dist/sdk/types.d.ts +41 -41
  39. package/dist/sdk/workflows/index.d.ts +13 -0
  40. package/dist/sdk/workflows/types.d.ts +18 -0
  41. package/dist/versions/v1/index.d.ts +164 -132
  42. package/dist/versions/v1/types.d.ts +31 -31
  43. package/package.json +31 -44
  44. package/src/sdk/batch/events.ts +1 -1
  45. package/src/sdk/batch/index.ts +13 -25
  46. package/src/sdk/broadcasts/index.ts +43 -0
  47. package/src/sdk/broadcasts/types.ts +34 -0
  48. package/src/sdk/client/errors.ts +7 -0
  49. package/src/sdk/client/index.ts +113 -30
  50. package/src/sdk/commands/index.ts +54 -89
  51. package/src/sdk/email-templates/index.ts +39 -0
  52. package/src/sdk/email-templates/types.ts +27 -0
  53. package/src/sdk/enums.ts +3 -0
  54. package/src/sdk/experimental/index.ts +44 -26
  55. package/src/sdk/experimental/types.ts +35 -0
  56. package/src/sdk/fields/index.ts +1 -3
  57. package/src/sdk/forms/index.ts +4 -9
  58. package/src/sdk/forms/types.ts +1 -7
  59. package/src/sdk/index.ts +3 -0
  60. package/src/sdk/sequences/index.ts +21 -0
  61. package/src/sdk/sequences/types.ts +21 -0
  62. package/src/sdk/stats/index.ts +37 -0
  63. package/src/sdk/stats/types.ts +28 -0
  64. package/src/sdk/subscribers/index.ts +5 -15
  65. package/src/sdk/tags/index.ts +1 -3
  66. package/src/sdk/types.ts +1 -1
  67. package/src/sdk/workflows/index.ts +21 -0
  68. package/src/sdk/workflows/types.ts +21 -0
  69. package/src/versions/v1/index.ts +59 -10
  70. package/dist/bento-node-sdk.cjs.development.js +0 -2071
  71. package/dist/bento-node-sdk.cjs.development.js.map +0 -1
  72. package/dist/bento-node-sdk.cjs.production.min.js +0 -2
  73. package/dist/bento-node-sdk.cjs.production.min.js.map +0 -1
  74. package/dist/bento-node-sdk.esm.js +0 -2063
  75. package/dist/bento-node-sdk.esm.js.map +0 -1
@@ -1,7 +1,34 @@
1
1
  import fetch from 'cross-fetch';
2
2
  import type { AnalyticsOptions, AuthenticationOptions } from '../interfaces';
3
- import { NotAuthorizedError, RateLimitedError } from './errors';
3
+ import { NotAuthorizedError, RateLimitedError, AuthorNotAuthorizedError } from './errors';
4
4
 
5
+ function encodeBase64(str: string): string {
6
+ if (typeof btoa === 'function') {
7
+ return btoa(str);
8
+ } else if (typeof Buffer !== 'undefined') {
9
+ return Buffer.from(str).toString('base64');
10
+ } else {
11
+ // Fallback implementation
12
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
13
+ let output = '';
14
+ for (
15
+ let block = 0, charCode, i = 0, map = chars;
16
+ str.charAt(i | 0) || ((map = '='), i % 1);
17
+ output += map.charAt(63 & (block >> (8 - (i % 1) * 8)))
18
+ ) {
19
+ charCode = str.charCodeAt((i += 3 / 4));
20
+
21
+ if (charCode > 0xff) {
22
+ throw new Error(
23
+ "'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."
24
+ );
25
+ }
26
+
27
+ block = (block << 8) | charCode;
28
+ }
29
+ return output;
30
+ }
31
+ }
5
32
  export class BentoClient {
6
33
  private readonly _headers: HeadersInit = {};
7
34
  private readonly _baseUrl: string = 'https://app.bentonow.com/api/v1';
@@ -11,7 +38,7 @@ export class BentoClient {
11
38
  constructor(options: AnalyticsOptions) {
12
39
  this._baseUrl = options.clientOptions?.baseUrl || this._baseUrl;
13
40
  this._siteUuid = options.siteUuid;
14
- this._headers = this._extractHeaders(options.authentication);
41
+ this._headers = this._extractHeaders(options.authentication, options.siteUuid);
15
42
  this._logErrors = options.logErrors || false;
16
43
  }
17
44
 
@@ -23,10 +50,7 @@ export class BentoClient {
23
50
  * @param payload object
24
51
  * @returns Promise\<T\>
25
52
  * */
26
- public get<T>(
27
- endpoint: string,
28
- payload: Record<string, unknown> = {}
29
- ): Promise<T> {
53
+ public get<T>(endpoint: string, payload: Record<string, unknown> = {}): Promise<T> {
30
54
  return new Promise<T>((resolve, reject) => {
31
55
  const queryParameters = this._getQueryParameters(payload);
32
56
 
@@ -34,15 +58,15 @@ export class BentoClient {
34
58
  method: 'GET',
35
59
  headers: this._headers,
36
60
  })
37
- .then(async result => {
61
+ .then(async (result) => {
38
62
  if (this._isSuccessfulStatus(result.status)) {
39
63
  return result.json();
40
64
  }
41
65
 
42
66
  throw await this._getErrorForResponse(result);
43
67
  })
44
- .then(data => resolve(data))
45
- .catch(error => reject(error));
68
+ .then((data) => resolve(data))
69
+ .catch((error) => reject(error));
46
70
  });
47
71
  }
48
72
 
@@ -54,10 +78,7 @@ export class BentoClient {
54
78
  * @param payload object
55
79
  * @returns Promise\<T\>
56
80
  * */
57
- public post<T>(
58
- endpoint: string,
59
- payload: Record<string, unknown> = {}
60
- ): Promise<T> {
81
+ public post<T>(endpoint: string, payload: Record<string, unknown> = {}): Promise<T> {
61
82
  return new Promise<T>((resolve, reject) => {
62
83
  const body = this._getBody(payload);
63
84
 
@@ -69,32 +90,66 @@ export class BentoClient {
69
90
  },
70
91
  body,
71
92
  })
72
- .then(async result => {
93
+ .then(async (result) => {
73
94
  if (this._isSuccessfulStatus(result.status)) {
74
95
  return result.json();
75
96
  }
76
97
 
77
98
  throw await this._getErrorForResponse(result);
78
99
  })
79
- .then(data => resolve(data))
80
- .catch(error => reject(error));
100
+ .then((data) => resolve(data))
101
+ .catch((error) => reject(error));
81
102
  });
82
103
  }
83
104
 
84
105
  /**
85
- * Extracts the `publishableKey` and `secretKey` from the `authentication` options and
86
- * adds the `Authorization` header.
106
+ * Wraps a PATCH request to the Bento API and automatically adds the required
107
+ * headers.
108
+ *
109
+ * @param endpoint string
110
+ * @param payload object
111
+ * @returns Promise\<T\>
112
+ * */
113
+ public patch<T>(endpoint: string, payload: Record<string, unknown> = {}): Promise<T> {
114
+ return new Promise<T>((resolve, reject) => {
115
+ const body = this._getBody(payload);
116
+
117
+ fetch(`${this._baseUrl}${endpoint}`, {
118
+ method: 'PATCH',
119
+ headers: {
120
+ ...this._headers,
121
+ 'Content-Type': 'application/json',
122
+ },
123
+ body,
124
+ })
125
+ .then(async (result) => {
126
+ if (this._isSuccessfulStatus(result.status)) {
127
+ return result.json();
128
+ }
129
+
130
+ throw await this._getErrorForResponse(result);
131
+ })
132
+ .then((data) => resolve(data))
133
+ .catch((error) => reject(error));
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Extracts the `publishableKey` and `secretKey` from the `authentication` options,
139
+ * adds the `Authorization` header, and includes a `User-Agent` header with the site UUID.
87
140
  *
88
141
  * @param authentication AuthenticationOptions
142
+ * @param siteUuid string The site UUID to be included in the User-Agent header
89
143
  * @returns HeadersInit
90
144
  */
91
- private _extractHeaders(authentication: AuthenticationOptions): HeadersInit {
92
- const authenticationKey = Buffer.from(
145
+ private _extractHeaders(authentication: AuthenticationOptions, siteUuid: string): HeadersInit {
146
+ const authenticationKey = encodeBase64(
93
147
  `${authentication.publishableKey}:${authentication.secretKey}`
94
- ).toString('base64');
148
+ );
95
149
 
96
150
  return {
97
151
  Authorization: `Basic ${authenticationKey}`,
152
+ 'User-Agent': `bento-node-${siteUuid}`,
98
153
  };
99
154
  }
100
155
 
@@ -161,17 +216,45 @@ export class BentoClient {
161
216
 
162
217
  const contentType = response.headers.get('Content-Type');
163
218
  let responseMessage = '';
219
+ let json: any = null;
164
220
 
165
- switch (contentType?.toLocaleLowerCase()) {
166
- case 'text/plain':
167
- responseMessage = await response.text();
168
- break;
169
- case 'application/json':
170
- responseMessage = JSON.stringify(await response.json());
171
- break;
172
- default:
221
+ // Try to parse the response body based on content type
222
+ try {
223
+ if (contentType?.toLowerCase().includes('application/json')) {
224
+ // For JSON content type, try to parse as JSON
225
+ try {
226
+ json = await response.json();
227
+ } catch {
228
+ responseMessage = 'Unable to parse JSON response';
229
+ }
230
+ } else if (contentType?.toLowerCase().includes('text/plain')) {
231
+ // For text/plain content type, read as text
232
+ try {
233
+ responseMessage = await response.text();
234
+ } catch {
235
+ responseMessage = 'Unable to read text response';
236
+ }
237
+ } else {
238
+ // For unknown content types, use default message
173
239
  responseMessage = 'Unknown response from the Bento API.';
174
- break;
240
+ }
241
+ } catch {
242
+ responseMessage = 'Unable to read response body';
243
+ }
244
+
245
+ // Check for author not authorized error in JSON response
246
+ if (json && json.error === 'Author not authorized to send on this account') {
247
+ return new AuthorNotAuthorizedError(json.error);
248
+ }
249
+
250
+ // If we have JSON but no specific error match, use the JSON string
251
+ if (json) {
252
+ responseMessage = JSON.stringify(json);
253
+ }
254
+
255
+ // If we still don't have a message, use a default
256
+ if (!responseMessage) {
257
+ responseMessage = 'Unknown response from the Bento API.';
175
258
  }
176
259
 
177
260
  return new Error(`[${response.status}] - ${responseMessage}`);
@@ -30,19 +30,14 @@ export class BentoCommands<S> {
30
30
  * @param parameters \{ email: string, tagName: string \}
31
31
  * @returns Promise\<Subscriber | null\>
32
32
  */
33
- public async addTag(
34
- parameters: AddTagParameters
35
- ): Promise<Subscriber<S> | null> {
36
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
37
- this._url,
38
- {
39
- command: {
40
- command: CommandTypes.ADD_TAG,
41
- email: parameters.email,
42
- query: parameters.tagName,
43
- },
44
- }
45
- );
33
+ public async addTag(parameters: AddTagParameters): Promise<Subscriber<S> | null> {
34
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
35
+ command: {
36
+ command: CommandTypes.ADD_TAG,
37
+ email: parameters.email,
38
+ query: parameters.tagName,
39
+ },
40
+ });
46
41
 
47
42
  if (Object.keys(result).length === 0 || !result.data) return null;
48
43
  return result.data;
@@ -54,19 +49,14 @@ export class BentoCommands<S> {
54
49
  * @param parameters \{ email: string, tagName: string \}
55
50
  * @returns Promise\<Subscriber | null\>
56
51
  */
57
- public async removeTag(
58
- parameters: RemoveTagParameters
59
- ): Promise<Subscriber<S> | null> {
60
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
61
- this._url,
62
- {
63
- command: {
64
- command: CommandTypes.REMOVE_TAG,
65
- email: parameters.email,
66
- query: parameters.tagName,
67
- },
68
- }
69
- );
52
+ public async removeTag(parameters: RemoveTagParameters): Promise<Subscriber<S> | null> {
53
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
54
+ command: {
55
+ command: CommandTypes.REMOVE_TAG,
56
+ email: parameters.email,
57
+ query: parameters.tagName,
58
+ },
59
+ });
70
60
 
71
61
  if (Object.keys(result).length === 0 || !result.data) return null;
72
62
  return result.data;
@@ -84,19 +74,14 @@ export class BentoCommands<S> {
84
74
  * @param parameters \{ email: string, field: \{ key: string; value: string; \} \}
85
75
  * @returns Promise\<Subscriber | null\>
86
76
  */
87
- public async addField(
88
- parameters: AddFieldParameters<S>
89
- ): Promise<Subscriber<S> | null> {
90
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
91
- this._url,
92
- {
93
- command: {
94
- command: CommandTypes.ADD_FIELD,
95
- email: parameters.email,
96
- query: parameters.field,
97
- },
98
- }
99
- );
77
+ public async addField(parameters: AddFieldParameters<S>): Promise<Subscriber<S> | null> {
78
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
79
+ command: {
80
+ command: CommandTypes.ADD_FIELD,
81
+ email: parameters.email,
82
+ query: parameters.field,
83
+ },
84
+ });
100
85
 
101
86
  if (Object.keys(result).length === 0 || !result.data) return null;
102
87
  return result.data;
@@ -108,19 +93,14 @@ export class BentoCommands<S> {
108
93
  * @param parameters \{ email: string, fieldName: string \}
109
94
  * @returns Promise\<Subscriber | null\>
110
95
  */
111
- public async removeField(
112
- parameters: RemoveFieldParameters<S>
113
- ): Promise<Subscriber<S> | null> {
114
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
115
- this._url,
116
- {
117
- command: {
118
- command: CommandTypes.REMOVE_FIELD,
119
- email: parameters.email,
120
- query: parameters.fieldName,
121
- },
122
- }
123
- );
96
+ public async removeField(parameters: RemoveFieldParameters<S>): Promise<Subscriber<S> | null> {
97
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
98
+ command: {
99
+ command: CommandTypes.REMOVE_FIELD,
100
+ email: parameters.email,
101
+ query: parameters.fieldName,
102
+ },
103
+ });
124
104
 
125
105
  if (Object.keys(result).length === 0 || !result.data) return null;
126
106
  return result.data;
@@ -136,18 +116,13 @@ export class BentoCommands<S> {
136
116
  * @param parameters \{ email: string \}
137
117
  * @returns Promise\<Subscriber | null\>
138
118
  */
139
- public async subscribe(
140
- parameters: SubscribeParameters
141
- ): Promise<Subscriber<S> | null> {
142
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
143
- this._url,
144
- {
145
- command: {
146
- command: CommandTypes.SUBSCRIBE,
147
- email: parameters.email,
148
- },
149
- }
150
- );
119
+ public async subscribe(parameters: SubscribeParameters): Promise<Subscriber<S> | null> {
120
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
121
+ command: {
122
+ command: CommandTypes.SUBSCRIBE,
123
+ email: parameters.email,
124
+ },
125
+ });
151
126
 
152
127
  if (Object.keys(result).length === 0 || !result.data) return null;
153
128
  return result.data;
@@ -164,18 +139,13 @@ export class BentoCommands<S> {
164
139
  * @param parameters \{ email: string \}
165
140
  * @returns Promise\<Subscriber | null\>
166
141
  */
167
- public async unsubscribe(
168
- parameters: UnsubscribeParameters
169
- ): Promise<Subscriber<S> | null> {
170
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
171
- this._url,
172
- {
173
- command: {
174
- command: CommandTypes.UNSUBSCRIBE,
175
- email: parameters.email,
176
- },
177
- }
178
- );
142
+ public async unsubscribe(parameters: UnsubscribeParameters): Promise<Subscriber<S> | null> {
143
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
144
+ command: {
145
+ command: CommandTypes.UNSUBSCRIBE,
146
+ email: parameters.email,
147
+ },
148
+ });
179
149
 
180
150
  if (Object.keys(result).length === 0 || !result.data) return null;
181
151
  return result.data;
@@ -187,19 +157,14 @@ export class BentoCommands<S> {
187
157
  * @param parameters \{ oldEmail: string, newEmail: string \}
188
158
  * @returns Promise\<Subscriber | null\>
189
159
  */
190
- public async changeEmail(
191
- parameters: ChangeEmailParameters
192
- ): Promise<Subscriber<S> | null> {
193
- const result = await this._client.post<DataResponse<Subscriber<S>>>(
194
- this._url,
195
- {
196
- command: {
197
- command: CommandTypes.CHANGE_EMAIL,
198
- email: parameters.oldEmail,
199
- query: parameters.newEmail,
200
- },
201
- }
202
- );
160
+ public async changeEmail(parameters: ChangeEmailParameters): Promise<Subscriber<S> | null> {
161
+ const result = await this._client.post<DataResponse<Subscriber<S>>>(this._url, {
162
+ command: {
163
+ command: CommandTypes.CHANGE_EMAIL,
164
+ email: parameters.oldEmail,
165
+ query: parameters.newEmail,
166
+ },
167
+ });
203
168
 
204
169
  if (Object.keys(result).length === 0 || !result.data) return null;
205
170
  return result.data;
@@ -0,0 +1,39 @@
1
+ import type { BentoClient } from '../client';
2
+ import type { DataResponse } from '../client/types';
3
+ import type { EmailTemplate, GetEmailTemplateParameters, UpdateEmailTemplateParameters } from './types';
4
+
5
+ export class BentoEmailTemplates {
6
+ private readonly _url = '/fetch/emails/templates';
7
+
8
+ constructor(private readonly _client: BentoClient) {}
9
+
10
+ /**
11
+ * Returns a single email template by ID.
12
+ *
13
+ * @param parameters GetEmailTemplateParameters
14
+ * @returns Promise\<EmailTemplate | null\>
15
+ */
16
+ public async getEmailTemplate(parameters: GetEmailTemplateParameters): Promise<EmailTemplate | null> {
17
+ const result = await this._client.get<DataResponse<EmailTemplate>>(`${this._url}/${parameters.id}`);
18
+
19
+ if (Object.keys(result).length === 0 || !result.data) return null;
20
+ return result.data;
21
+ }
22
+
23
+ /**
24
+ * Updates an email template's subject and/or HTML content.
25
+ *
26
+ * @param parameters UpdateEmailTemplateParameters
27
+ * @returns Promise\<EmailTemplate | null\>
28
+ */
29
+ public async updateEmailTemplate(parameters: UpdateEmailTemplateParameters): Promise<EmailTemplate | null> {
30
+ const { id, ...updateFields } = parameters;
31
+
32
+ const result = await this._client.patch<DataResponse<EmailTemplate>>(`${this._url}/${id}`, {
33
+ email_template: updateFields,
34
+ });
35
+
36
+ if (Object.keys(result).length === 0 || !result.data) return null;
37
+ return result.data;
38
+ }
39
+ }
@@ -0,0 +1,27 @@
1
+ import type { BaseEntity } from '../types';
2
+
3
+ /**
4
+ * Email Template Method Parameter Types
5
+ */
6
+ export type GetEmailTemplateParameters = {
7
+ id: number;
8
+ };
9
+
10
+ export type UpdateEmailTemplateParameters = {
11
+ id: number;
12
+ subject?: string;
13
+ html?: string;
14
+ };
15
+
16
+ /**
17
+ * Core Email Template Types
18
+ */
19
+ export type EmailTemplateAttributes = {
20
+ name: string;
21
+ subject: string;
22
+ html: string;
23
+ created_at: string;
24
+ stats: Record<string, unknown> | null;
25
+ };
26
+
27
+ export type EmailTemplate = BaseEntity<EmailTemplateAttributes>;
package/src/sdk/enums.ts CHANGED
@@ -6,4 +6,7 @@ export enum EntityType {
6
6
  TAGS = 'tags',
7
7
  VISITORS = 'visitors',
8
8
  VISITORS_FIELDS = 'visitors-fields',
9
+ SEQUENCES = 'sequences',
10
+ WORKFLOWS = 'workflows',
11
+ EMAIL_TEMPLATES = 'email_templates',
9
12
  }
@@ -1,8 +1,9 @@
1
1
  import type { BentoClient } from '../client';
2
2
  import type { LocationData } from '../types';
3
3
  import type {
4
+ BlacklistCheckInput,
4
5
  BlacklistParameters,
5
- BlacklistResponse,
6
+ BlacklistResponse, BlacklistResult, ContentModerationResult,
6
7
  GeolocateParameters,
7
8
  GeolocateResponse,
8
9
  GuessGenderParameters,
@@ -29,18 +30,13 @@ export class BentoExperimental {
29
30
  * @param parameters
30
31
  * @returns Promise\<boolean\>
31
32
  */
32
- public async validateEmail(
33
- parameters: ValidateEmailParameters
34
- ): Promise<boolean> {
35
- const result = await this._client.post<ValidateEmailResponse>(
36
- `${this._url}/validation`,
37
- {
38
- email: parameters.email,
39
- ip: parameters.ip,
40
- name: parameters.name,
41
- user_agent: parameters.userAgent,
42
- }
43
- );
33
+ public async validateEmail(parameters: ValidateEmailParameters): Promise<boolean> {
34
+ const result = await this._client.post<ValidateEmailResponse>(`${this._url}/validation`, {
35
+ email: parameters.email,
36
+ ip: parameters.ip,
37
+ name: parameters.name,
38
+ user_agent: parameters.userAgent,
39
+ });
44
40
 
45
41
  return result.valid;
46
42
  }
@@ -58,13 +54,8 @@ export class BentoExperimental {
58
54
  * @param parameters
59
55
  * @returns Promise\<GuessGenderResponse\>
60
56
  */
61
- public async guessGender(
62
- parameters: GuessGenderParameters
63
- ): Promise<GuessGenderResponse> {
64
- const result = await this._client.post<GuessGenderResponse>(
65
- `${this._url}/gender`,
66
- parameters
67
- );
57
+ public async guessGender(parameters: GuessGenderParameters): Promise<GuessGenderResponse> {
58
+ const result = await this._client.post<GuessGenderResponse>(`${this._url}/gender`, parameters);
68
59
 
69
60
  return result;
70
61
  }
@@ -78,9 +69,7 @@ export class BentoExperimental {
78
69
  * @param parameters
79
70
  * @returns Promise\<GeolocateResponse\>
80
71
  */
81
- public async geolocate(
82
- parameters: GeolocateParameters
83
- ): Promise<LocationData | null> {
72
+ public async geolocate(parameters: GeolocateParameters): Promise<LocationData | null> {
84
73
  const result = await this._client.get<GeolocateResponse>(
85
74
  `${this._url}/geolocation`,
86
75
  parameters
@@ -100,9 +89,7 @@ export class BentoExperimental {
100
89
  * @param parameters
101
90
  * @returns Promise\<BlacklistResponse\>
102
91
  */
103
- public async checkBlacklist(
104
- parameters: BlacklistParameters
105
- ): Promise<BlacklistResponse> {
92
+ public async checkBlacklist(parameters: BlacklistParameters): Promise<BlacklistResponse> {
106
93
  const result = await this._client.get<BlacklistResponse>(
107
94
  `${this._url}/blacklist.json`,
108
95
  parameters
@@ -110,4 +97,35 @@ export class BentoExperimental {
110
97
 
111
98
  return result;
112
99
  }
100
+
101
+ /**
102
+ * Checks if a domain or IP is blacklisted
103
+ * @param input Domain or IP to check
104
+ * @returns Promise<BlacklistResult>
105
+ */
106
+ public async getBlacklistStatus(input: BlacklistCheckInput): Promise<BlacklistResult> {
107
+ return this._client.get<BlacklistResult>(`${this._url}/blacklist`, input);
108
+ }
109
+
110
+ /**
111
+ * Performs content moderation on provided text
112
+ * @param content Text content to moderate
113
+ * @returns Promise<ContentModerationResult>
114
+ */
115
+ public async getContentModeration(content: string): Promise<ContentModerationResult> {
116
+ return this._client.post<ContentModerationResult>(`${this._url}/moderation`, {
117
+ content
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Gets geolocation data for an IP address
123
+ * @param ipAddress IP address to geolocate
124
+ * @returns Promise<LocationData>
125
+ */
126
+ public async geoLocateIP(ipAddress: string): Promise<LocationData> {
127
+ return this._client.get<LocationData>(`${this._url}/geolocation`, {
128
+ ip: ipAddress
129
+ });
130
+ }
113
131
  }
@@ -28,6 +28,13 @@ export type BlacklistParameters =
28
28
  ip: string;
29
29
  };
30
30
 
31
+ export type BlacklistCheckInput = {
32
+ domain?: string;
33
+ ipAddress?: string;
34
+ };
35
+
36
+
37
+
31
38
  /**
32
39
  * Experimental Method Response Types
33
40
  */
@@ -47,3 +54,31 @@ export type BlacklistResponse = {
47
54
  query: string;
48
55
  results: { [key: string]: boolean };
49
56
  };
57
+
58
+ export type BlacklistResult = {
59
+ description: string;
60
+ query: string;
61
+ results: Record<string, boolean>;
62
+ };
63
+
64
+ export type ContentModerationResult = {
65
+ flagged: boolean;
66
+ categories: {
67
+ hate: boolean;
68
+ 'hate/threatening': boolean;
69
+ 'self-harm': boolean;
70
+ sexual: boolean;
71
+ 'sexual/minors': boolean;
72
+ violence: boolean;
73
+ 'violence/graphic': boolean;
74
+ };
75
+ category_scores: {
76
+ hate: number;
77
+ 'hate/threatening': number;
78
+ 'self-harm': number;
79
+ sexual: number;
80
+ 'sexual/minors': number;
81
+ violence: number;
82
+ 'violence/graphic': number;
83
+ };
84
+ };
@@ -34,9 +34,7 @@ export class BentoFields {
34
34
  * @param parameters \{ key: string \}
35
35
  * @returns Promise<Field[]>
36
36
  */
37
- public async createField(
38
- parameters: CreateFieldParameters
39
- ): Promise<Field[] | null> {
37
+ public async createField(parameters: CreateFieldParameters): Promise<Field[] | null> {
40
38
  const result = await this._client.post<DataResponse<Field[]>>(this._url, {
41
39
  field: parameters,
42
40
  });
@@ -13,15 +13,10 @@ export class BentoForms {
13
13
  * @param formIdentifier string
14
14
  * @returns Promise\<FormResponse[] | null\>
15
15
  */
16
- public async getResponses(
17
- formIdentifier: string
18
- ): Promise<FormResponse[] | null> {
19
- const result = await this._client.get<DataResponse<FormResponse[]>>(
20
- this._url,
21
- {
22
- id: formIdentifier,
23
- }
24
- );
16
+ public async getResponses(formIdentifier: string): Promise<FormResponse[] | null> {
17
+ const result = await this._client.get<DataResponse<FormResponse[]>>(this._url, {
18
+ id: formIdentifier,
19
+ });
25
20
 
26
21
  if (Object.keys(result).length === 0 || !result.data) return null;
27
22
  return result.data;
@@ -1,10 +1,4 @@
1
- import type {
2
- BaseEntity,
3
- BrowserData,
4
- IdentityData,
5
- LocationData,
6
- PageData,
7
- } from '../types';
1
+ import type { BaseEntity, BrowserData, IdentityData, LocationData, PageData } from '../types';
8
2
 
9
3
  /**
10
4
  * Core Form Types