@product7/feedback-sdk 1.6.6 → 1.6.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@product7/feedback-sdk",
3
- "version": "1.6.6",
3
+ "version": "1.6.7",
4
4
  "description": "JavaScript SDK for integrating Product7 feedback widgets into any website",
5
5
  "main": "dist/feedback-sdk.js",
6
6
  "module": "src/index.js",
@@ -1,4 +1,4 @@
1
- import { MOCK_CHANGELOGS } from '../mock-data';
1
+ import { MOCK_CHANGELOGS } from '../mock-data/index.js';
2
2
  import { delay } from '../utils/helpers.js';
3
3
 
4
4
  export class ChangelogService {
@@ -1,4 +1,4 @@
1
- import { MOCK_HELP_COLLECTIONS } from '../mock-data';
1
+ import { MOCK_HELP_COLLECTIONS } from '../mock-data/index.js';
2
2
  import { delay } from '../utils/helpers.js';
3
3
 
4
4
  export class HelpService {
@@ -1,4 +1,4 @@
1
- import { MOCK_CONVERSATIONS, MOCK_MESSAGES } from '../mock-data';
1
+ import { MOCK_CONVERSATIONS, MOCK_MESSAGES } from '../mock-data/index.js';
2
2
  import { delay } from '../utils/helpers.js';
3
3
 
4
4
  export class MessengerService {
@@ -1,5 +1,5 @@
1
1
  import { APIError } from '../../utils/errors.js';
2
- import { MOCK_SURVEYS } from '../mock-data';
2
+ import { MOCK_SURVEYS } from '../mock-data/index.js';
3
3
  import { delay, getDeviceInfo } from '../utils/helpers.js';
4
4
 
5
5
  export class SurveyService {
@@ -90,15 +90,19 @@ export class BaseAPIService {
90
90
  body: JSON.stringify(payload),
91
91
  headers: { 'Content-Type': 'application/json' },
92
92
  });
93
+ const initData = this._extractInitResponseData(response);
93
94
 
94
- this.sessionToken = response.session_token;
95
- this.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);
95
+ this.sessionToken = initData.sessionToken;
96
+ this.sessionExpiry = new Date(Date.now() + initData.expiresIn * 1000);
96
97
  this._storeSession();
97
98
 
98
99
  return {
99
100
  sessionToken: this.sessionToken,
100
- config: response.config || {},
101
- expiresIn: response.expires_in,
101
+ config: initData.config,
102
+ expiresIn: initData.expiresIn,
103
+ status: initData.status,
104
+ message: initData.message,
105
+ configVersion: initData.configVersion,
102
106
  };
103
107
  } catch (error) {
104
108
  throw new APIError(
@@ -109,6 +113,34 @@ export class BaseAPIService {
109
113
  }
110
114
  }
111
115
 
116
+ _extractInitResponseData(response) {
117
+ const payload =
118
+ response && typeof response.data === 'object' ? response.data : response || {};
119
+
120
+ const sessionToken = payload.session_token || payload.sessionToken;
121
+ const expiresIn = Number(payload.expires_in ?? payload.expiresIn);
122
+
123
+ if (!sessionToken) {
124
+ throw new APIError(500, 'Invalid init response: missing session_token');
125
+ }
126
+
127
+ if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
128
+ throw new APIError(500, 'Invalid init response: missing expires_in');
129
+ }
130
+
131
+ return {
132
+ sessionToken,
133
+ expiresIn,
134
+ config:
135
+ payload.config && typeof payload.config === 'object'
136
+ ? payload.config
137
+ : {},
138
+ configVersion: payload.config_version ?? payload.configVersion ?? null,
139
+ status: response?.status ?? payload?.status ?? true,
140
+ message: response?.message ?? payload?.message ?? null,
141
+ };
142
+ }
143
+
112
144
  async _ensureSession() {
113
145
  if (!this.isSessionValid()) {
114
146
  await this.init();
@@ -65,6 +65,10 @@ export class FeedbackSDK {
65
65
  const widgetId = generateId('widget');
66
66
  const widgetConfig = this._getWidgetTypeConfig(type);
67
67
  const explicitOptions = this._omitUndefined(options);
68
+ const widgetEnabled = this._isWidgetEnabled(type, {
69
+ ...widgetConfig,
70
+ ...explicitOptions,
71
+ });
68
72
  const widgetOptions = {
69
73
  id: widgetId,
70
74
  sdk: this,
@@ -72,6 +76,7 @@ export class FeedbackSDK {
72
76
  ...this.config,
73
77
  ...widgetConfig,
74
78
  ...explicitOptions,
79
+ enabled: widgetEnabled,
75
80
  };
76
81
 
77
82
  try {
@@ -162,6 +167,7 @@ export class FeedbackSDK {
162
167
  surveyConfig.showDescription ?? surveyConfig.show_description,
163
168
  customQuestions: surveyConfig.customQuestions || surveyConfig.questions,
164
169
  pages: surveyConfig.pages,
170
+ enabled: surveyConfig.enabled,
165
171
  ...displayOptions,
166
172
  });
167
173
  }
@@ -184,6 +190,17 @@ export class FeedbackSDK {
184
190
 
185
191
  const normalizedOptions = this._normalizeSurveyConfig(options);
186
192
  const surveyConfigDefaults = this._getWidgetTypeConfig('survey');
193
+ const surveyEnabled = this._isWidgetEnabled('survey', normalizedOptions);
194
+
195
+ if (!surveyEnabled) {
196
+ this.eventBus.emit('survey:suppressed', {
197
+ surveyId:
198
+ normalizedOptions.surveyId || normalizedOptions.id || options.id || null,
199
+ reason: 'disabled',
200
+ survey: normalizedOptions,
201
+ });
202
+ return null;
203
+ }
187
204
 
188
205
  const surveyWidget = this.createWidget('survey', {
189
206
  surveyId: normalizedOptions.surveyId,
@@ -215,6 +232,7 @@ export class FeedbackSDK {
215
232
  email: normalizedOptions.email,
216
233
  onSubmit: normalizedOptions.onSubmit,
217
234
  onDismiss: normalizedOptions.onDismiss,
235
+ enabled: surveyEnabled,
218
236
  });
219
237
 
220
238
  surveyWidget.mount();
@@ -308,13 +326,19 @@ export class FeedbackSDK {
308
326
  : {};
309
327
 
310
328
  const inferredType =
311
- survey.type || this._inferSurveyTypeFromPage(firstPage) || 'nps';
329
+ survey.surveyType ||
330
+ survey.survey_type ||
331
+ survey.type ||
332
+ this._inferSurveyTypeFromPage(firstPage) ||
333
+ 'nps';
312
334
 
313
335
  return {
314
336
  ...survey,
315
- surveyId: survey.surveyId || survey.id || null,
316
- surveyType: survey.surveyType || inferredType,
317
- type: survey.type || inferredType,
337
+ surveyId: survey.surveyId || survey.survey_id || survey.id || null,
338
+ surveyType: survey.surveyType || survey.survey_type || inferredType,
339
+ type: survey.type || survey.survey_type || inferredType,
340
+ enabled:
341
+ typeof survey.enabled === 'boolean' ? survey.enabled : undefined,
318
342
  should_show:
319
343
  survey.should_show ??
320
344
  (survey.eligibility ? survey.eligibility.should_show : undefined),
@@ -343,7 +367,11 @@ export class FeedbackSDK {
343
367
  showTitle: survey.showTitle ?? survey.show_title ?? null,
344
368
  showDescription:
345
369
  survey.showDescription ?? survey.show_description ?? null,
346
- customQuestions: survey.customQuestions || survey.questions || [],
370
+ customQuestions:
371
+ survey.customQuestions ||
372
+ survey.custom_questions ||
373
+ survey.questions ||
374
+ [],
347
375
  pages: this._normalizeSurveyPages(survey.pages || []),
348
376
  };
349
377
  }
@@ -418,6 +446,23 @@ export class FeedbackSDK {
418
446
  return this._toCamelCaseObject(mergedTypeConfig);
419
447
  }
420
448
 
449
+ _isWidgetEnabled(type, options = {}) {
450
+ const typeConfig = this._getWidgetTypeConfig(type);
451
+ if (typeConfig.enabled === false) {
452
+ return false;
453
+ }
454
+
455
+ if (typeof options.enabled === 'boolean') {
456
+ return options.enabled;
457
+ }
458
+
459
+ if (typeof typeConfig.enabled === 'boolean') {
460
+ return typeConfig.enabled;
461
+ }
462
+
463
+ return true;
464
+ }
465
+
421
466
  _isPlainObject(value) {
422
467
  return Object.prototype.toString.call(value) === '[object Object]';
423
468
  }
@@ -471,11 +516,21 @@ export class FeedbackSDK {
471
516
 
472
517
  const configDefaults = this._getWidgetTypeConfig('changelog');
473
518
  const explicitOptions = this._omitUndefined(options);
519
+ const changelogEnabled = this._isWidgetEnabled('changelog', explicitOptions);
520
+
521
+ if (!changelogEnabled) {
522
+ this.eventBus.emit('widget:suppressed', {
523
+ type: 'changelog',
524
+ reason: 'disabled',
525
+ });
526
+ return null;
527
+ }
474
528
 
475
529
  const changelogWidget = this.createWidget('changelog', {
476
530
  ...defaults,
477
531
  ...configDefaults,
478
532
  ...explicitOptions,
533
+ enabled: changelogEnabled,
479
534
  });
480
535
 
481
536
  changelogWidget.mount();
@@ -48,6 +48,15 @@ export class BaseWidget {
48
48
  mount(container) {
49
49
  if (this.mounted || this.destroyed) return this;
50
50
 
51
+ if (this.options.enabled === false) {
52
+ this.sdk.eventBus.emit('widget:suppressed', {
53
+ widget: this,
54
+ type: this.type,
55
+ reason: 'disabled',
56
+ });
57
+ return this;
58
+ }
59
+
51
60
  if (this.options.suppressAfterSubmission && this._hasRecentlySubmitted()) {
52
61
  this.sdk.eventBus.emit('widget:suppressed', {
53
62
  widget: this,
@@ -8,6 +8,8 @@ export class SurveyWidget extends BaseWidget {
8
8
  surveyId: options.surveyId || null,
9
9
  surveyType: options.surveyType || 'nps',
10
10
  position: options.position || 'bottom-right',
11
+ enabled:
12
+ typeof options.enabled === 'boolean' ? options.enabled : undefined,
11
13
  title: options.title || null,
12
14
  description: options.description || null,
13
15
  lowLabel: options.lowLabel || null,
@@ -61,6 +63,15 @@ export class SurveyWidget extends BaseWidget {
61
63
  }
62
64
 
63
65
  show() {
66
+ if (this.options.enabled === false || this.surveyOptions.enabled === false) {
67
+ this.sdk.eventBus.emit('survey:suppressed', {
68
+ widget: this,
69
+ surveyId: this.surveyOptions.surveyId,
70
+ reason: 'disabled',
71
+ });
72
+ return this;
73
+ }
74
+
64
75
  this._renderSurvey();
65
76
  this.surveyState.isVisible = true;
66
77
  this.sdk.eventBus.emit('survey:shown', {
package/types/index.d.ts CHANGED
@@ -28,6 +28,7 @@ declare module '@product7/feedback-sdk' {
28
28
  }
29
29
 
30
30
  export interface ButtonWidgetOptions {
31
+ enabled?: boolean;
31
32
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
32
33
  theme?: 'light' | 'dark';
33
34
  boardId?: string;
@@ -78,6 +79,9 @@ declare module '@product7/feedback-sdk' {
78
79
  config?: any;
79
80
  sessionToken?: string;
80
81
  expiresIn?: number;
82
+ status?: boolean;
83
+ message?: string | null;
84
+ configVersion?: number | null;
81
85
  }>;
82
86
  createWidget(type: 'button', options?: ButtonWidgetOptions): ButtonWidget;
83
87
  createWidget(type: 'survey', options?: SurveyWidgetOptions): SurveyWidget;
@@ -152,6 +156,7 @@ declare module '@product7/feedback-sdk' {
152
156
  }
153
157
 
154
158
  export interface SurveyWidgetOptions {
159
+ enabled?: boolean;
155
160
  surveyId?: string | null;
156
161
  surveyType?: SurveyType;
157
162
  position?: 'bottom-right' | 'bottom-left' | 'center' | 'bottom';
@@ -225,6 +230,7 @@ declare module '@product7/feedback-sdk' {
225
230
  }
226
231
 
227
232
  export interface ChangelogWidgetOptions {
233
+ enabled?: boolean;
228
234
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
229
235
  theme?: 'light' | 'dark';
230
236
  triggerText?: string;
@@ -254,6 +260,7 @@ declare module '@product7/feedback-sdk' {
254
260
  }
255
261
 
256
262
  export interface MessengerWidgetOptions {
263
+ enabled?: boolean;
257
264
  position?: 'bottom-right' | 'bottom-left';
258
265
  theme?: 'light' | 'dark';
259
266
  teamName?: string;