@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.
- package/README.md +15 -45
- package/dist/bugspotter.min.js +1 -1
- package/dist/bugspotter.min.js.map +1 -1
- package/dist/core/bug-reporter.js +6 -4
- package/dist/core/transport.d.ts +2 -3
- package/dist/core/uploader.d.ts +0 -1
- package/dist/core/uploader.js +0 -1
- package/dist/index.d.ts +5 -7
- package/dist/index.esm.js +17 -23
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +7 -4
- package/dist/utils/config-validator.d.ts +2 -3
- package/dist/utils/config-validator.js +3 -13
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/eslint.config.js +7 -0
- package/package.json +4 -4
- package/release_notes.md +1 -1
|
@@ -137,7 +137,7 @@ class BugReporter {
|
|
|
137
137
|
var _a;
|
|
138
138
|
(0, config_validator_1.validateAuthConfig)({
|
|
139
139
|
endpoint: this.config.endpoint,
|
|
140
|
-
|
|
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
|
|
169
|
-
|
|
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.
|
|
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 });
|
package/dist/core/transport.d.ts
CHANGED
|
@@ -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) */
|
package/dist/core/uploader.d.ts
CHANGED
package/dist/core/uploader.js
CHANGED
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 {
|
|
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 {
|
|
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 = '
|
|
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
|
|
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.
|
|
2967
|
-
throw new Error('API key
|
|
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
|
-
|
|
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
|
|
16781
|
-
|
|
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.
|
|
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
|
|
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
|
-
//
|
|
17299
|
-
if (!(
|
|
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.
|
|
17297
|
+
backendSettings = yield fetchReplaySettings(config.endpoint, config.apiKey);
|
|
17304
17298
|
}
|
|
17305
17299
|
}
|
|
17306
17300
|
// Merge backend settings with user config (user config takes precedence)
|