@bugspotter/sdk 1.0.0 → 1.1.0
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/dist/bugspotter.min.js +1 -1
- package/dist/bugspotter.min.js.map +1 -1
- package/dist/capture/console.js +2 -2
- package/dist/capture/network.js +2 -2
- package/dist/index.esm.js +210 -313
- package/dist/index.esm.js.map +1 -1
- package/dist/utils/sanitize-patterns.d.ts +3 -76
- package/dist/utils/sanitize-patterns.js +18 -216
- package/dist/utils/url-helpers.d.ts +2 -40
- package/dist/utils/url-helpers.js +10 -97
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/release_notes.md +1 -16
- package/rollup.config.js +1 -1
- package/dist/core/circular-buffer.d.ts +0 -42
- package/dist/core/circular-buffer.js +0 -80
|
@@ -1,42 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PII Pattern Definitions
|
|
3
|
-
*
|
|
3
|
+
* Re-exports from @bugspotter/common + SDK-specific extensions
|
|
4
4
|
*/
|
|
5
|
-
export type PIIPatternName
|
|
6
|
-
|
|
7
|
-
* Pattern definition with metadata
|
|
8
|
-
*/
|
|
9
|
-
export interface PatternDefinition {
|
|
10
|
-
/** Pattern name/identifier */
|
|
11
|
-
name: PIIPatternName;
|
|
12
|
-
/** Regular expression for detection */
|
|
13
|
-
regex: RegExp;
|
|
14
|
-
/** Human-readable description */
|
|
15
|
-
description: string;
|
|
16
|
-
/** Examples of data this pattern matches */
|
|
17
|
-
examples: string[];
|
|
18
|
-
/** Priority order (lower = higher priority, checked first) */
|
|
19
|
-
priority: number;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Default built-in patterns
|
|
23
|
-
*/
|
|
24
|
-
export declare const DEFAULT_PATTERNS: Record<PIIPatternName, PatternDefinition>;
|
|
25
|
-
/**
|
|
26
|
-
* Pattern categories for grouping
|
|
27
|
-
*/
|
|
28
|
-
export declare const PATTERN_CATEGORIES: {
|
|
29
|
-
readonly financial: PIIPatternName[];
|
|
30
|
-
readonly contact: PIIPatternName[];
|
|
31
|
-
readonly identification: PIIPatternName[];
|
|
32
|
-
readonly network: PIIPatternName[];
|
|
33
|
-
readonly credentials: PIIPatternName[];
|
|
34
|
-
readonly kazakhstan: PIIPatternName[];
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Get patterns sorted by priority
|
|
38
|
-
*/
|
|
39
|
-
export declare function getPatternsByPriority(patterns: PatternDefinition[]): PatternDefinition[];
|
|
5
|
+
export { type PIIPatternName, type PatternDefinition, type PatternPresetName, DEFAULT_PATTERNS, PATTERN_CATEGORIES, PATTERN_PRESETS, getAllPatternNames, getPatternsByPriority, getPatternsByPreset, createPatternConfig, validatePattern, } from '@bugspotter/common';
|
|
6
|
+
import { type PIIPatternName, type PatternDefinition, PATTERN_CATEGORIES } from '@bugspotter/common';
|
|
40
7
|
/**
|
|
41
8
|
* Get pattern by name
|
|
42
9
|
*/
|
|
@@ -45,10 +12,6 @@ export declare function getPattern(name: PIIPatternName): PatternDefinition;
|
|
|
45
12
|
* Get patterns by category
|
|
46
13
|
*/
|
|
47
14
|
export declare function getPatternsByCategory(category: keyof typeof PATTERN_CATEGORIES): PatternDefinition[];
|
|
48
|
-
/**
|
|
49
|
-
* Get all pattern names
|
|
50
|
-
*/
|
|
51
|
-
export declare function getAllPatternNames(): PIIPatternName[];
|
|
52
15
|
/**
|
|
53
16
|
* Custom pattern builder for advanced use cases
|
|
54
17
|
*/
|
|
@@ -61,42 +24,6 @@ export declare class PatternBuilder {
|
|
|
61
24
|
priority(priority: number): this;
|
|
62
25
|
build(): PatternDefinition;
|
|
63
26
|
}
|
|
64
|
-
/**
|
|
65
|
-
* Pre-configured pattern sets for common use cases
|
|
66
|
-
*/
|
|
67
|
-
export declare const PATTERN_PRESETS: {
|
|
68
|
-
/** All patterns enabled (PII + credentials) - default */
|
|
69
|
-
readonly all: PIIPatternName[];
|
|
70
|
-
/** Minimal - only most critical PII */
|
|
71
|
-
readonly minimal: PIIPatternName[];
|
|
72
|
-
/** Financial data only */
|
|
73
|
-
readonly financial: PIIPatternName[];
|
|
74
|
-
/** Contact information only */
|
|
75
|
-
readonly contact: PIIPatternName[];
|
|
76
|
-
/** Identification numbers only */
|
|
77
|
-
readonly identification: PIIPatternName[];
|
|
78
|
-
/** Credentials and secrets only */
|
|
79
|
-
readonly credentials: PIIPatternName[];
|
|
80
|
-
/** Kazakhstan-specific patterns */
|
|
81
|
-
readonly kazakhstan: PIIPatternName[];
|
|
82
|
-
/** GDPR compliance recommended set */
|
|
83
|
-
readonly gdpr: PIIPatternName[];
|
|
84
|
-
/** PCI DSS compliance required */
|
|
85
|
-
readonly pci: PIIPatternName[];
|
|
86
|
-
/** Security-focused: PII + credentials */
|
|
87
|
-
readonly security: PIIPatternName[];
|
|
88
|
-
};
|
|
89
|
-
/**
|
|
90
|
-
* Create custom pattern configuration
|
|
91
|
-
*/
|
|
92
|
-
export declare function createPatternConfig(preset: keyof typeof PATTERN_PRESETS | PIIPatternName[]): PatternDefinition[];
|
|
93
|
-
/**
|
|
94
|
-
* Validate pattern regex
|
|
95
|
-
*/
|
|
96
|
-
export declare function validatePattern(pattern: PatternDefinition): {
|
|
97
|
-
valid: boolean;
|
|
98
|
-
errors: string[];
|
|
99
|
-
};
|
|
100
27
|
/**
|
|
101
28
|
* Merge pattern configurations
|
|
102
29
|
*/
|
|
@@ -1,156 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* PII Pattern Definitions
|
|
4
|
-
*
|
|
4
|
+
* Re-exports from @bugspotter/common + SDK-specific extensions
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
-
exports.getPatternsByPriority = getPatternsByPriority;
|
|
7
|
+
exports.PatternBuilder = exports.validatePattern = exports.createPatternConfig = exports.getPatternsByPreset = exports.getPatternsByPriority = exports.getAllPatternNames = exports.PATTERN_PRESETS = exports.PATTERN_CATEGORIES = exports.DEFAULT_PATTERNS = void 0;
|
|
9
8
|
exports.getPattern = getPattern;
|
|
10
9
|
exports.getPatternsByCategory = getPatternsByCategory;
|
|
11
|
-
exports.getAllPatternNames = getAllPatternNames;
|
|
12
|
-
exports.createPatternConfig = createPatternConfig;
|
|
13
|
-
exports.validatePattern = validatePattern;
|
|
14
10
|
exports.mergePatternConfigs = mergePatternConfigs;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
exports.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
],
|
|
28
|
-
priority: 1, // Highest priority - most specific
|
|
29
|
-
},
|
|
30
|
-
creditcard: {
|
|
31
|
-
name: 'creditcard',
|
|
32
|
-
regex: /\b(?:\d{4}[-\s]){3}\d{4}\b|\b\d{4}[-\s]\d{6}[-\s]\d{5}\b|\b\d{13,19}\b/g,
|
|
33
|
-
description: 'Credit card numbers (Visa, MC, Amex, Discover, etc.)',
|
|
34
|
-
examples: [
|
|
35
|
-
'4532-1488-0343-6467',
|
|
36
|
-
'4532148803436467',
|
|
37
|
-
'5425 2334 3010 9903',
|
|
38
|
-
'3782 822463 10005',
|
|
39
|
-
],
|
|
40
|
-
priority: 2,
|
|
41
|
-
},
|
|
42
|
-
ssn: {
|
|
43
|
-
name: 'ssn',
|
|
44
|
-
regex: /\b\d{3}-\d{2}-\d{4}\b|\b(?<!\d)\d{9}(?!\d)\b/g,
|
|
45
|
-
description: 'US Social Security Numbers',
|
|
46
|
-
examples: ['123-45-6789', '987654321'],
|
|
47
|
-
priority: 3,
|
|
48
|
-
},
|
|
49
|
-
iin: {
|
|
50
|
-
name: 'iin',
|
|
51
|
-
regex: /\b[0-9]{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12][0-9]|3[01])\d{6}\b/g,
|
|
52
|
-
description: 'Kazakhstan IIN/BIN (12 digits with date validation)',
|
|
53
|
-
examples: ['950315300123', '880612500456', '021225123456'],
|
|
54
|
-
priority: 4,
|
|
55
|
-
},
|
|
56
|
-
ip: {
|
|
57
|
-
name: 'ip',
|
|
58
|
-
regex: /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,
|
|
59
|
-
description: 'IPv4 and IPv6 addresses',
|
|
60
|
-
examples: [
|
|
61
|
-
'192.168.1.100',
|
|
62
|
-
'127.0.0.1',
|
|
63
|
-
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
|
|
64
|
-
],
|
|
65
|
-
priority: 5,
|
|
66
|
-
},
|
|
67
|
-
phone: {
|
|
68
|
-
name: 'phone',
|
|
69
|
-
regex: /\+\d{1,3}[-.\s]\d{3}[-.\s]\d{4}\b|\+\d{1,3}[-.\s]\d{3}[-.\s]\d{3}[-.\s]\d{4}\b|\(\d{3}\)\s*\d{3}[-.\s]\d{4}\b|\b\d{3}[-.\s]\d{3}[-.\s]\d{4}\b/g,
|
|
70
|
-
description: 'International phone numbers',
|
|
71
|
-
examples: [
|
|
72
|
-
'+1-555-1234',
|
|
73
|
-
'+1-555-123-4567',
|
|
74
|
-
'(555) 123-4567',
|
|
75
|
-
'555-123-4567',
|
|
76
|
-
'+7 777 123 4567',
|
|
77
|
-
],
|
|
78
|
-
priority: 6,
|
|
79
|
-
},
|
|
80
|
-
apikey: {
|
|
81
|
-
name: 'apikey',
|
|
82
|
-
regex: /\b(?:sk|pk)_(?:live|test)_[a-zA-Z0-9]{24,}\b|AIza[a-zA-Z0-9_-]{35}|ya29\.[a-zA-Z0-9_-]+|AKIA[a-zA-Z0-9]{16}\b/g,
|
|
83
|
-
description: 'API keys (Stripe, Google, AWS, etc.)',
|
|
84
|
-
examples: [
|
|
85
|
-
'sk_live_abc123def456ghi789jkl',
|
|
86
|
-
'pk_test_xyz789abc123def456',
|
|
87
|
-
'AIzaSyD1234567890abcdefghijklmnopqrst',
|
|
88
|
-
'AKIAIOSFODNN7EXAMPLE',
|
|
89
|
-
],
|
|
90
|
-
priority: 7,
|
|
91
|
-
},
|
|
92
|
-
token: {
|
|
93
|
-
name: 'token',
|
|
94
|
-
regex: /\b(?:Bearer\s+)?[a-zA-Z0-9_-]{32,}\b|ghp_[a-zA-Z0-9]{36}|gho_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9_]{82}/g,
|
|
95
|
-
description: 'Authentication tokens (Bearer, GitHub, JWT-like)',
|
|
96
|
-
examples: [
|
|
97
|
-
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
|
|
98
|
-
'ghp_abc123def456ghi789jkl012mno345pqr',
|
|
99
|
-
'gho_xyz789abc123def456ghi789jkl012mno',
|
|
100
|
-
],
|
|
101
|
-
priority: 8,
|
|
102
|
-
},
|
|
103
|
-
password: {
|
|
104
|
-
name: 'password',
|
|
105
|
-
regex: /(?:password|passwd|pwd)[\s:=]+[^\s]{6,}|(?:password|passwd|pwd)["']?\s*[:=]\s*["']?[^\s"']{6,}/gi,
|
|
106
|
-
description: 'Password fields in text (password=..., pwd:...)',
|
|
107
|
-
examples: [
|
|
108
|
-
'password: MySecret123!',
|
|
109
|
-
'passwd=SecurePass456',
|
|
110
|
-
'pwd: "MyP@ssw0rd"',
|
|
111
|
-
],
|
|
112
|
-
priority: 9,
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
/**
|
|
116
|
-
* Pattern categories for grouping
|
|
117
|
-
*/
|
|
118
|
-
exports.PATTERN_CATEGORIES = {
|
|
119
|
-
financial: ['creditcard', 'ssn'],
|
|
120
|
-
contact: ['email', 'phone'],
|
|
121
|
-
identification: ['ssn', 'iin'],
|
|
122
|
-
network: ['ip', 'email'],
|
|
123
|
-
credentials: ['apikey', 'token', 'password'],
|
|
124
|
-
kazakhstan: ['iin'],
|
|
125
|
-
};
|
|
126
|
-
/**
|
|
127
|
-
* Get patterns sorted by priority
|
|
128
|
-
*/
|
|
129
|
-
function getPatternsByPriority(patterns) {
|
|
130
|
-
return [...patterns].sort((a, b) => {
|
|
131
|
-
return a.priority - b.priority;
|
|
132
|
-
});
|
|
133
|
-
}
|
|
11
|
+
// Re-export everything from @bugspotter/common
|
|
12
|
+
var common_1 = require("@bugspotter/common");
|
|
13
|
+
Object.defineProperty(exports, "DEFAULT_PATTERNS", { enumerable: true, get: function () { return common_1.DEFAULT_PATTERNS; } });
|
|
14
|
+
Object.defineProperty(exports, "PATTERN_CATEGORIES", { enumerable: true, get: function () { return common_1.PATTERN_CATEGORIES; } });
|
|
15
|
+
Object.defineProperty(exports, "PATTERN_PRESETS", { enumerable: true, get: function () { return common_1.PATTERN_PRESETS; } });
|
|
16
|
+
Object.defineProperty(exports, "getAllPatternNames", { enumerable: true, get: function () { return common_1.getAllPatternNames; } });
|
|
17
|
+
Object.defineProperty(exports, "getPatternsByPriority", { enumerable: true, get: function () { return common_1.getPatternsByPriority; } });
|
|
18
|
+
Object.defineProperty(exports, "getPatternsByPreset", { enumerable: true, get: function () { return common_1.getPatternsByPreset; } });
|
|
19
|
+
Object.defineProperty(exports, "createPatternConfig", { enumerable: true, get: function () { return common_1.createPatternConfig; } });
|
|
20
|
+
Object.defineProperty(exports, "validatePattern", { enumerable: true, get: function () { return common_1.validatePattern; } });
|
|
21
|
+
const common_2 = require("@bugspotter/common");
|
|
22
|
+
// SDK-specific extensions
|
|
134
23
|
/**
|
|
135
24
|
* Get pattern by name
|
|
136
25
|
*/
|
|
137
26
|
function getPattern(name) {
|
|
138
|
-
return
|
|
27
|
+
return common_2.DEFAULT_PATTERNS[name];
|
|
139
28
|
}
|
|
140
29
|
/**
|
|
141
30
|
* Get patterns by category
|
|
142
31
|
*/
|
|
143
32
|
function getPatternsByCategory(category) {
|
|
144
|
-
return
|
|
145
|
-
return
|
|
33
|
+
return common_2.PATTERN_CATEGORIES[category].map((name) => {
|
|
34
|
+
return common_2.DEFAULT_PATTERNS[name];
|
|
146
35
|
});
|
|
147
36
|
}
|
|
148
|
-
/**
|
|
149
|
-
* Get all pattern names
|
|
150
|
-
*/
|
|
151
|
-
function getAllPatternNames() {
|
|
152
|
-
return Object.keys(exports.DEFAULT_PATTERNS);
|
|
153
|
-
}
|
|
154
37
|
/**
|
|
155
38
|
* Custom pattern builder for advanced use cases
|
|
156
39
|
*/
|
|
@@ -163,7 +46,6 @@ class PatternBuilder {
|
|
|
163
46
|
return this;
|
|
164
47
|
}
|
|
165
48
|
regex(regex) {
|
|
166
|
-
// Ensure global flag
|
|
167
49
|
if (!regex.global) {
|
|
168
50
|
const flags = regex.flags.includes('g') ? regex.flags : regex.flags + 'g';
|
|
169
51
|
this.pattern.regex = new RegExp(regex.source, flags);
|
|
@@ -200,85 +82,6 @@ class PatternBuilder {
|
|
|
200
82
|
}
|
|
201
83
|
}
|
|
202
84
|
exports.PatternBuilder = PatternBuilder;
|
|
203
|
-
/**
|
|
204
|
-
* Pre-configured pattern sets for common use cases
|
|
205
|
-
*/
|
|
206
|
-
exports.PATTERN_PRESETS = {
|
|
207
|
-
/** All patterns enabled (PII + credentials) - default */
|
|
208
|
-
all: getAllPatternNames(),
|
|
209
|
-
/** Minimal - only most critical PII */
|
|
210
|
-
minimal: ['email', 'creditcard', 'ssn'],
|
|
211
|
-
/** Financial data only */
|
|
212
|
-
financial: exports.PATTERN_CATEGORIES.financial,
|
|
213
|
-
/** Contact information only */
|
|
214
|
-
contact: exports.PATTERN_CATEGORIES.contact,
|
|
215
|
-
/** Identification numbers only */
|
|
216
|
-
identification: exports.PATTERN_CATEGORIES.identification,
|
|
217
|
-
/** Credentials and secrets only */
|
|
218
|
-
credentials: exports.PATTERN_CATEGORIES.credentials,
|
|
219
|
-
/** Kazakhstan-specific patterns */
|
|
220
|
-
kazakhstan: ['email', 'phone', 'iin'],
|
|
221
|
-
/** GDPR compliance recommended set */
|
|
222
|
-
gdpr: ['email', 'phone', 'ip'],
|
|
223
|
-
/** PCI DSS compliance required */
|
|
224
|
-
pci: ['creditcard'],
|
|
225
|
-
/** Security-focused: PII + credentials */
|
|
226
|
-
security: [
|
|
227
|
-
'email',
|
|
228
|
-
'phone',
|
|
229
|
-
'creditcard',
|
|
230
|
-
'ssn',
|
|
231
|
-
'apikey',
|
|
232
|
-
'token',
|
|
233
|
-
'password',
|
|
234
|
-
],
|
|
235
|
-
};
|
|
236
|
-
/**
|
|
237
|
-
* Create custom pattern configuration
|
|
238
|
-
*/
|
|
239
|
-
function createPatternConfig(preset) {
|
|
240
|
-
const names = typeof preset === 'string' ? exports.PATTERN_PRESETS[preset] : preset;
|
|
241
|
-
return names.map((name) => {
|
|
242
|
-
return exports.DEFAULT_PATTERNS[name];
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Validate pattern regex
|
|
247
|
-
*/
|
|
248
|
-
function validatePattern(pattern) {
|
|
249
|
-
const errors = [];
|
|
250
|
-
if (!pattern.name) {
|
|
251
|
-
errors.push('Pattern must have a name');
|
|
252
|
-
}
|
|
253
|
-
if (!pattern.regex) {
|
|
254
|
-
errors.push('Pattern must have a regex');
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
if (!pattern.regex.global) {
|
|
258
|
-
errors.push('Pattern regex must have global flag');
|
|
259
|
-
}
|
|
260
|
-
// Test regex doesn't cause catastrophic backtracking
|
|
261
|
-
try {
|
|
262
|
-
const testString = 'a'.repeat(1000);
|
|
263
|
-
const start = Date.now();
|
|
264
|
-
testString.match(pattern.regex);
|
|
265
|
-
const duration = Date.now() - start;
|
|
266
|
-
if (duration > 100) {
|
|
267
|
-
errors.push(`Pattern regex may cause performance issues (took ${duration}ms on test)`);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
errors.push(`Pattern regex error: ${error.message}`);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (pattern.priority < 0) {
|
|
275
|
-
errors.push('Pattern priority must be non-negative');
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
valid: errors.length === 0,
|
|
279
|
-
errors,
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
85
|
/**
|
|
283
86
|
* Merge pattern configurations
|
|
284
87
|
*/
|
|
@@ -286,9 +89,8 @@ function mergePatternConfigs(...configs) {
|
|
|
286
89
|
const merged = new Map();
|
|
287
90
|
configs.forEach((config) => {
|
|
288
91
|
config.forEach((pattern) => {
|
|
289
|
-
// Later configs override earlier ones
|
|
290
92
|
merged.set(pattern.name, pattern);
|
|
291
93
|
});
|
|
292
94
|
});
|
|
293
|
-
return getPatternsByPriority([...merged.values()]);
|
|
95
|
+
return (0, common_2.getPatternsByPriority)([...merged.values()]);
|
|
294
96
|
}
|
|
@@ -1,43 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* URL Helper Utilities
|
|
3
|
-
*
|
|
3
|
+
* Re-exports from @bugspotter/common
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
* Custom error for invalid endpoint URLs
|
|
7
|
-
*/
|
|
8
|
-
export declare class InvalidEndpointError extends Error {
|
|
9
|
-
readonly endpoint: string;
|
|
10
|
-
readonly reason: string;
|
|
11
|
-
constructor(endpoint: string, reason: string);
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Strip known endpoint suffixes from path
|
|
15
|
-
* Removes /api/v1/reports path
|
|
16
|
-
*/
|
|
17
|
-
export declare function stripEndpointSuffix(path: string): string;
|
|
18
|
-
/**
|
|
19
|
-
* Extract base API URL from endpoint
|
|
20
|
-
* Returns scheme + host + base path (without /api/v1/reports suffix)
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* getApiBaseUrl('https://api.example.com/api/v1/reports')
|
|
24
|
-
* // Returns: 'https://api.example.com'
|
|
25
|
-
*
|
|
26
|
-
* @throws InvalidEndpointError if endpoint is not a valid absolute URL
|
|
27
|
-
*/
|
|
28
|
-
export declare function getApiBaseUrl(endpoint: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* specific error for insecure endpoints
|
|
31
|
-
*/
|
|
32
|
-
export declare class InsecureEndpointError extends Error {
|
|
33
|
-
readonly endpoint: string;
|
|
34
|
-
constructor(endpoint: string);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Checks if the endpoint uses the secure HTTPS protocol.
|
|
38
|
-
* Uses the URL API for robust parsing.
|
|
39
|
-
*
|
|
40
|
-
* @param endpoint The endpoint URL to check
|
|
41
|
-
* @returns True if the endpoint uses HTTPS
|
|
42
|
-
*/
|
|
43
|
-
export declare function isSecureEndpoint(endpoint: string): boolean;
|
|
5
|
+
export { InvalidEndpointError, InsecureEndpointError, stripEndpointSuffix, getApiBaseUrl, isSecureEndpoint, } from '@bugspotter/common';
|
|
@@ -1,100 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* URL Helper Utilities
|
|
4
|
-
* Extract base API URL from endpoint configuration
|
|
5
|
-
*/
|
|
6
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.InsecureEndpointError = exports.InvalidEndpointError = void 0;
|
|
8
|
-
exports.stripEndpointSuffix = stripEndpointSuffix;
|
|
9
|
-
exports.getApiBaseUrl = getApiBaseUrl;
|
|
10
|
-
exports.isSecureEndpoint = isSecureEndpoint;
|
|
11
|
-
const logger_1 = require("./logger");
|
|
12
|
-
const logger = (0, logger_1.getLogger)();
|
|
13
|
-
/**
|
|
14
|
-
* Custom error for invalid endpoint URLs
|
|
15
|
-
*/
|
|
16
|
-
class InvalidEndpointError extends Error {
|
|
17
|
-
constructor(endpoint, reason) {
|
|
18
|
-
super(`Invalid endpoint URL: ${endpoint}. ${reason}`);
|
|
19
|
-
this.endpoint = endpoint;
|
|
20
|
-
this.reason = reason;
|
|
21
|
-
this.name = 'InvalidEndpointError';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.InvalidEndpointError = InvalidEndpointError;
|
|
25
|
-
/**
|
|
26
|
-
* Strip known endpoint suffixes from path
|
|
27
|
-
* Removes /api/v1/reports path
|
|
28
|
-
*/
|
|
29
|
-
function stripEndpointSuffix(path) {
|
|
30
|
-
// Use lastIndexOf to handle paths like '/prefix/api/v1/reports'
|
|
31
|
-
const reportsIndex = path.lastIndexOf('/api/v1/reports');
|
|
32
|
-
if (reportsIndex !== -1) {
|
|
33
|
-
return path.substring(0, reportsIndex);
|
|
34
|
-
}
|
|
35
|
-
// Remove trailing slash
|
|
36
|
-
return path.replace(/\/$/, '') || '';
|
|
37
|
-
}
|
|
3
|
+
exports.isSecureEndpoint = exports.getApiBaseUrl = exports.stripEndpointSuffix = exports.InsecureEndpointError = exports.InvalidEndpointError = void 0;
|
|
38
4
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
function getApiBaseUrl(endpoint) {
|
|
49
|
-
if (!endpoint) {
|
|
50
|
-
throw new InvalidEndpointError('', 'No endpoint configured');
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
const url = new URL(endpoint);
|
|
54
|
-
const basePath = stripEndpointSuffix(url.pathname);
|
|
55
|
-
return url.origin + basePath;
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
59
|
-
logger.error('Invalid endpoint URL - must be a valid absolute URL', {
|
|
60
|
-
endpoint,
|
|
61
|
-
error: errorMessage,
|
|
62
|
-
});
|
|
63
|
-
throw new InvalidEndpointError(endpoint, 'Must be a valid absolute URL (e.g., https://api.example.com/api/v1/reports)');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* specific error for insecure endpoints
|
|
68
|
-
*/
|
|
69
|
-
class InsecureEndpointError extends Error {
|
|
70
|
-
constructor(endpoint) {
|
|
71
|
-
super(`Secure HTTPS connection required. Attempted to connect to insecure endpoint: "${endpoint}"`);
|
|
72
|
-
this.endpoint = endpoint;
|
|
73
|
-
this.name = 'InsecureEndpointError';
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
exports.InsecureEndpointError = InsecureEndpointError;
|
|
77
|
-
/**
|
|
78
|
-
* Checks if the endpoint uses the secure HTTPS protocol.
|
|
79
|
-
* Uses the URL API for robust parsing.
|
|
80
|
-
*
|
|
81
|
-
* @param endpoint The endpoint URL to check
|
|
82
|
-
* @returns True if the endpoint uses HTTPS
|
|
83
|
-
*/
|
|
84
|
-
function isSecureEndpoint(endpoint) {
|
|
85
|
-
if (!endpoint)
|
|
86
|
-
return false;
|
|
87
|
-
try {
|
|
88
|
-
const url = new URL(endpoint.trim());
|
|
89
|
-
// STRICT SECURITY:
|
|
90
|
-
// 1. Production must use HTTPS
|
|
91
|
-
// 2. Development allowed on localhost/127.0.0.1 via HTTP
|
|
92
|
-
return (url.protocol === 'https:' ||
|
|
93
|
-
(url.protocol === 'http:' &&
|
|
94
|
-
(url.hostname === 'localhost' || url.hostname === '127.0.0.1')));
|
|
95
|
-
}
|
|
96
|
-
catch (_a) {
|
|
97
|
-
// If it's not a valid URL, it's definitely not a secure endpoint
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
5
|
+
* URL Helper Utilities
|
|
6
|
+
* Re-exports from @bugspotter/common
|
|
7
|
+
*/
|
|
8
|
+
var common_1 = require("@bugspotter/common");
|
|
9
|
+
Object.defineProperty(exports, "InvalidEndpointError", { enumerable: true, get: function () { return common_1.InvalidEndpointError; } });
|
|
10
|
+
Object.defineProperty(exports, "InsecureEndpointError", { enumerable: true, get: function () { return common_1.InsecureEndpointError; } });
|
|
11
|
+
Object.defineProperty(exports, "stripEndpointSuffix", { enumerable: true, get: function () { return common_1.stripEndpointSuffix; } });
|
|
12
|
+
Object.defineProperty(exports, "getApiBaseUrl", { enumerable: true, get: function () { return common_1.getApiBaseUrl; } });
|
|
13
|
+
Object.defineProperty(exports, "isSecureEndpoint", { enumerable: true, get: function () { return common_1.isSecureEndpoint; } });
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bugspotter/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Professional bug reporting SDK with screenshots, session replay, and automatic error capture for web applications",
|
|
5
5
|
"packageManager": "pnpm@9.15.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
]
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
+
"@bugspotter/common": "^1.0.1",
|
|
82
83
|
"@rrweb/types": "2.0.0-alpha.18",
|
|
83
84
|
"html-to-image": "^1.11.13",
|
|
84
85
|
"pako": "^2.1.0",
|
package/release_notes.md
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
## Release 1.
|
|
1
|
+
## Release 1.1.0
|
|
2
2
|
|
|
3
3
|
### Changes
|
|
4
4
|
|
|
5
|
-
## [1.0.0] - 2026-01-17
|
|
6
|
-
|
|
7
|
-
### Changed
|
|
8
|
-
|
|
9
|
-
- **Stable Release**: First production-ready 1.0.0 release
|
|
10
|
-
- Improved code quality and readability across core modules
|
|
11
|
-
- Enhanced test infrastructure with better Node.js and browser compatibility
|
|
12
|
-
- Optimized transport layer and URL validation logic
|
|
13
|
-
|
|
14
|
-
### Fixed
|
|
15
|
-
|
|
16
|
-
- E2E test compatibility issues in Playwright test suite
|
|
17
|
-
- Integration test Node.js Buffer API compatibility
|
|
18
|
-
- ESLint configuration for test environment globals
|
|
19
|
-
|
package/rollup.config.js
CHANGED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A generic circular buffer implementation for storing a fixed number of items.
|
|
3
|
-
* When the buffer is full, new items overwrite the oldest items.
|
|
4
|
-
*
|
|
5
|
-
* @template T The type of items stored in the buffer
|
|
6
|
-
*/
|
|
7
|
-
export declare class CircularBuffer<T> {
|
|
8
|
-
private maxSize;
|
|
9
|
-
private items;
|
|
10
|
-
private index;
|
|
11
|
-
private count;
|
|
12
|
-
constructor(maxSize: number);
|
|
13
|
-
/**
|
|
14
|
-
* Add an item to the buffer. If the buffer is full, the oldest item is overwritten.
|
|
15
|
-
*/
|
|
16
|
-
add(item: T): void;
|
|
17
|
-
/**
|
|
18
|
-
* Get all items in chronological order (oldest to newest).
|
|
19
|
-
* Returns a copy of the internal array.
|
|
20
|
-
*/
|
|
21
|
-
getAll(): T[];
|
|
22
|
-
/**
|
|
23
|
-
* Clear all items from the buffer.
|
|
24
|
-
*/
|
|
25
|
-
clear(): void;
|
|
26
|
-
/**
|
|
27
|
-
* Get the current number of items in the buffer.
|
|
28
|
-
*/
|
|
29
|
-
get size(): number;
|
|
30
|
-
/**
|
|
31
|
-
* Get the maximum capacity of the buffer.
|
|
32
|
-
*/
|
|
33
|
-
get capacity(): number;
|
|
34
|
-
/**
|
|
35
|
-
* Check if the buffer is empty.
|
|
36
|
-
*/
|
|
37
|
-
get isEmpty(): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Check if the buffer is full.
|
|
40
|
-
*/
|
|
41
|
-
get isFull(): boolean;
|
|
42
|
-
}
|