@socketsecurity/sdk 1.10.1 → 1.11.1

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.
@@ -0,0 +1,453 @@
1
+ /**
2
+ * @fileoverview Testing utilities for Socket SDK.
3
+ * Provides mock factories, response builders, and test helpers for easier SDK testing.
4
+ */
5
+ import type { SocketSdkErrorResult, SocketSdkGenericResult, SocketSdkOperations, SocketSdkSuccessResult } from './types';
6
+ /**
7
+ * Create a successful SDK response.
8
+ *
9
+ * @template T - The data type
10
+ * @param data - The response data
11
+ * @param status - HTTP status code (default: 200)
12
+ * @returns A successful SDK result
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const response = mockSuccessResponse({ id: '123', name: 'test' })
17
+ * expect(response.success).toBe(true)
18
+ * ```
19
+ */
20
+ export declare function mockSuccessResponse<T>(data: T, status?: number): SocketSdkGenericResult<T>;
21
+ /**
22
+ * Create an error SDK response.
23
+ *
24
+ * @template T - The data type (unused in error responses)
25
+ * @param error - The error message
26
+ * @param status - HTTP status code (default: 500)
27
+ * @param cause - Optional error cause
28
+ * @returns An error SDK result
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const response = mockErrorResponse('Not found', 404)
33
+ * expect(response.success).toBe(false)
34
+ * ```
35
+ */
36
+ export declare function mockErrorResponse<T>(error: string, status?: number, cause?: string): SocketSdkGenericResult<T>;
37
+ /**
38
+ * Create a mock Socket API error response body.
39
+ *
40
+ * @param message - Error message
41
+ * @param details - Optional error details
42
+ * @returns Socket API error response structure
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * nock('https://api.socket.dev')
47
+ * .get('/v0/repo/org/repo')
48
+ * .reply(404, mockApiErrorBody('Repository not found'))
49
+ * ```
50
+ */
51
+ export declare function mockApiErrorBody(message: string, details?: Record<string, unknown>): {
52
+ error: {
53
+ message: string;
54
+ details?: Record<string, unknown>;
55
+ };
56
+ };
57
+ /**
58
+ * Common fixture data for organization responses.
59
+ */
60
+ export declare const organizationFixtures: {
61
+ /**
62
+ * Basic organization with minimal data.
63
+ */
64
+ readonly basic: {
65
+ readonly id: "org_123";
66
+ readonly name: "test-org";
67
+ readonly plan: "free";
68
+ };
69
+ /**
70
+ * Organization with full details.
71
+ */
72
+ readonly full: {
73
+ readonly id: "org_123";
74
+ readonly name: "test-org";
75
+ readonly plan: "enterprise";
76
+ readonly created_at: "2024-01-01T00:00:00Z";
77
+ readonly updated_at: "2024-01-02T00:00:00Z";
78
+ };
79
+ };
80
+ /**
81
+ * Common fixture data for repository responses.
82
+ */
83
+ export declare const repositoryFixtures: {
84
+ /**
85
+ * Basic repository with minimal data.
86
+ */
87
+ readonly basic: {
88
+ readonly id: "repo_123";
89
+ readonly name: "test-repo";
90
+ readonly archived: false;
91
+ readonly default_branch: "main";
92
+ };
93
+ /**
94
+ * Archived repository.
95
+ */
96
+ readonly archived: {
97
+ readonly id: "repo_456";
98
+ readonly name: "old-repo";
99
+ readonly archived: true;
100
+ readonly default_branch: "master";
101
+ };
102
+ /**
103
+ * Repository with full details.
104
+ */
105
+ readonly full: {
106
+ readonly id: "repo_123";
107
+ readonly name: "test-repo";
108
+ readonly archived: false;
109
+ readonly default_branch: "main";
110
+ readonly homepage: "https://example.com";
111
+ readonly visibility: "public";
112
+ readonly created_at: "2024-01-01T00:00:00Z";
113
+ readonly updated_at: "2024-01-02T00:00:00Z";
114
+ };
115
+ };
116
+ /**
117
+ * Common fixture data for scan responses.
118
+ */
119
+ export declare const scanFixtures: {
120
+ /**
121
+ * Pending scan.
122
+ */
123
+ readonly pending: {
124
+ readonly id: "scan_pending";
125
+ readonly status: "pending";
126
+ readonly created_at: "2024-01-01T00:00:00Z";
127
+ };
128
+ /**
129
+ * Completed scan with no issues.
130
+ */
131
+ readonly completed: {
132
+ readonly id: "scan_completed";
133
+ readonly status: "completed";
134
+ readonly created_at: "2024-01-01T00:00:00Z";
135
+ readonly completed_at: "2024-01-01T00:01:00Z";
136
+ readonly issues_found: 0;
137
+ };
138
+ /**
139
+ * Completed scan with issues.
140
+ */
141
+ readonly withIssues: {
142
+ readonly id: "scan_with_issues";
143
+ readonly status: "completed";
144
+ readonly created_at: "2024-01-01T00:00:00Z";
145
+ readonly completed_at: "2024-01-01T00:01:00Z";
146
+ readonly issues_found: 3;
147
+ };
148
+ /**
149
+ * Failed scan.
150
+ */
151
+ readonly failed: {
152
+ readonly id: "scan_failed";
153
+ readonly status: "failed";
154
+ readonly created_at: "2024-01-01T00:00:00Z";
155
+ readonly error: "Scan timeout";
156
+ };
157
+ };
158
+ /**
159
+ * Common fixture data for package/artifact responses.
160
+ */
161
+ export declare const packageFixtures: {
162
+ /**
163
+ * Safe package with high score.
164
+ */
165
+ readonly safe: {
166
+ readonly id: "pkg_safe";
167
+ readonly name: "safe-package";
168
+ readonly version: "1.0.0";
169
+ readonly score: 95;
170
+ };
171
+ /**
172
+ * Package with vulnerabilities.
173
+ */
174
+ readonly vulnerable: {
175
+ readonly id: "pkg_vuln";
176
+ readonly name: "vulnerable-package";
177
+ readonly version: "2.0.0";
178
+ readonly score: 45;
179
+ readonly issues: readonly ["vulnerability"];
180
+ };
181
+ /**
182
+ * Package with malware alert.
183
+ */
184
+ readonly malware: {
185
+ readonly id: "pkg_malware";
186
+ readonly name: "malware-package";
187
+ readonly version: "3.0.0";
188
+ readonly score: 0;
189
+ readonly issues: readonly ["malware"];
190
+ };
191
+ };
192
+ /**
193
+ * Common fixture data for issue/alert responses.
194
+ */
195
+ export declare const issueFixtures: {
196
+ /**
197
+ * Vulnerability issue.
198
+ */
199
+ readonly vulnerability: {
200
+ readonly type: "vulnerability";
201
+ readonly severity: "high";
202
+ readonly key: "CVE-2024-1234";
203
+ readonly description: "SQL Injection vulnerability";
204
+ };
205
+ /**
206
+ * Malware issue.
207
+ */
208
+ readonly malware: {
209
+ readonly type: "malware";
210
+ readonly severity: "critical";
211
+ readonly key: "malware-detected";
212
+ readonly description: "Malicious code detected";
213
+ };
214
+ /**
215
+ * License issue.
216
+ */
217
+ readonly license: {
218
+ readonly type: "license";
219
+ readonly severity: "medium";
220
+ readonly key: "license-incompatible";
221
+ readonly description: "License incompatible with project";
222
+ };
223
+ };
224
+ /**
225
+ * All fixture categories in one object.
226
+ */
227
+ export declare const fixtures: {
228
+ readonly issues: {
229
+ /**
230
+ * Vulnerability issue.
231
+ */
232
+ readonly vulnerability: {
233
+ readonly type: "vulnerability";
234
+ readonly severity: "high";
235
+ readonly key: "CVE-2024-1234";
236
+ readonly description: "SQL Injection vulnerability";
237
+ };
238
+ /**
239
+ * Malware issue.
240
+ */
241
+ readonly malware: {
242
+ readonly type: "malware";
243
+ readonly severity: "critical";
244
+ readonly key: "malware-detected";
245
+ readonly description: "Malicious code detected";
246
+ };
247
+ /**
248
+ * License issue.
249
+ */
250
+ readonly license: {
251
+ readonly type: "license";
252
+ readonly severity: "medium";
253
+ readonly key: "license-incompatible";
254
+ readonly description: "License incompatible with project";
255
+ };
256
+ };
257
+ readonly organizations: {
258
+ /**
259
+ * Basic organization with minimal data.
260
+ */
261
+ readonly basic: {
262
+ readonly id: "org_123";
263
+ readonly name: "test-org";
264
+ readonly plan: "free";
265
+ };
266
+ /**
267
+ * Organization with full details.
268
+ */
269
+ readonly full: {
270
+ readonly id: "org_123";
271
+ readonly name: "test-org";
272
+ readonly plan: "enterprise";
273
+ readonly created_at: "2024-01-01T00:00:00Z";
274
+ readonly updated_at: "2024-01-02T00:00:00Z";
275
+ };
276
+ };
277
+ readonly packages: {
278
+ /**
279
+ * Safe package with high score.
280
+ */
281
+ readonly safe: {
282
+ readonly id: "pkg_safe";
283
+ readonly name: "safe-package";
284
+ readonly version: "1.0.0";
285
+ readonly score: 95;
286
+ };
287
+ /**
288
+ * Package with vulnerabilities.
289
+ */
290
+ readonly vulnerable: {
291
+ readonly id: "pkg_vuln";
292
+ readonly name: "vulnerable-package";
293
+ readonly version: "2.0.0";
294
+ readonly score: 45;
295
+ readonly issues: readonly ["vulnerability"];
296
+ };
297
+ /**
298
+ * Package with malware alert.
299
+ */
300
+ readonly malware: {
301
+ readonly id: "pkg_malware";
302
+ readonly name: "malware-package";
303
+ readonly version: "3.0.0";
304
+ readonly score: 0;
305
+ readonly issues: readonly ["malware"];
306
+ };
307
+ };
308
+ readonly repositories: {
309
+ /**
310
+ * Basic repository with minimal data.
311
+ */
312
+ readonly basic: {
313
+ readonly id: "repo_123";
314
+ readonly name: "test-repo";
315
+ readonly archived: false;
316
+ readonly default_branch: "main";
317
+ };
318
+ /**
319
+ * Archived repository.
320
+ */
321
+ readonly archived: {
322
+ readonly id: "repo_456";
323
+ readonly name: "old-repo";
324
+ readonly archived: true;
325
+ readonly default_branch: "master";
326
+ };
327
+ /**
328
+ * Repository with full details.
329
+ */
330
+ readonly full: {
331
+ readonly id: "repo_123";
332
+ readonly name: "test-repo";
333
+ readonly archived: false;
334
+ readonly default_branch: "main";
335
+ readonly homepage: "https://example.com";
336
+ readonly visibility: "public";
337
+ readonly created_at: "2024-01-01T00:00:00Z";
338
+ readonly updated_at: "2024-01-02T00:00:00Z";
339
+ };
340
+ };
341
+ readonly scans: {
342
+ /**
343
+ * Pending scan.
344
+ */
345
+ readonly pending: {
346
+ readonly id: "scan_pending";
347
+ readonly status: "pending";
348
+ readonly created_at: "2024-01-01T00:00:00Z";
349
+ };
350
+ /**
351
+ * Completed scan with no issues.
352
+ */
353
+ readonly completed: {
354
+ readonly id: "scan_completed";
355
+ readonly status: "completed";
356
+ readonly created_at: "2024-01-01T00:00:00Z";
357
+ readonly completed_at: "2024-01-01T00:01:00Z";
358
+ readonly issues_found: 0;
359
+ };
360
+ /**
361
+ * Completed scan with issues.
362
+ */
363
+ readonly withIssues: {
364
+ readonly id: "scan_with_issues";
365
+ readonly status: "completed";
366
+ readonly created_at: "2024-01-01T00:00:00Z";
367
+ readonly completed_at: "2024-01-01T00:01:00Z";
368
+ readonly issues_found: 3;
369
+ };
370
+ /**
371
+ * Failed scan.
372
+ */
373
+ readonly failed: {
374
+ readonly id: "scan_failed";
375
+ readonly status: "failed";
376
+ readonly created_at: "2024-01-01T00:00:00Z";
377
+ readonly error: "Scan timeout";
378
+ };
379
+ };
380
+ };
381
+ /**
382
+ * Mock SDK method result with proper typing.
383
+ *
384
+ * @template T - The operation type
385
+ * @param success - Whether the operation succeeded
386
+ * @param data - Success data or error details
387
+ * @returns Properly typed SDK result
388
+ *
389
+ * @example
390
+ * ```ts
391
+ * const mockGet = vi.fn().mockResolvedValue(
392
+ * mockSdkResult<'getRepo'>(true, { id: '123', name: 'repo' })
393
+ * )
394
+ * ```
395
+ */
396
+ export declare function mockSdkResult<T extends SocketSdkOperations>(success: true, data: SocketSdkSuccessResult<T>['data'], status?: number): SocketSdkSuccessResult<T>;
397
+ export declare function mockSdkResult<T extends SocketSdkOperations>(success: false, error: string, status?: number, cause?: string): SocketSdkErrorResult<T>;
398
+ /**
399
+ * Create a mock SDK error with proper structure.
400
+ *
401
+ * @param type - Error type ('NOT_FOUND', 'UNAUTHORIZED', etc.)
402
+ * @param options - Error options
403
+ * @returns Error response matching SDK structure
404
+ *
405
+ * @example
406
+ * ```ts
407
+ * const mockMethod = vi.fn().mockRejectedValue(
408
+ * mockSdkError('NOT_FOUND', { status: 404, message: 'Repository not found' })
409
+ * )
410
+ * ```
411
+ */
412
+ export declare function mockSdkError(type: 'NOT_FOUND' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'SERVER_ERROR' | 'TIMEOUT', options?: {
413
+ cause?: string;
414
+ message?: string;
415
+ status?: number;
416
+ }): Error & {
417
+ status: number;
418
+ cause?: string;
419
+ };
420
+ /**
421
+ * Type guard to check if SDK result is successful.
422
+ *
423
+ * @param result - SDK result to check
424
+ * @returns True if result is successful
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const result = await sdk.getRepo('org', 'repo')
429
+ * if (isSuccessResult(result)) {
430
+ * console.log(result.data.name) // Type-safe access
431
+ * }
432
+ * ```
433
+ */
434
+ export declare function isSuccessResult<T>(result: SocketSdkGenericResult<T>): result is Extract<SocketSdkGenericResult<T>, {
435
+ success: true;
436
+ }>;
437
+ /**
438
+ * Type guard to check if SDK result is an error.
439
+ *
440
+ * @param result - SDK result to check
441
+ * @returns True if result is an error
442
+ *
443
+ * @example
444
+ * ```ts
445
+ * const result = await sdk.getRepo('org', 'repo')
446
+ * if (isErrorResult(result)) {
447
+ * console.error(result.error) // Type-safe access
448
+ * }
449
+ * ```
450
+ */
451
+ export declare function isErrorResult<T>(result: SocketSdkGenericResult<T>): result is Extract<SocketSdkGenericResult<T>, {
452
+ success: false;
453
+ }>;