@bugspotter/sdk 1.1.0 → 2.0.5

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.
@@ -137,7 +137,7 @@ class BugReporter {
137
137
  var _a;
138
138
  (0, config_validator_1.validateAuthConfig)({
139
139
  endpoint: this.config.endpoint,
140
- auth: this.config.auth,
140
+ apiKey: this.config.apiKey,
141
141
  });
142
142
  const dedupContext = createDeduplicationContext(payload);
143
143
  if (this.deduplicator.isDuplicate(dedupContext.title, dedupContext.description, dedupContext.errorStacks)) {
@@ -165,8 +165,10 @@ class BugReporter {
165
165
  network: report.network,
166
166
  metadata: report.metadata,
167
167
  }, hasScreenshot: fileAnalysis.hasScreenshot, hasReplay: fileAnalysis.hasReplay });
168
- const response = await (0, transport_1.submitWithAuth)(this.config.endpoint, JSON.stringify(createPayload), { 'Content-Type': 'application/json' }, {
169
- auth: this.config.auth,
168
+ const apiBaseUrl = (0, url_helpers_1.getApiBaseUrl)(this.config.endpoint);
169
+ const submitUrl = `${apiBaseUrl}/api/v1/reports`;
170
+ const response = await (0, transport_1.submitWithAuth)(submitUrl, JSON.stringify(createPayload), { 'Content-Type': 'application/json' }, {
171
+ auth: { apiKey: this.config.apiKey },
170
172
  retry: this.config.retry,
171
173
  offline: this.config.offline,
172
174
  });
@@ -218,7 +220,7 @@ class BugReporter {
218
220
  throw new Error('Server did not provide presigned URLs for file uploads. Check backend configuration.');
219
221
  }
220
222
  const apiEndpoint = (0, url_helpers_1.getApiBaseUrl)(this.config.endpoint);
221
- const uploadHandler = new file_upload_handler_1.FileUploadHandler(apiEndpoint, this.config.auth.apiKey);
223
+ const uploadHandler = new file_upload_handler_1.FileUploadHandler(apiEndpoint, this.config.apiKey);
222
224
  try {
223
225
  await uploadHandler.uploadFiles(bugId, report, bugReportData.presignedUrls);
224
226
  logger.debug('File uploads completed successfully', { bugId });
@@ -16,12 +16,11 @@ export declare class AuthenticationError extends Error {
16
16
  constructor(message: string);
17
17
  }
18
18
  /**
19
- * Authentication configuration - API key only
19
+ * Authentication configuration - API key only.
20
+ * The API key is scoped to specific projects server-side.
20
21
  */
21
22
  export type AuthConfig = {
22
- type: 'api-key';
23
23
  apiKey: string;
24
- projectId: string;
25
24
  };
26
25
  export interface RetryConfig {
27
26
  /** Maximum number of retry attempts (default: 3) */
@@ -5,7 +5,6 @@
5
5
  export interface DirectUploadConfig {
6
6
  apiEndpoint: string;
7
7
  apiKey: string;
8
- projectId: string;
9
8
  bugId: string;
10
9
  }
11
10
  export interface UploadProgress {
@@ -97,7 +97,6 @@ class DirectUploader {
97
97
  'x-api-key': this.config.apiKey,
98
98
  },
99
99
  body: JSON.stringify({
100
- projectId: this.config.projectId,
101
100
  bugId: this.config.bugId,
102
101
  fileType,
103
102
  filename,
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { BrowserMetadata } from './capture/metadata';
2
2
  import { type FloatingButtonOptions } from './widget/button';
3
3
  import type { eventWithTime } from '@rrweb/types';
4
- import type { AuthConfig, RetryConfig } from './core/transport';
4
+ import type { RetryConfig } from './core/transport';
5
5
  import type { OfflineConfig } from './core/offline-queue';
6
6
  import { VERSION } from './version';
7
7
  import { type DeduplicationConfig } from './utils/deduplicator';
@@ -39,14 +39,12 @@ export declare class BugSpotter {
39
39
  destroy(): void;
40
40
  }
41
41
  export interface BugSpotterConfig {
42
+ /** Base URL of BugSpotter API (e.g., https://api.example.com). SDK appends paths internally. */
42
43
  endpoint?: string;
44
+ /** API key for authentication (starts with 'bgs_'). Required. */
45
+ apiKey: string;
43
46
  showWidget?: boolean;
44
47
  widgetOptions?: FloatingButtonOptions;
45
- /**
46
- * Authentication configuration (required)
47
- * API key authentication with project ID
48
- */
49
- auth: AuthConfig;
50
48
  /** Retry configuration for failed requests */
51
49
  retry?: RetryConfig;
52
50
  /** Offline queue configuration */
@@ -133,7 +131,7 @@ export { CircularBuffer } from './core/buffer';
133
131
  export type { CircularBufferConfig } from './core/buffer';
134
132
  export { compressData, decompressData, compressImage, estimateSize, getCompressionRatio, } from './core/compress';
135
133
  export { submitWithAuth, getAuthHeaders, clearOfflineQueue, } from './core/transport';
136
- export type { AuthConfig, TransportOptions, RetryConfig, } from './core/transport';
134
+ export type { TransportOptions, RetryConfig } from './core/transport';
137
135
  export type { OfflineConfig } from './core/offline-queue';
138
136
  export type { Logger, LogLevel, LoggerConfig } from './utils/logger';
139
137
  export { getLogger, configureLogger, createLogger } from './utils/logger';
package/dist/index.esm.js CHANGED
@@ -2944,14 +2944,14 @@ const MAX_RECOMMENDED_REPLAY_DURATION_SECONDS = 30;
2944
2944
  * This file is automatically generated during the build process.
2945
2945
  * To update the version, modify package.json
2946
2946
  */
2947
- const VERSION = '1.1.0';
2947
+ const VERSION = '2.0.5';
2948
2948
 
2949
2949
  /**
2950
2950
  * Configuration Validation Utilities
2951
2951
  * Validates BugSpotter configuration before use
2952
2952
  */
2953
2953
  /**
2954
- * Validate authentication configuration
2954
+ * Validate configuration before submitting a bug report
2955
2955
  * @throws Error if configuration is invalid
2956
2956
  */
2957
2957
  function validateAuthConfig(context) {
@@ -2959,21 +2959,11 @@ function validateAuthConfig(context) {
2959
2959
  throw new Error('No endpoint configured for bug report submission');
2960
2960
  }
2961
2961
  // SECURITY: Ensure endpoint uses HTTPS
2962
- // This prevents credentials and sensitive data from being sent over plain HTTP
2963
2962
  if (!isSecureEndpoint(context.endpoint)) {
2964
2963
  throw new InsecureEndpointError(context.endpoint);
2965
2964
  }
2966
- if (!context.auth) {
2967
- throw new Error('API key authentication is required');
2968
- }
2969
- if (context.auth.type !== 'api-key') {
2970
- throw new Error('API key authentication is required');
2971
- }
2972
- if (!context.auth.apiKey) {
2973
- throw new Error('API key is required in auth configuration');
2974
- }
2975
- if (!context.auth.projectId) {
2976
- throw new Error('Project ID is required in auth configuration');
2965
+ if (!context.apiKey) {
2966
+ throw new Error('API key is required');
2977
2967
  }
2978
2968
  }
2979
2969
  /**
@@ -16748,7 +16738,7 @@ class BugReporter {
16748
16738
  var _a;
16749
16739
  validateAuthConfig({
16750
16740
  endpoint: this.config.endpoint,
16751
- auth: this.config.auth,
16741
+ apiKey: this.config.apiKey,
16752
16742
  });
16753
16743
  const dedupContext = createDeduplicationContext(payload);
16754
16744
  if (this.deduplicator.isDuplicate(dedupContext.title, dedupContext.description, dedupContext.errorStacks)) {
@@ -16777,8 +16767,10 @@ class BugReporter {
16777
16767
  network: report.network,
16778
16768
  metadata: report.metadata,
16779
16769
  }, hasScreenshot: fileAnalysis.hasScreenshot, hasReplay: fileAnalysis.hasReplay });
16780
- const response = yield submitWithAuth(this.config.endpoint, JSON.stringify(createPayload), { 'Content-Type': 'application/json' }, {
16781
- auth: this.config.auth,
16770
+ const apiBaseUrl = getApiBaseUrl(this.config.endpoint);
16771
+ const submitUrl = `${apiBaseUrl}/api/v1/reports`;
16772
+ const response = yield submitWithAuth(submitUrl, JSON.stringify(createPayload), { 'Content-Type': 'application/json' }, {
16773
+ auth: { apiKey: this.config.apiKey },
16782
16774
  retry: this.config.retry,
16783
16775
  offline: this.config.offline,
16784
16776
  });
@@ -16832,7 +16824,7 @@ class BugReporter {
16832
16824
  throw new Error('Server did not provide presigned URLs for file uploads. Check backend configuration.');
16833
16825
  }
16834
16826
  const apiEndpoint = getApiBaseUrl(this.config.endpoint);
16835
- const uploadHandler = new FileUploadHandler(apiEndpoint, this.config.auth.apiKey);
16827
+ const uploadHandler = new FileUploadHandler(apiEndpoint, this.config.apiKey);
16836
16828
  try {
16837
16829
  yield uploadHandler.uploadFiles(bugId, report, bugReportData.presignedUrls);
16838
16830
  logger$1.debug('File uploads completed successfully', { bugId });
@@ -16960,7 +16952,6 @@ class DirectUploader {
16960
16952
  'x-api-key': this.config.apiKey,
16961
16953
  },
16962
16954
  body: JSON.stringify({
16963
- projectId: this.config.projectId,
16964
16955
  bugId: this.config.bugId,
16965
16956
  fileType,
16966
16957
  filename,
@@ -17290,17 +17281,20 @@ class BugSpotter {
17290
17281
  */
17291
17282
  static createInstance(config) {
17292
17283
  return __awaiter$1(this, void 0, void 0, function* () {
17293
- var _a, _b, _c;
17284
+ var _a, _b;
17294
17285
  // Fetch replay quality settings from backend if replay is enabled
17295
17286
  let backendSettings = null;
17296
17287
  const replayEnabled = (_b = (_a = config.replay) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;
17297
17288
  if (replayEnabled && config.endpoint) {
17298
- // Validate auth is configured before attempting fetch
17299
- if (!((_c = config.auth) === null || _c === void 0 ? void 0 : _c.apiKey)) {
17289
+ // SECURITY: Don't send API key over insecure connection
17290
+ if (!isSecureEndpoint(config.endpoint)) {
17291
+ logger.warn('Insecure endpoint — skipping backend settings fetch to protect API key.');
17292
+ }
17293
+ else if (!config.apiKey) {
17300
17294
  logger.warn('Endpoint provided but no API key configured. Skipping backend settings fetch.');
17301
17295
  }
17302
17296
  else {
17303
- backendSettings = yield fetchReplaySettings(config.endpoint, config.auth.apiKey);
17297
+ backendSettings = yield fetchReplaySettings(config.endpoint, config.apiKey);
17304
17298
  }
17305
17299
  }
17306
17300
  // Merge backend settings with user config (user config takes precedence)