@socketsecurity/sdk 3.4.1 → 4.0.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/index.js CHANGED
@@ -30,48 +30,31 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- DEFAULT_USER_AGENT: () => DEFAULT_USER_AGENT,
34
33
  ResponseError: () => ResponseError,
35
34
  SocketSdk: () => SocketSdk,
36
35
  calculateTotalQuotaCost: () => calculateTotalQuotaCost,
37
- calculateWordSetSimilarity: () => calculateWordSetSimilarity,
38
- createDeleteRequest: () => createDeleteRequest,
39
- createGetRequest: () => createGetRequest,
40
- createRequestBodyForFilepaths: () => createRequestBodyForFilepaths,
41
- createRequestBodyForJson: () => createRequestBodyForJson,
42
- createRequestWithJson: () => createRequestWithJson,
43
- createUploadRequest: () => createUploadRequest,
44
36
  createUserAgentFromPkgJson: () => createUserAgentFromPkgJson,
45
- filterRedundantCause: () => filterRedundantCause,
46
37
  getAllMethodRequirements: () => getAllMethodRequirements,
47
- getErrorResponseBody: () => getErrorResponseBody,
48
- getHttpModule: () => getHttpModule,
49
38
  getMethodRequirements: () => getMethodRequirements,
50
39
  getMethodsByPermissions: () => getMethodsByPermissions,
51
40
  getMethodsByQuotaCost: () => getMethodsByQuotaCost,
52
41
  getQuotaCost: () => getQuotaCost,
53
42
  getQuotaUsageSummary: () => getQuotaUsageSummary,
54
43
  getRequiredPermissions: () => getRequiredPermissions,
55
- getResponse: () => getResponse,
56
- getResponseJson: () => getResponseJson,
57
- hasQuotaForMethods: () => hasQuotaForMethods,
58
- httpAgentNames: () => httpAgentNames,
59
- isResponseOk: () => isResponseOk,
60
- normalizeBaseUrl: () => normalizeBaseUrl,
61
- promiseWithResolvers: () => promiseWithResolvers,
62
- publicPolicy: () => publicPolicy,
63
- queryToSearchParams: () => queryToSearchParams,
64
- reshapeArtifactForPublicPolicy: () => reshapeArtifactForPublicPolicy,
65
- resolveAbsPaths: () => resolveAbsPaths,
66
- resolveBasePath: () => resolveBasePath,
67
- shouldOmitReason: () => shouldOmitReason
44
+ hasQuotaForMethods: () => hasQuotaForMethods
68
45
  });
69
46
  module.exports = __toCommonJS(index_exports);
70
47
 
48
+ // src/http-client.ts
49
+ var import_debug = require("@socketsecurity/lib/debug");
50
+ var import_http_request = require("@socketsecurity/lib/http-request");
51
+ var import_parse = require("@socketsecurity/lib/json/parse");
52
+ var import_performance = require("@socketsecurity/lib/performance");
53
+
71
54
  // package.json
72
55
  var package_default = {
73
56
  name: "@socketsecurity/sdk",
74
- version: "3.4.1",
57
+ version: "4.0.0",
75
58
  description: "SDK for the Socket API client",
76
59
  homepage: "https://github.com/SocketDev/socket-sdk-js",
77
60
  license: "MIT",
@@ -119,7 +102,7 @@ var package_default = {
119
102
  clean: "node scripts/clean.mjs",
120
103
  cover: "node scripts/cover.mjs",
121
104
  fix: "node scripts/lint.mjs --fix",
122
- format: "oxfmt .",
105
+ format: "oxfmt --write .",
123
106
  "format:check": "oxfmt --check .",
124
107
  "generate-sdk": "node scripts/generate-sdk.mjs",
125
108
  lint: "node scripts/lint.mjs",
@@ -130,16 +113,17 @@ var package_default = {
130
113
  publish: "node scripts/publish.mjs",
131
114
  "publish:ci": "node scripts/publish.mjs --tag ${DIST_TAG:-latest}",
132
115
  claude: "node scripts/claude.mjs",
116
+ security: "agentshield scan && { command -v zizmor >/dev/null && zizmor .github/ || echo 'zizmor not installed \u2014 run pnpm run setup to install'; }",
133
117
  test: "node scripts/test.mjs",
134
118
  type: "tsgo --noEmit -p .config/tsconfig.check.json",
135
119
  update: "node scripts/update.mjs"
136
120
  },
137
121
  dependencies: {
138
- "@socketregistry/packageurl-js": "1.3.5",
139
- "@socketsecurity/lib": "5.8.1",
122
+ "@socketsecurity/lib": "5.15.0",
140
123
  "form-data": "4.0.5"
141
124
  },
142
125
  devDependencies: {
126
+ "@anthropic-ai/claude-code": "2.1.92",
143
127
  "@babel/generator": "7.28.5",
144
128
  "@babel/parser": "7.26.3",
145
129
  "@babel/traverse": "7.26.4",
@@ -154,9 +138,9 @@ var package_default = {
154
138
  acorn: "8.15.0",
155
139
  del: "8.0.1",
156
140
  "dev-null-cli": "2.0.0",
141
+ "ecc-agentshield": "1.4.0",
157
142
  esbuild: "0.25.11",
158
143
  "fast-glob": "3.3.3",
159
- "http2-wrapper": "2.2.1",
160
144
  husky: "9.1.7",
161
145
  "magic-string": "0.30.14",
162
146
  nock: "14.0.10",
@@ -180,17 +164,18 @@ var package_default = {
180
164
  strict: true
181
165
  },
182
166
  engines: {
183
- node: ">=18",
184
- pnpm: ">=10.25.0"
167
+ node: ">=18.20.8",
168
+ pnpm: ">=10.33.0"
185
169
  },
186
- packageManager: "pnpm@10.32.1",
170
+ packageManager: "pnpm@10.33.0",
187
171
  pnpm: {
188
172
  ignoredBuiltDependencies: [
189
173
  "esbuild",
190
174
  "unrs-resolver"
191
175
  ],
192
176
  overrides: {
193
- vite: "7.1.12"
177
+ defu: ">=6.1.6",
178
+ vite: "7.3.2"
194
179
  }
195
180
  }
196
181
  };
@@ -216,6 +201,8 @@ var MIN_HTTP_TIMEOUT = 5e3;
216
201
  var MAX_RESPONSE_SIZE = 10 * 1024 * 1024;
217
202
  var MAX_STREAM_SIZE = 100 * 1024 * 1024;
218
203
  var SOCKET_PUBLIC_BLOB_STORE_URL = "https://socketusercontent.com";
204
+ var MAX_FIREWALL_COMPONENTS = 8;
205
+ var SOCKET_FIREWALL_API_URL = "https://firewall-api.socket.dev/purl";
219
206
  var httpAgentNames = /* @__PURE__ */ new Set(["http", "https", "http2"]);
220
207
  var publicPolicy = /* @__PURE__ */ new Map([
221
208
  // error (1):
@@ -325,110 +312,6 @@ var publicPolicy = /* @__PURE__ */ new Map([
325
312
  ["zeroWidth", "ignore"]
326
313
  ]);
327
314
 
328
- // src/utils.ts
329
- var import_node_path = __toESM(require("node:path"));
330
- var import_memoization = require("@socketsecurity/lib/memoization");
331
- var import_normalize = require("@socketsecurity/lib/paths/normalize");
332
- function normalizeToWordSet(s) {
333
- const words = s.toLowerCase().match(/\w+/g);
334
- return new Set(words ?? []);
335
- }
336
- function calculateWordSetSimilarity(str1, str2) {
337
- const set1 = normalizeToWordSet(str1);
338
- const set2 = normalizeToWordSet(str2);
339
- if (set1.size === 0 && set2.size === 0) {
340
- return 1;
341
- }
342
- if (set1.size === 0 || set2.size === 0) {
343
- return 0;
344
- }
345
- let intersectionSize = 0;
346
- for (const word of set1) {
347
- if (set2.has(word)) {
348
- intersectionSize++;
349
- }
350
- }
351
- const unionSize = set1.size + set2.size - intersectionSize;
352
- return intersectionSize / unionSize;
353
- }
354
- function filterRedundantCause(errorMessage, errorCause, threshold = 0.6) {
355
- if (!errorCause || !errorCause.trim()) {
356
- return void 0;
357
- }
358
- const messageParts = errorMessage.split(":").map((part) => part.trim());
359
- for (const part of messageParts) {
360
- if (part && shouldOmitReason(part, errorCause, threshold)) {
361
- return void 0;
362
- }
363
- }
364
- return errorCause;
365
- }
366
- var normalizeBaseUrl = (0, import_memoization.memoize)(
367
- (baseUrl) => {
368
- return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
369
- },
370
- { name: "normalizeBaseUrl" }
371
- );
372
- function promiseWithResolvers() {
373
- if (Promise.withResolvers) {
374
- return Promise.withResolvers();
375
- }
376
- const obj = {};
377
- obj.promise = new Promise((resolver, reject) => {
378
- obj.resolve = resolver;
379
- obj.reject = reject;
380
- });
381
- return obj;
382
- }
383
- function queryToSearchParams(init) {
384
- const params = new URLSearchParams(
385
- init
386
- );
387
- const normalized = { __proto__: null };
388
- const entries = params.entries();
389
- for (const entry of entries) {
390
- let key = entry[0];
391
- const value = entry[1];
392
- if (key === "defaultBranch") {
393
- key = "default_branch";
394
- } else if (key === "perPage") {
395
- key = "per_page";
396
- }
397
- if (value) {
398
- normalized[key] = value;
399
- }
400
- }
401
- return new URLSearchParams(normalized);
402
- }
403
- function resolveAbsPaths(filepaths, pathsRelativeTo) {
404
- const basePath = resolveBasePath(pathsRelativeTo);
405
- return filepaths.map((p) => (0, import_normalize.normalizePath)(import_node_path.default.resolve(basePath, p)));
406
- }
407
- function resolveBasePath(pathsRelativeTo = ".") {
408
- return (0, import_normalize.normalizePath)(import_node_path.default.resolve(process.cwd(), pathsRelativeTo));
409
- }
410
- function shouldOmitReason(errorMessage, reason, threshold = 0.6) {
411
- if (!reason || !reason.trim()) {
412
- return true;
413
- }
414
- const similarity = calculateWordSetSimilarity(errorMessage, reason);
415
- return similarity >= threshold;
416
- }
417
-
418
- // src/file-upload.ts
419
- var import_node_fs = require("node:fs");
420
- var import_node_path2 = __toESM(require("node:path"));
421
- var import_node_stream = require("node:stream");
422
- var import_form_data = __toESM(require("form-data"));
423
- var import_normalize2 = require("@socketsecurity/lib/paths/normalize");
424
-
425
- // src/http-client.ts
426
- var import_node_http = __toESM(require("node:http"));
427
- var import_node_https = __toESM(require("node:https"));
428
- var import_debug = require("@socketsecurity/lib/debug");
429
- var import_parse = require("@socketsecurity/lib/json/parse");
430
- var import_performance = require("@socketsecurity/lib/performance");
431
-
432
315
  // src/utils/header-sanitization.ts
433
316
  var SENSITIVE_HEADERS = [
434
317
  "authorization",
@@ -461,13 +344,9 @@ function sanitizeHeaders(headers) {
461
344
  var ResponseError = class _ResponseError extends Error {
462
345
  response;
463
346
  url;
464
- /**
465
- * Create a new ResponseError from an HTTP response.
466
- * Automatically formats error message with status code and message.
467
- */
468
347
  constructor(response, message = "", url) {
469
- const statusCode = response.statusCode ?? "unknown";
470
- const statusMessage = response.statusMessage ?? "No status message";
348
+ const statusCode = response.status ?? "unknown";
349
+ const statusMessage = response.statusText || "No status message";
471
350
  super(
472
351
  /* c8 ignore next - fallback empty message if not provided */
473
352
  `Socket API ${message || "Request failed"} (${statusCode}): ${statusMessage}`
@@ -487,34 +366,41 @@ async function createDeleteRequest(baseUrl, urlPath, options) {
487
366
  ...options
488
367
  };
489
368
  const opts = { __proto__: null, ...rawOpts };
490
- hooks?.onRequest?.({
491
- method,
492
- url,
493
- headers: sanitizeHeaders(opts.headers),
494
- timeout: opts.timeout
495
- });
496
- try {
497
- const req = getHttpModule(baseUrl).request(url, {
498
- method,
499
- ...opts
500
- }).end();
501
- const response = await getResponse(req);
502
- hooks?.onResponse?.({
369
+ if (hooks?.onRequest) {
370
+ hooks.onRequest({
503
371
  method,
504
372
  url,
505
- duration: Date.now() - startTime,
506
- status: response.statusCode,
507
- statusText: response.statusMessage,
508
- headers: sanitizeHeaders(response.headers)
373
+ headers: sanitizeHeaders(opts.headers),
374
+ timeout: opts.timeout
509
375
  });
510
- return response;
511
- } catch (error) {
512
- hooks?.onResponse?.({
376
+ }
377
+ try {
378
+ const response = await (0, import_http_request.httpRequest)(url, {
513
379
  method,
514
- url,
515
- duration: Date.now() - startTime,
516
- error
380
+ headers: opts.headers,
381
+ timeout: opts.timeout,
382
+ maxResponseSize: MAX_RESPONSE_SIZE
517
383
  });
384
+ if (hooks?.onResponse) {
385
+ hooks.onResponse({
386
+ method,
387
+ url,
388
+ duration: Date.now() - startTime,
389
+ status: response.status,
390
+ statusText: response.statusText,
391
+ headers: sanitizeHeaders(response.headers)
392
+ });
393
+ }
394
+ return response;
395
+ } catch (error) {
396
+ if (hooks?.onResponse) {
397
+ hooks.onResponse({
398
+ method,
399
+ url,
400
+ duration: Date.now() - startTime,
401
+ error
402
+ });
403
+ }
518
404
  throw error;
519
405
  }
520
406
  }
@@ -528,36 +414,43 @@ async function createGetRequest(baseUrl, urlPath, options) {
528
414
  ...options
529
415
  };
530
416
  const opts = { __proto__: null, ...rawOpts };
531
- hooks?.onRequest?.({
532
- method,
533
- url,
534
- headers: sanitizeHeaders(opts.headers),
535
- timeout: opts.timeout
536
- });
537
- try {
538
- const req = getHttpModule(baseUrl).request(url, {
539
- method,
540
- ...opts
541
- }).end();
542
- const response = await getResponse(req);
543
- stopTimer({ statusCode: response.statusCode });
544
- hooks?.onResponse?.({
417
+ if (hooks?.onRequest) {
418
+ hooks.onRequest({
545
419
  method,
546
420
  url,
547
- duration: Date.now() - startTime,
548
- status: response.statusCode,
549
- statusText: response.statusMessage,
550
- headers: sanitizeHeaders(response.headers)
421
+ headers: sanitizeHeaders(opts.headers),
422
+ timeout: opts.timeout
551
423
  });
424
+ }
425
+ try {
426
+ const response = await (0, import_http_request.httpRequest)(url, {
427
+ method,
428
+ headers: opts.headers,
429
+ timeout: opts.timeout,
430
+ maxResponseSize: MAX_RESPONSE_SIZE
431
+ });
432
+ stopTimer({ statusCode: response.status });
433
+ if (hooks?.onResponse) {
434
+ hooks.onResponse({
435
+ method,
436
+ url,
437
+ duration: Date.now() - startTime,
438
+ status: response.status,
439
+ statusText: response.statusText,
440
+ headers: sanitizeHeaders(response.headers)
441
+ });
442
+ }
552
443
  return response;
553
444
  } catch (error) {
554
445
  stopTimer({ error: true });
555
- hooks?.onResponse?.({
556
- method,
557
- url,
558
- duration: Date.now() - startTime,
559
- error
560
- });
446
+ if (hooks?.onResponse) {
447
+ hooks.onResponse({
448
+ method,
449
+ url,
450
+ duration: Date.now() - startTime,
451
+ error
452
+ });
453
+ }
561
454
  throw error;
562
455
  }
563
456
  }
@@ -575,157 +468,49 @@ async function createRequestWithJson(method, baseUrl, urlPath, json, options) {
575
468
  const body = JSON.stringify(json);
576
469
  const headers = {
577
470
  ...opts.headers,
578
- "Content-Length": Buffer.byteLength(body, "utf8"),
579
471
  "Content-Type": "application/json"
580
472
  };
581
- hooks?.onRequest?.({
582
- method,
583
- url,
584
- headers: sanitizeHeaders(headers),
585
- timeout: opts.timeout
586
- });
587
- try {
588
- const req = getHttpModule(baseUrl).request(url, {
473
+ if (hooks?.onRequest) {
474
+ hooks.onRequest({
589
475
  method,
590
- ...opts,
591
- headers
476
+ url,
477
+ headers: sanitizeHeaders(headers),
478
+ timeout: opts.timeout
592
479
  });
593
- req.write(body);
594
- req.end();
595
- const response = await getResponse(req);
596
- stopTimer({ statusCode: response.statusCode });
597
- hooks?.onResponse?.({
480
+ }
481
+ try {
482
+ const response = await (0, import_http_request.httpRequest)(url, {
598
483
  method,
599
- url,
600
- duration: Date.now() - startTime,
601
- status: response.statusCode,
602
- statusText: response.statusMessage,
603
- headers: sanitizeHeaders(response.headers)
484
+ body,
485
+ headers,
486
+ timeout: opts.timeout,
487
+ maxResponseSize: MAX_RESPONSE_SIZE
604
488
  });
489
+ stopTimer({ statusCode: response.status });
490
+ if (hooks?.onResponse) {
491
+ hooks.onResponse({
492
+ method,
493
+ url,
494
+ duration: Date.now() - startTime,
495
+ status: response.status,
496
+ statusText: response.statusText,
497
+ headers: sanitizeHeaders(response.headers)
498
+ });
499
+ }
605
500
  return response;
606
501
  } catch (error) {
607
502
  stopTimer({ error: true });
608
- hooks?.onResponse?.({
609
- method,
610
- url,
611
- duration: Date.now() - startTime,
612
- error
613
- });
503
+ if (hooks?.onResponse) {
504
+ hooks.onResponse({
505
+ method,
506
+ url,
507
+ duration: Date.now() - startTime,
508
+ error
509
+ });
510
+ }
614
511
  throw error;
615
512
  }
616
513
  }
617
- async function getErrorResponseBody(response) {
618
- return await new Promise((resolve, reject) => {
619
- let body = "";
620
- let totalBytes = 0;
621
- response.setEncoding("utf8");
622
- response.on("data", (chunk) => {
623
- const chunkBytes = Buffer.byteLength(chunk, "utf8");
624
- if (totalBytes + chunkBytes > MAX_RESPONSE_SIZE) {
625
- response.destroy();
626
- const projectedSize = totalBytes + chunkBytes;
627
- const sizeMB = (projectedSize / (1024 * 1024)).toFixed(2);
628
- const maxMB = (MAX_RESPONSE_SIZE / (1024 * 1024)).toFixed(2);
629
- const message = [
630
- `Response exceeds maximum size limit (${sizeMB}MB > ${maxMB}MB)`,
631
- "\u2192 The API response is too large to process safely.",
632
- "\u2192 Try: Use pagination parameters (limit, offset) to reduce response size.",
633
- "\u2192 Try: Request specific fields instead of full objects.",
634
- "\u2192 Contact support if you need to process larger responses."
635
- ].join("\n");
636
- reject(new Error(message));
637
- return;
638
- }
639
- totalBytes += chunkBytes;
640
- body += chunk;
641
- });
642
- response.on("end", () => resolve(body));
643
- response.on("error", (e) => reject(e));
644
- });
645
- }
646
- function getHttpModule(url) {
647
- return url.startsWith("https:") ? import_node_https.default : import_node_http.default;
648
- }
649
- async function getResponse(req) {
650
- return await new Promise((resolve, reject) => {
651
- let timedOut = false;
652
- req.on("response", (response) => {
653
- if (timedOut) {
654
- return;
655
- }
656
- resolve(response);
657
- });
658
- req.on("timeout", () => {
659
- timedOut = true;
660
- req.destroy();
661
- const method = req.method || "REQUEST";
662
- const path4 = req.path || "unknown";
663
- const timeout = req.timeout || "configured timeout";
664
- const message = [
665
- `${method} request timed out after ${timeout}ms: ${path4}`,
666
- "\u2192 The Socket API did not respond in time.",
667
- "\u2192 Try: Increase timeout option or check network connectivity.",
668
- "\u2192 If problem persists, Socket API may be experiencing issues."
669
- ].join("\n");
670
- reject(new Error(message));
671
- });
672
- req.on("error", (e) => {
673
- if (!timedOut) {
674
- const err = e;
675
- const method = req.method || "REQUEST";
676
- const path4 = req.path || "unknown";
677
- let message = `${method} request failed: ${path4}`;
678
- if (err.code === "ECONNREFUSED") {
679
- message += [
680
- "",
681
- "\u2192 Connection refused. Socket API server is unreachable.",
682
- "\u2192 Check: Network connectivity and firewall settings.",
683
- "\u2192 Verify: Base URL is correct (default: https://api.socket.dev)"
684
- ].join("\n");
685
- } else if (err.code === "ENOTFOUND") {
686
- message += [
687
- "",
688
- "\u2192 DNS lookup failed. Cannot resolve hostname.",
689
- "\u2192 Check: Internet connection and DNS settings.",
690
- "\u2192 Verify: Base URL hostname is correct."
691
- ].join("\n");
692
- } else if (err.code === "ETIMEDOUT") {
693
- message += [
694
- "",
695
- "\u2192 Connection timed out. Network or server issue.",
696
- "\u2192 Try: Check network connectivity and retry.",
697
- "\u2192 If using proxy, verify proxy configuration."
698
- ].join("\n");
699
- } else if (err.code === "ECONNRESET") {
700
- message += [
701
- "",
702
- "\u2192 Connection reset by server. Possible network interruption.",
703
- "\u2192 Try: Retry the request. Enable retries option if not set."
704
- ].join("\n");
705
- } else if (err.code === "EPIPE") {
706
- message += [
707
- "",
708
- "\u2192 Broken pipe. Server closed connection unexpectedly.",
709
- "\u2192 Possible: Authentication issue or server error.",
710
- "\u2192 Check: API token is valid and has required permissions."
711
- ].join("\n");
712
- } else if (err.code === "CERT_HAS_EXPIRED" || err.code === "UNABLE_TO_VERIFY_LEAF_SIGNATURE") {
713
- message += [
714
- "",
715
- "\u2192 SSL/TLS certificate error.",
716
- "\u2192 Check: System time and date are correct.",
717
- "\u2192 Try: Update CA certificates on your system."
718
- ].join("\n");
719
- } else if (err.code) {
720
- message += `
721
- \u2192 Error code: ${err.code}`;
722
- }
723
- const enhancedError = new Error(message, { cause: e });
724
- reject(enhancedError);
725
- }
726
- });
727
- });
728
- }
729
514
  async function getResponseJson(response, method, url) {
730
515
  const stopTimer = (0, import_performance.perfTimer)("http:parse-json");
731
516
  try {
@@ -736,7 +521,7 @@ async function getResponseJson(response, method, url) {
736
521
  url
737
522
  );
738
523
  }
739
- const responseBody = await getErrorResponseBody(response);
524
+ const responseBody = response.text();
740
525
  if (responseBody === "") {
741
526
  (0, import_debug.debugLog)("API response: empty response treated as {}");
742
527
  stopTimer({ success: true });
@@ -800,12 +585,12 @@ async function getResponseJson(response, method, url) {
800
585
  }
801
586
  }
802
587
  function isResponseOk(response) {
803
- const { statusCode } = response;
804
- return statusCode ? statusCode >= 200 && statusCode < 300 : false;
588
+ return response.ok;
805
589
  }
806
- function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions) {
590
+ function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions, policy) {
807
591
  if (!isAuthenticated) {
808
- const allowedActions = actions?.trim() ? actions.split(",") : void 0;
592
+ const allowedActions = actions?.trim() ? new Set(actions.split(",")) : void 0;
593
+ const resolvedPolicy = policy ?? publicPolicy;
809
594
  const reshapeArtifact = (artifact) => ({
810
595
  name: artifact.name,
811
596
  version: artifact.version,
@@ -815,21 +600,22 @@ function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions) {
815
600
  supplyChainRisk: artifact.supplyChainRisk,
816
601
  scorecards: artifact.scorecards,
817
602
  topLevelAncestors: artifact.topLevelAncestors,
818
- // Compact the alerts array to reduce response size for non-authenticated
819
- // requests.
820
- alerts: artifact.alerts?.filter((alert) => {
603
+ alerts: artifact.alerts?.reduce((acc, alert) => {
821
604
  if (alert.severity === "low") {
822
- return false;
605
+ return acc;
823
606
  }
824
- if (allowedActions && alert.action && !allowedActions.includes(alert.action)) {
825
- return false;
607
+ const action = resolvedPolicy.get(alert.type);
608
+ if (allowedActions && action && !allowedActions.has(action)) {
609
+ return acc;
826
610
  }
827
- return true;
828
- }).map((alert) => ({
829
- type: alert.type,
830
- severity: alert.severity,
831
- key: alert.key
832
- }))
611
+ acc.push({
612
+ action,
613
+ key: alert.key,
614
+ severity: alert.severity,
615
+ type: alert.type
616
+ });
617
+ return acc;
618
+ }, [])
833
619
  });
834
620
  if (data["artifacts"]) {
835
621
  const artifacts = data["artifacts"];
@@ -847,121 +633,22 @@ function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions) {
847
633
  return data;
848
634
  }
849
635
 
850
- // src/file-upload.ts
851
- function createRequestBodyForFilepaths(filepaths, basePath) {
852
- const form = new import_form_data.default();
853
- for (const absPath of filepaths) {
854
- const relPath = (0, import_normalize2.normalizePath)(import_node_path2.default.relative(basePath, absPath));
855
- const filename = import_node_path2.default.basename(absPath);
856
- let stream;
857
- try {
858
- stream = (0, import_node_fs.createReadStream)(absPath, { highWaterMark: 1024 * 1024 });
859
- } catch (error) {
860
- const err = error;
861
- let message = `Failed to read file: ${absPath}`;
862
- if (err.code === "ENOENT") {
863
- message += "\n\u2192 File does not exist. Check the file path and try again.";
864
- } else if (err.code === "EACCES") {
865
- message += `
866
- \u2192 Permission denied. Run: chmod +r "${absPath}"`;
867
- } else if (err.code === "EISDIR") {
868
- message += "\n\u2192 Expected a file but found a directory.";
869
- } else if (err.code) {
870
- message += `
871
- \u2192 Error code: ${err.code}`;
872
- }
873
- throw new Error(message, { cause: error });
874
- }
875
- form.append(relPath, stream, {
876
- contentType: "application/octet-stream",
877
- filename
878
- });
879
- }
880
- return form;
881
- }
882
- function createRequestBodyForJson(jsonData, basename = "data.json") {
883
- const ext = import_node_path2.default.extname(basename);
884
- const name = import_node_path2.default.basename(basename, ext);
885
- const jsonStream = import_node_stream.Readable.from(JSON.stringify(jsonData), {
886
- highWaterMark: 1024 * 1024
887
- });
888
- const form = new import_form_data.default();
889
- form.append(name, jsonStream, {
890
- contentType: "application/json",
891
- filename: basename
892
- });
893
- return form;
894
- }
895
- async function createUploadRequest(baseUrl, urlPath, form, options) {
896
- const { hooks, ...rawOpts } = {
897
- __proto__: null,
898
- ...options
899
- };
900
- const opts = { __proto__: null, ...rawOpts };
901
- return await new Promise((pass, fail) => {
902
- const url = new URL(urlPath, baseUrl);
903
- const method = "POST";
904
- const formHeaders = form.getHeaders();
905
- const headers = {
906
- ...opts?.headers,
907
- ...formHeaders
908
- };
909
- const startTime = Date.now();
910
- const req = getHttpModule(baseUrl).request(url, {
911
- method,
912
- ...opts,
913
- headers
914
- });
915
- hooks?.onRequest?.({
916
- method,
917
- url: url.toString(),
918
- headers: sanitizeHeaders(headers),
919
- timeout: opts.timeout
920
- });
921
- req.flushHeaders();
922
- void getResponse(req).then(
923
- (response) => {
924
- hooks?.onResponse?.({
925
- method,
926
- url: url.toString(),
927
- duration: Date.now() - startTime,
928
- status: response.statusCode,
929
- statusText: response.statusMessage,
930
- headers: sanitizeHeaders(response.headers)
931
- });
932
- pass(response);
933
- },
934
- (error) => {
935
- hooks?.onResponse?.({
936
- method,
937
- url: url.toString(),
938
- duration: Date.now() - startTime,
939
- error
940
- });
941
- fail(error);
942
- }
943
- );
944
- form.pipe(req);
945
- form.on("error", fail);
946
- });
947
- }
948
-
949
636
  // src/quota-utils.ts
950
- var import_node_fs2 = require("node:fs");
951
- var import_node_path3 = require("node:path");
952
- var import_memoization2 = require("@socketsecurity/lib/memoization");
953
- var loadRequirements = (0, import_memoization2.once)(() => {
637
+ var import_node_fs = require("node:fs");
638
+ var import_node_path = require("node:path");
639
+ var import_memoization = require("@socketsecurity/lib/memoization");
640
+ var loadRequirements = (0, import_memoization.once)(() => {
954
641
  try {
955
- const requirementsPath = (0, import_node_path3.join)(
642
+ const requirementsPath = (0, import_node_path.join)(
956
643
  __dirname,
957
644
  "..",
958
645
  "data",
959
646
  "api-method-quota-and-permissions.json"
960
647
  );
961
- if (!(0, import_node_fs2.existsSync)(requirementsPath)) {
648
+ if (!(0, import_node_fs.existsSync)(requirementsPath)) {
962
649
  throw new Error(`Requirements file not found at: ${requirementsPath}`);
963
650
  }
964
- const data = (0, import_node_fs2.readFileSync)(requirementsPath, "utf8");
651
+ const data = (0, import_node_fs.readFileSync)(requirementsPath, "utf8");
965
652
  return JSON.parse(data);
966
653
  } catch (e) {
967
654
  throw new Error("Failed to load SDK method requirements", { cause: e });
@@ -983,7 +670,7 @@ function getAllMethodRequirements() {
983
670
  });
984
671
  return result;
985
672
  }
986
- var getMethodRequirements = (0, import_memoization2.memoize)(
673
+ var getMethodRequirements = (0, import_memoization.memoize)(
987
674
  (methodName) => {
988
675
  const reqs = loadRequirements();
989
676
  const requirement = reqs.api[methodName];
@@ -997,7 +684,7 @@ var getMethodRequirements = (0, import_memoization2.memoize)(
997
684
  },
998
685
  { name: "getMethodRequirements" }
999
686
  );
1000
- var getMethodsByPermissions = (0, import_memoization2.memoize)(
687
+ var getMethodsByPermissions = (0, import_memoization.memoize)(
1001
688
  (permissions) => {
1002
689
  const reqs = loadRequirements();
1003
690
  return Object.entries(reqs.api).filter(([, requirement]) => {
@@ -1008,14 +695,14 @@ var getMethodsByPermissions = (0, import_memoization2.memoize)(
1008
695
  },
1009
696
  { name: "getMethodsByPermissions" }
1010
697
  );
1011
- var getMethodsByQuotaCost = (0, import_memoization2.memoize)(
698
+ var getMethodsByQuotaCost = (0, import_memoization.memoize)(
1012
699
  (quotaCost) => {
1013
700
  const reqs = loadRequirements();
1014
701
  return Object.entries(reqs.api).filter(([, requirement]) => requirement.quota === quotaCost).map(([methodName]) => methodName).sort();
1015
702
  },
1016
703
  { name: "getMethodsByQuotaCost" }
1017
704
  );
1018
- var getQuotaCost = (0, import_memoization2.memoize)(
705
+ var getQuotaCost = (0, import_memoization.memoize)(
1019
706
  (methodName) => {
1020
707
  const reqs = loadRequirements();
1021
708
  const requirement = reqs.api[methodName];
@@ -1026,7 +713,7 @@ var getQuotaCost = (0, import_memoization2.memoize)(
1026
713
  },
1027
714
  { name: "getQuotaCost" }
1028
715
  );
1029
- var getQuotaUsageSummary = (0, import_memoization2.memoize)(
716
+ var getQuotaUsageSummary = (0, import_memoization.memoize)(
1030
717
  () => {
1031
718
  const reqs = loadRequirements();
1032
719
  const summary = {};
@@ -1044,40 +731,234 @@ var getQuotaUsageSummary = (0, import_memoization2.memoize)(
1044
731
  },
1045
732
  { name: "getQuotaUsageSummary" }
1046
733
  );
1047
- var getRequiredPermissions = (0, import_memoization2.memoize)(
734
+ var getRequiredPermissions = (0, import_memoization.memoize)(
1048
735
  (methodName) => {
1049
736
  const reqs = loadRequirements();
1050
737
  const requirement = reqs.api[methodName];
1051
738
  if (!requirement) {
1052
739
  throw new Error(`Unknown SDK method: "${String(methodName)}"`);
1053
740
  }
1054
- return [...requirement.permissions];
1055
- },
1056
- { name: "getRequiredPermissions" }
1057
- );
1058
- function hasQuotaForMethods(availableQuota, methodNames) {
1059
- const totalCost = calculateTotalQuotaCost(methodNames);
1060
- return availableQuota >= totalCost;
741
+ return [...requirement.permissions];
742
+ },
743
+ { name: "getRequiredPermissions" }
744
+ );
745
+ function hasQuotaForMethods(availableQuota, methodNames) {
746
+ const totalCost = calculateTotalQuotaCost(methodNames);
747
+ return availableQuota >= totalCost;
748
+ }
749
+
750
+ // src/socket-sdk-class.ts
751
+ var import_node_path4 = __toESM(require("node:path"));
752
+ var import_node_process2 = __toESM(require("node:process"));
753
+ var import_cache_with_ttl = require("@socketsecurity/lib/cache-with-ttl");
754
+ var import_core = require("@socketsecurity/lib/constants/core");
755
+ var import_process = require("@socketsecurity/lib/constants/process");
756
+ var import_socket2 = require("@socketsecurity/lib/constants/socket");
757
+ var import_debug2 = require("@socketsecurity/lib/debug");
758
+ var import_fs = require("@socketsecurity/lib/fs");
759
+ var import_parse2 = require("@socketsecurity/lib/json/parse");
760
+ var import_objects = require("@socketsecurity/lib/objects");
761
+ var import_promises = require("@socketsecurity/lib/promises");
762
+ var import_suppress_warnings = require("@socketsecurity/lib/suppress-warnings");
763
+ var import_url = require("@socketsecurity/lib/url");
764
+ var import_http_request3 = require("@socketsecurity/lib/http-request");
765
+
766
+ // src/file-upload.ts
767
+ var import_node_fs2 = require("node:fs");
768
+ var import_node_path2 = __toESM(require("node:path"));
769
+ var import_form_data = __toESM(require("form-data"));
770
+ var import_http_request2 = require("@socketsecurity/lib/http-request");
771
+ var import_normalize = require("@socketsecurity/lib/paths/normalize");
772
+ function createRequestBodyForFilepaths(filepaths, basePath) {
773
+ const form = new import_form_data.default();
774
+ for (const absPath of filepaths) {
775
+ const relPath = (0, import_normalize.normalizePath)(import_node_path2.default.relative(basePath, absPath));
776
+ const filename = import_node_path2.default.basename(absPath);
777
+ let stream;
778
+ try {
779
+ stream = (0, import_node_fs2.createReadStream)(absPath, { highWaterMark: 1024 * 1024 });
780
+ } catch (error) {
781
+ const err = error;
782
+ let message = `Failed to read file: ${absPath}`;
783
+ if (err.code === "ENOENT") {
784
+ message += "\n\u2192 File does not exist. Check the file path and try again.";
785
+ } else if (err.code === "EACCES") {
786
+ message += `
787
+ \u2192 Permission denied. Run: chmod +r "${absPath}"`;
788
+ } else if (err.code === "EISDIR") {
789
+ message += "\n\u2192 Expected a file but found a directory.";
790
+ } else if (err.code) {
791
+ message += `
792
+ \u2192 Error code: ${err.code}`;
793
+ }
794
+ throw new Error(message, { cause: error });
795
+ }
796
+ form.append(relPath, stream, {
797
+ contentType: "application/octet-stream",
798
+ filename
799
+ });
800
+ }
801
+ return form;
802
+ }
803
+ async function createUploadRequest(baseUrl, urlPath, form, options) {
804
+ const { hooks, ...rawOpts } = {
805
+ __proto__: null,
806
+ ...options
807
+ };
808
+ const opts = { __proto__: null, ...rawOpts };
809
+ const url = new URL(urlPath, baseUrl).toString();
810
+ const method = "POST";
811
+ const startTime = Date.now();
812
+ const headers = {
813
+ ...opts.headers
814
+ };
815
+ if (hooks?.onRequest) {
816
+ hooks.onRequest({
817
+ method,
818
+ url,
819
+ headers: sanitizeHeaders(headers),
820
+ timeout: opts.timeout
821
+ });
822
+ }
823
+ try {
824
+ const response = await (0, import_http_request2.httpRequest)(url, {
825
+ method,
826
+ body: form,
827
+ headers,
828
+ maxResponseSize: MAX_RESPONSE_SIZE,
829
+ timeout: opts.timeout
830
+ });
831
+ if (hooks?.onResponse) {
832
+ hooks.onResponse({
833
+ method,
834
+ url,
835
+ duration: Date.now() - startTime,
836
+ status: response.status,
837
+ statusText: response.statusText,
838
+ headers: sanitizeHeaders(response.headers)
839
+ });
840
+ }
841
+ return response;
842
+ } catch (error) {
843
+ if (hooks?.onResponse) {
844
+ hooks.onResponse({
845
+ method,
846
+ url,
847
+ duration: Date.now() - startTime,
848
+ error
849
+ });
850
+ }
851
+ throw error;
852
+ }
853
+ }
854
+
855
+ // src/utils.ts
856
+ var import_node_path3 = __toESM(require("node:path"));
857
+ var import_node_process = __toESM(require("node:process"));
858
+ var import_memoization2 = require("@socketsecurity/lib/memoization");
859
+ var import_normalize2 = require("@socketsecurity/lib/paths/normalize");
860
+ function normalizeToWordSet(s) {
861
+ const words = s.toLowerCase().match(/\w+/g);
862
+ return new Set(words ?? []);
863
+ }
864
+ function calculateWordSetSimilarity(str1, str2) {
865
+ const set1 = normalizeToWordSet(str1);
866
+ const set2 = normalizeToWordSet(str2);
867
+ if (set1.size === 0 && set2.size === 0) {
868
+ return 1;
869
+ }
870
+ if (set1.size === 0 || set2.size === 0) {
871
+ return 0;
872
+ }
873
+ let intersectionSize = 0;
874
+ for (const word of set1) {
875
+ if (set2.has(word)) {
876
+ intersectionSize++;
877
+ }
878
+ }
879
+ const unionSize = set1.size + set2.size - intersectionSize;
880
+ return intersectionSize / unionSize;
881
+ }
882
+ function filterRedundantCause(errorMessage, errorCause, threshold = 0.6) {
883
+ if (!errorCause || !errorCause.trim()) {
884
+ return void 0;
885
+ }
886
+ const messageParts = errorMessage.split(":").map((part) => part.trim());
887
+ for (const part of messageParts) {
888
+ if (part && shouldOmitReason(part, errorCause, threshold)) {
889
+ return void 0;
890
+ }
891
+ }
892
+ return errorCause;
893
+ }
894
+ var normalizeBaseUrl = (0, import_memoization2.memoize)(
895
+ (baseUrl) => {
896
+ return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
897
+ },
898
+ { name: "normalizeBaseUrl" }
899
+ );
900
+ function promiseWithResolvers() {
901
+ if (Promise.withResolvers) {
902
+ return Promise.withResolvers();
903
+ }
904
+ const obj = {};
905
+ obj.promise = new Promise((resolver, reject) => {
906
+ obj.resolve = resolver;
907
+ obj.reject = reject;
908
+ });
909
+ return obj;
910
+ }
911
+ function queryToSearchParams(init) {
912
+ const params = new URLSearchParams(
913
+ init
914
+ );
915
+ let needsNormalization = false;
916
+ let hasEmpty = false;
917
+ for (const [key, value] of params) {
918
+ if (key === "defaultBranch" || key === "perPage") {
919
+ needsNormalization = true;
920
+ break;
921
+ }
922
+ if (!value) {
923
+ hasEmpty = true;
924
+ }
925
+ }
926
+ if (!needsNormalization && !hasEmpty) {
927
+ return params;
928
+ }
929
+ const normalized = new URLSearchParams();
930
+ for (const [key, value] of params) {
931
+ if (!value) {
932
+ continue;
933
+ }
934
+ if (key === "defaultBranch") {
935
+ normalized.set("default_branch", value);
936
+ } else if (key === "perPage") {
937
+ normalized.set("per_page", value);
938
+ } else {
939
+ normalized.set(key, value);
940
+ }
941
+ }
942
+ return normalized;
943
+ }
944
+ function resolveAbsPaths(filepaths, pathsRelativeTo) {
945
+ const basePath = resolveBasePath(pathsRelativeTo);
946
+ return filepaths.map((p) => (0, import_normalize2.normalizePath)(import_node_path3.default.resolve(basePath, p)));
947
+ }
948
+ function resolveBasePath(pathsRelativeTo = ".") {
949
+ return (0, import_normalize2.normalizePath)(import_node_path3.default.resolve(import_node_process.default.cwd(), pathsRelativeTo));
950
+ }
951
+ function shouldOmitReason(errorMessage, reason, threshold = 0.6) {
952
+ if (!reason || !reason.trim()) {
953
+ return true;
954
+ }
955
+ const similarity = calculateWordSetSimilarity(errorMessage, reason);
956
+ return similarity >= threshold;
1061
957
  }
1062
958
 
1063
959
  // src/socket-sdk-class.ts
1064
- var import_node_events = __toESM(require("node:events"));
1065
- var import_node_fs3 = require("node:fs");
1066
- var import_node_path4 = __toESM(require("node:path"));
1067
- var import_node_readline = __toESM(require("node:readline"));
1068
- var import_cache_with_ttl = require("@socketsecurity/lib/cache-with-ttl");
1069
- var import_core = require("@socketsecurity/lib/constants/core");
1070
- var import_process = require("@socketsecurity/lib/constants/process");
1071
- var import_socket2 = require("@socketsecurity/lib/constants/socket");
1072
- var import_debug2 = require("@socketsecurity/lib/debug");
1073
- var import_fs = require("@socketsecurity/lib/fs");
1074
- var import_parse2 = require("@socketsecurity/lib/json/parse");
1075
- var import_objects = require("@socketsecurity/lib/objects");
1076
- var import_promises = require("@socketsecurity/lib/promises");
1077
- var import_suppress_warnings = require("@socketsecurity/lib/suppress-warnings");
1078
- var import_url = require("@socketsecurity/lib/url");
1079
960
  var abortSignal = (0, import_process.getAbortSignal)();
1080
- var SocketSdk = class {
961
+ var SocketSdk = class _SocketSdk {
1081
962
  #apiToken;
1082
963
  #baseUrl;
1083
964
  #cache;
@@ -1086,6 +967,7 @@ var SocketSdk = class {
1086
967
  #hooks;
1087
968
  #onFileValidation;
1088
969
  #reqOptions;
970
+ #reqOptionsWithHooks;
1089
971
  #retries;
1090
972
  #retryDelay;
1091
973
  /**
@@ -1158,6 +1040,10 @@ var SocketSdk = class {
1158
1040
  /* c8 ignore next - Optional timeout parameter, tested implicitly through method calls */
1159
1041
  ...timeout ? { timeout } : {}
1160
1042
  };
1043
+ this.#reqOptionsWithHooks = {
1044
+ ...this.#reqOptions,
1045
+ hooks: this.#hooks
1046
+ };
1161
1047
  }
1162
1048
  /**
1163
1049
  * Create async generator for streaming batch package URL processing.
@@ -1176,32 +1062,30 @@ var SocketSdk = class {
1176
1062
  if (!res) {
1177
1063
  throw new Error("Failed to get response from batch PURL request");
1178
1064
  }
1179
- const rli = import_node_readline.default.createInterface({
1180
- input: res,
1181
- crlfDelay: Number.POSITIVE_INFINITY,
1182
- signal: abortSignal
1183
- });
1184
1065
  const isPublicToken = this.#apiToken === import_socket2.SOCKET_PUBLIC_API_TOKEN;
1185
- try {
1186
- for await (const line of rli) {
1187
- const trimmed = line.trim();
1188
- const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1189
- /* c8 ignore next - Empty line handling in batch streaming response parsing. */
1190
- null
1191
- );
1192
- if ((0, import_objects.isObjectObject)(artifact)) {
1193
- yield this.#handleApiSuccess(
1194
- /* c8 ignore next 7 - Public token artifact reshaping branch for policy compliance. */
1195
- isPublicToken ? reshapeArtifactForPublicPolicy(
1196
- artifact,
1197
- false,
1198
- queryParams?.["actions"]
1199
- ) : artifact
1200
- );
1066
+ const text = res.text();
1067
+ let start = 0;
1068
+ for (let i = 0; i <= text.length; i++) {
1069
+ if (i === text.length || text.charCodeAt(i) === 10) {
1070
+ if (i > start) {
1071
+ const line = text.slice(start, i);
1072
+ const artifact = (0, import_parse2.jsonParse)(line, {
1073
+ throws: false
1074
+ });
1075
+ if ((0, import_objects.isObjectObject)(artifact)) {
1076
+ yield this.#handleApiSuccess(
1077
+ /* c8 ignore next 8 - Public token artifact reshaping branch for policy compliance. */
1078
+ isPublicToken ? reshapeArtifactForPublicPolicy(
1079
+ artifact,
1080
+ false,
1081
+ queryParams?.["actions"],
1082
+ publicPolicy
1083
+ ) : artifact
1084
+ );
1085
+ }
1201
1086
  }
1087
+ start = i + 1;
1202
1088
  }
1203
- } finally {
1204
- rli.close();
1205
1089
  }
1206
1090
  }
1207
1091
  /**
@@ -1210,11 +1094,13 @@ var SocketSdk = class {
1210
1094
  */
1211
1095
  async #createBatchPurlRequest(componentsObj, queryParams) {
1212
1096
  const url = `${this.#baseUrl}purl?${queryToSearchParams(queryParams)}`;
1213
- const req = getHttpModule(this.#baseUrl).request(url, {
1097
+ const response = await (0, import_http_request3.httpRequest)(url, {
1214
1098
  method: "POST",
1215
- ...this.#reqOptions
1216
- }).end(JSON.stringify(componentsObj));
1217
- const response = await getResponse(req);
1099
+ body: JSON.stringify(componentsObj),
1100
+ headers: this.#reqOptions.headers,
1101
+ timeout: this.#reqOptions.timeout,
1102
+ maxResponseSize: MAX_RESPONSE_SIZE
1103
+ });
1218
1104
  if (!isResponseOk(response)) {
1219
1105
  throw new ResponseError(response, "", url);
1220
1106
  }
@@ -1261,17 +1147,18 @@ var SocketSdk = class {
1261
1147
  if (!(error instanceof ResponseError)) {
1262
1148
  return void 0;
1263
1149
  }
1264
- const { statusCode } = error.response;
1265
- if (statusCode === 401 || statusCode === 403) {
1266
- throw error;
1267
- }
1268
- if (statusCode === 429) {
1150
+ const { status } = error.response;
1151
+ if (status === 429) {
1269
1152
  const retryAfter = this.#parseRetryAfter(
1270
1153
  error.response.headers["retry-after"]
1271
1154
  );
1272
1155
  if (retryAfter !== void 0) {
1273
1156
  return retryAfter;
1274
1157
  }
1158
+ return void 0;
1159
+ }
1160
+ if (status >= 400 && status < 500) {
1161
+ throw error;
1275
1162
  }
1276
1163
  return void 0;
1277
1164
  },
@@ -1332,25 +1219,6 @@ var SocketSdk = class {
1332
1219
  return await this.#executeWithRetry(fetcher);
1333
1220
  });
1334
1221
  }
1335
- /**
1336
- * Extract text content from HTTP response stream.
1337
- * Internal method with size limits to prevent memory exhaustion.
1338
- */
1339
- /* c8 ignore start - unused utility method reserved for future text response handling */
1340
- async #getResponseText(response) {
1341
- const chunks = [];
1342
- let size = 0;
1343
- const MAX = 50 * 1024 * 1024;
1344
- for await (const chunk of response) {
1345
- size += chunk.length;
1346
- if (size > MAX) {
1347
- throw new Error("Response body exceeds maximum size limit");
1348
- }
1349
- chunks.push(chunk);
1350
- }
1351
- return Buffer.concat(chunks).toString("utf8");
1352
- }
1353
- /* c8 ignore stop */
1354
1222
  /**
1355
1223
  * Handle API error responses and convert to standardized error result.
1356
1224
  * Internal error handling with status code analysis and message formatting.
@@ -1369,13 +1237,13 @@ var SocketSdk = class {
1369
1237
  cause: error
1370
1238
  });
1371
1239
  }
1372
- const { statusCode } = error.response;
1240
+ const { status: statusCode } = error.response;
1373
1241
  if (statusCode && statusCode >= 500) {
1374
1242
  throw new Error(`Socket API server error (${statusCode})`, {
1375
1243
  cause: error
1376
1244
  });
1377
1245
  }
1378
- const bodyStr = await getErrorResponseBody(error.response);
1246
+ const bodyStr = error.response.text();
1379
1247
  let body;
1380
1248
  try {
1381
1249
  const parsed = JSON.parse(bodyStr);
@@ -1393,7 +1261,7 @@ var SocketSdk = class {
1393
1261
  import_core.UNKNOWN_ERROR;
1394
1262
  const trimmedBody = body?.trim();
1395
1263
  if (trimmedBody && !errorMessage.includes(trimmedBody)) {
1396
- const statusMessage = error.response?.statusMessage;
1264
+ const statusMessage = error.response?.statusText;
1397
1265
  if (statusMessage && errorMessage.includes(statusMessage)) {
1398
1266
  errorMessage = errorMessage.replace(statusMessage, trimmedBody);
1399
1267
  } else {
@@ -1477,7 +1345,7 @@ var SocketSdk = class {
1477
1345
  return response;
1478
1346
  }
1479
1347
  if (responseType === "text") {
1480
- return await this.#getResponseText(response);
1348
+ return response.text();
1481
1349
  }
1482
1350
  if (responseType === "json") {
1483
1351
  return await getResponseJson(response);
@@ -1547,39 +1415,41 @@ var SocketSdk = class {
1547
1415
  const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/purl?${queryToSearchParams(queryParams)}`;
1548
1416
  let res;
1549
1417
  try {
1550
- const req = getHttpModule(this.#baseUrl).request(url, {
1551
- method: "POST",
1552
- ...this.#reqOptions
1553
- }).end(JSON.stringify(componentsObj));
1554
- res = await getResponse(req);
1555
- if (!isResponseOk(res)) {
1556
- throw new ResponseError(res, "", url);
1557
- }
1418
+ res = await this.#executeWithRetry(async () => {
1419
+ const response = await (0, import_http_request3.httpRequest)(url, {
1420
+ method: "POST",
1421
+ body: JSON.stringify(componentsObj),
1422
+ headers: this.#reqOptions.headers,
1423
+ timeout: this.#reqOptions.timeout,
1424
+ maxResponseSize: MAX_RESPONSE_SIZE
1425
+ });
1426
+ if (!isResponseOk(response)) {
1427
+ throw new ResponseError(response, "POST Request failed", url);
1428
+ }
1429
+ return response;
1430
+ });
1558
1431
  } catch (e) {
1559
1432
  return await this.#handleApiError(e);
1560
1433
  }
1561
1434
  if (!res) {
1562
1435
  throw new Error("Failed to get response from batch PURL request");
1563
1436
  }
1564
- const rli = import_node_readline.default.createInterface({
1565
- input: res,
1566
- crlfDelay: Number.POSITIVE_INFINITY,
1567
- signal: abortSignal
1568
- });
1569
1437
  const results = [];
1570
- try {
1571
- for await (const line of rli) {
1572
- const trimmed = line.trim();
1573
- const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1574
- /* c8 ignore next - Empty line handling in batch parsing. */
1575
- null
1576
- );
1577
- if ((0, import_objects.isObjectObject)(artifact)) {
1578
- results.push(artifact);
1438
+ const text = res.text();
1439
+ let start = 0;
1440
+ for (let i = 0; i <= text.length; i++) {
1441
+ if (i === text.length || text.charCodeAt(i) === 10) {
1442
+ if (i > start) {
1443
+ const line = text.slice(start, i);
1444
+ const artifact = (0, import_parse2.jsonParse)(line, {
1445
+ throws: false
1446
+ });
1447
+ if ((0, import_objects.isObjectObject)(artifact)) {
1448
+ results.push(artifact);
1449
+ }
1579
1450
  }
1451
+ start = i + 1;
1580
1452
  }
1581
- } finally {
1582
- rli.close();
1583
1453
  }
1584
1454
  const compact = (0, import_url.urlSearchParamAsBoolean)(
1585
1455
  (0, import_objects.getOwn)(queryParams, "compact")
@@ -1604,33 +1474,31 @@ var SocketSdk = class {
1604
1474
  if (!res) {
1605
1475
  throw new Error("Failed to get response from batch PURL request");
1606
1476
  }
1607
- const rli = import_node_readline.default.createInterface({
1608
- input: res,
1609
- crlfDelay: Number.POSITIVE_INFINITY,
1610
- signal: abortSignal
1611
- });
1612
1477
  const isPublicToken = this.#apiToken === import_socket2.SOCKET_PUBLIC_API_TOKEN;
1613
1478
  const results = [];
1614
- try {
1615
- for await (const line of rli) {
1616
- const trimmed = line.trim();
1617
- const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1618
- /* c8 ignore next - Empty line handling in batch parsing. */
1619
- null
1620
- );
1621
- if ((0, import_objects.isObjectObject)(artifact)) {
1622
- results.push(
1623
- /* c8 ignore next 7 - Public token artifact reshaping for policy compliance. */
1624
- isPublicToken ? reshapeArtifactForPublicPolicy(
1625
- artifact,
1626
- false,
1627
- queryParams?.["actions"]
1628
- ) : artifact
1629
- );
1479
+ const text = res.text();
1480
+ let start = 0;
1481
+ for (let i = 0; i <= text.length; i++) {
1482
+ if (i === text.length || text.charCodeAt(i) === 10) {
1483
+ if (i > start) {
1484
+ const line = text.slice(start, i);
1485
+ const artifact = (0, import_parse2.jsonParse)(line, {
1486
+ throws: false
1487
+ });
1488
+ if ((0, import_objects.isObjectObject)(artifact)) {
1489
+ results.push(
1490
+ /* c8 ignore next 8 - Public token artifact reshaping for policy compliance. */
1491
+ isPublicToken ? reshapeArtifactForPublicPolicy(
1492
+ artifact,
1493
+ false,
1494
+ queryParams?.["actions"],
1495
+ publicPolicy
1496
+ ) : artifact
1497
+ );
1498
+ }
1630
1499
  }
1500
+ start = i + 1;
1631
1501
  }
1632
- } finally {
1633
- rli.close();
1634
1502
  }
1635
1503
  const compact = (0, import_url.urlSearchParamAsBoolean)(
1636
1504
  (0, import_objects.getOwn)(queryParams, "compact")
@@ -1658,7 +1526,7 @@ var SocketSdk = class {
1658
1526
  (0, import_suppress_warnings.setMaxEventTargetListeners)(abortSignal, neededMaxListeners);
1659
1527
  const { components } = componentsObj;
1660
1528
  const { length: componentsCount } = components;
1661
- const running = [];
1529
+ const running = /* @__PURE__ */ new Map();
1662
1530
  let index = 0;
1663
1531
  const enqueueGen = () => {
1664
1532
  if (index >= componentsCount) {
@@ -1666,7 +1534,6 @@ var SocketSdk = class {
1666
1534
  }
1667
1535
  const generator = this.#createBatchPurlGenerator(
1668
1536
  {
1669
- // Chunk components.
1670
1537
  components: components.slice(index, index + chunkSize)
1671
1538
  },
1672
1539
  queryParams
@@ -1680,29 +1547,20 @@ var SocketSdk = class {
1680
1547
  reject: rejectFn,
1681
1548
  resolve: resolveFn
1682
1549
  } = promiseWithResolvers();
1683
- running.push({
1684
- generator,
1685
- promise
1686
- });
1550
+ running.set(generator, promise);
1687
1551
  void generator.next().then(
1688
1552
  (iteratorResult) => resolveFn({ generator, iteratorResult }),
1689
1553
  rejectFn
1690
1554
  );
1691
1555
  };
1692
- while (running.length < concurrencyLimit && index < componentsCount) {
1556
+ while (running.size < concurrencyLimit && index < componentsCount) {
1693
1557
  enqueueGen();
1694
1558
  }
1695
- while (running.length > 0) {
1559
+ while (running.size > 0) {
1696
1560
  const { generator, iteratorResult } = await Promise.race(
1697
- running.map((entry) => entry.promise)
1561
+ running.values()
1698
1562
  );
1699
- const runningIndex = running.findIndex(
1700
- (entry) => entry.generator === generator
1701
- );
1702
- if (runningIndex === -1) {
1703
- continue;
1704
- }
1705
- running.splice(runningIndex, 1);
1563
+ running.delete(generator);
1706
1564
  if (iteratorResult.value) {
1707
1565
  yield iteratorResult.value;
1708
1566
  }
@@ -1713,6 +1571,111 @@ var SocketSdk = class {
1713
1571
  }
1714
1572
  }
1715
1573
  }
1574
+ /**
1575
+ * Check packages for malware and security alerts.
1576
+ *
1577
+ * For small sets (≤ MAX_FIREWALL_COMPONENTS), uses parallel firewall API
1578
+ * requests which return full artifact data including score and alert details.
1579
+ *
1580
+ * For larger sets, uses the batch PURL API for efficiency.
1581
+ *
1582
+ * Both paths normalize alerts through publicPolicy and only return
1583
+ * malware-relevant results.
1584
+ *
1585
+ * @param components - Array of package URLs to check
1586
+ * @returns Normalized results with policy-filtered alerts per package
1587
+ */
1588
+ async checkMalware(components) {
1589
+ if (components.length <= MAX_FIREWALL_COMPONENTS) {
1590
+ return this.#checkMalwareFirewall(components);
1591
+ }
1592
+ return this.#checkMalwareBatch(components);
1593
+ }
1594
+ // Small-set path: parallel firewall API requests per PURL.
1595
+ // Returns full artifact data (score, alert props, categories, fix info).
1596
+ async #checkMalwareFirewall(components) {
1597
+ const packages = [];
1598
+ const results = await Promise.allSettled(
1599
+ components.map(async ({ purl }) => {
1600
+ const urlPath = `/${encodeURIComponent(purl)}`;
1601
+ const response = await createGetRequest(
1602
+ SOCKET_FIREWALL_API_URL,
1603
+ urlPath,
1604
+ this.#reqOptions
1605
+ );
1606
+ if (!isResponseOk(response)) return void 0;
1607
+ const json = await getResponseJson(response);
1608
+ return json;
1609
+ })
1610
+ );
1611
+ for (const settled of results) {
1612
+ if (settled.status === "rejected" || !settled.value) continue;
1613
+ packages.push(_SocketSdk.#normalizeArtifact(settled.value, publicPolicy));
1614
+ }
1615
+ return {
1616
+ cause: void 0,
1617
+ data: packages,
1618
+ error: void 0,
1619
+ status: 200,
1620
+ success: true
1621
+ };
1622
+ }
1623
+ // Multi-component path: batch PURL API request, normalized to publicPolicy.
1624
+ async #checkMalwareBatch(components) {
1625
+ const result = await this.batchPackageFetch(
1626
+ { components },
1627
+ { alerts: true, cachedResultsOnly: true }
1628
+ );
1629
+ if (!result.success) {
1630
+ return {
1631
+ cause: result.cause,
1632
+ data: void 0,
1633
+ error: result.error,
1634
+ status: result.status,
1635
+ success: false
1636
+ };
1637
+ }
1638
+ const packages = [];
1639
+ for (const artifact of result.data) {
1640
+ packages.push(_SocketSdk.#normalizeArtifact(artifact, publicPolicy));
1641
+ }
1642
+ return {
1643
+ cause: void 0,
1644
+ data: packages,
1645
+ error: void 0,
1646
+ status: 200,
1647
+ success: true
1648
+ };
1649
+ }
1650
+ // Normalize an artifact into MalwareCheckPackage.
1651
+ // When policy is provided, derive action from the map.
1652
+ // When policy is undefined, use server-assigned alert.action.
1653
+ static #normalizeArtifact(artifact, policy) {
1654
+ const alerts = [];
1655
+ if (artifact.alerts) {
1656
+ for (const alert of artifact.alerts) {
1657
+ const action = policy ? policy.get(alert.type) ?? "ignore" : alert.action ?? "ignore";
1658
+ if (action === "error" || action === "warn") {
1659
+ alerts.push({
1660
+ category: alert.category,
1661
+ fix: alert.fix ? { description: alert.fix.description, type: alert.fix.type } : void 0,
1662
+ key: alert.key,
1663
+ props: alert.props,
1664
+ severity: alert.severity,
1665
+ type: alert.type
1666
+ });
1667
+ }
1668
+ }
1669
+ }
1670
+ return {
1671
+ alerts,
1672
+ name: artifact.name,
1673
+ namespace: artifact.namespace,
1674
+ score: artifact.score,
1675
+ type: artifact.type,
1676
+ version: artifact.version
1677
+ };
1678
+ }
1716
1679
  /**
1717
1680
  * Create a snapshot of project dependencies by uploading manifest files.
1718
1681
  * Analyzes dependency files to generate a comprehensive security report.
@@ -1787,7 +1750,7 @@ var SocketSdk = class {
1787
1750
  this.#baseUrl,
1788
1751
  `dependencies/upload?${queryToSearchParams(queryParams)}`,
1789
1752
  createRequestBodyForFilepaths(validPaths, basePath),
1790
- { ...this.#reqOptions, hooks: this.#hooks }
1753
+ this.#reqOptionsWithHooks
1791
1754
  )
1792
1755
  )
1793
1756
  );
@@ -1901,7 +1864,7 @@ var SocketSdk = class {
1901
1864
  this.#baseUrl,
1902
1865
  `orgs/${encodeURIComponent(orgSlug)}/full-scans?${queryToSearchParams(queryParams)}`,
1903
1866
  createRequestBodyForFilepaths(validPaths, basePath),
1904
- { ...this.#reqOptions, hooks: this.#hooks }
1867
+ this.#reqOptionsWithHooks
1905
1868
  )
1906
1869
  )
1907
1870
  );
@@ -1965,7 +1928,7 @@ var SocketSdk = class {
1965
1928
  this.#baseUrl,
1966
1929
  `orgs/${encodeURIComponent(orgSlug)}/diff-scans/from-ids?${queryToSearchParams(options)}`,
1967
1930
  {},
1968
- { ...this.#reqOptions, hooks: this.#hooks }
1931
+ this.#reqOptionsWithHooks
1969
1932
  )
1970
1933
  )
1971
1934
  );
@@ -1994,7 +1957,7 @@ var SocketSdk = class {
1994
1957
  this.#baseUrl,
1995
1958
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/archive?${queryToSearchParams(options)}`,
1996
1959
  createRequestBodyForFilepaths([archivePath], basePath),
1997
- { ...this.#reqOptions, hooks: this.#hooks }
1960
+ this.#reqOptionsWithHooks
1998
1961
  )
1999
1962
  )
2000
1963
  );
@@ -2022,7 +1985,7 @@ var SocketSdk = class {
2022
1985
  this.#baseUrl,
2023
1986
  `orgs/${encodeURIComponent(orgSlug)}/webhooks`,
2024
1987
  webhookData,
2025
- { ...this.#reqOptions, hooks: this.#hooks }
1988
+ this.#reqOptionsWithHooks
2026
1989
  )
2027
1990
  )
2028
1991
  );
@@ -2075,7 +2038,7 @@ var SocketSdk = class {
2075
2038
  this.#baseUrl,
2076
2039
  `orgs/${encodeURIComponent(orgSlug)}/repos`,
2077
2040
  { ...params, name: repoSlug },
2078
- { ...this.#reqOptions, hooks: this.#hooks }
2041
+ this.#reqOptionsWithHooks
2079
2042
  )
2080
2043
  )
2081
2044
  );
@@ -2131,7 +2094,7 @@ var SocketSdk = class {
2131
2094
  this.#baseUrl,
2132
2095
  `orgs/${encodeURIComponent(orgSlug)}/repos/labels`,
2133
2096
  labelData,
2134
- { ...this.#reqOptions, hooks: this.#hooks }
2097
+ this.#reqOptionsWithHooks
2135
2098
  )
2136
2099
  )
2137
2100
  );
@@ -2184,7 +2147,7 @@ var SocketSdk = class {
2184
2147
  await createDeleteRequest(
2185
2148
  this.#baseUrl,
2186
2149
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}`,
2187
- { ...this.#reqOptions, hooks: this.#hooks }
2150
+ this.#reqOptionsWithHooks
2188
2151
  )
2189
2152
  )
2190
2153
  );
@@ -2219,7 +2182,7 @@ var SocketSdk = class {
2219
2182
  await createDeleteRequest(
2220
2183
  this.#baseUrl,
2221
2184
  `orgs/${encodeURIComponent(orgSlug)}/diff-scans/${encodeURIComponent(diffScanId)}`,
2222
- { ...this.#reqOptions, hooks: this.#hooks }
2185
+ this.#reqOptionsWithHooks
2223
2186
  )
2224
2187
  )
2225
2188
  );
@@ -2245,7 +2208,7 @@ var SocketSdk = class {
2245
2208
  await createDeleteRequest(
2246
2209
  this.#baseUrl,
2247
2210
  `orgs/${encodeURIComponent(orgSlug)}/webhooks/${encodeURIComponent(webhookId)}`,
2248
- { ...this.#reqOptions, hooks: this.#hooks }
2211
+ this.#reqOptionsWithHooks
2249
2212
  )
2250
2213
  )
2251
2214
  );
@@ -2291,7 +2254,7 @@ var SocketSdk = class {
2291
2254
  await createDeleteRequest(
2292
2255
  this.#baseUrl,
2293
2256
  `orgs/${encodeURIComponent(orgSlug)}/repos/${encodeURIComponent(repoSlug)}${queryString}`,
2294
- { ...this.#reqOptions, hooks: this.#hooks }
2257
+ this.#reqOptionsWithHooks
2295
2258
  )
2296
2259
  )
2297
2260
  );
@@ -2344,7 +2307,7 @@ var SocketSdk = class {
2344
2307
  await createDeleteRequest(
2345
2308
  this.#baseUrl,
2346
2309
  `orgs/${encodeURIComponent(orgSlug)}/repos/labels/${encodeURIComponent(labelId)}`,
2347
- { ...this.#reqOptions, hooks: this.#hooks }
2310
+ this.#reqOptionsWithHooks
2348
2311
  )
2349
2312
  )
2350
2313
  );
@@ -2367,60 +2330,39 @@ var SocketSdk = class {
2367
2330
  }
2368
2331
  }
2369
2332
  /**
2370
- * Delete a legacy scan report permanently.
2371
-
2372
- /**
2373
- * Download patch file content by hash.
2374
- *
2375
- * Downloads the actual patched file content from the public Socket blob store.
2376
- * This is used after calling viewPatch() to get the patch metadata.
2377
- * No authentication is required as patch blobs are publicly accessible.
2378
- *
2379
- * @param hash - The blob hash in SSRI (sha256-base64) or hex format
2380
- * @param options - Optional configuration
2381
- * @param options.baseUrl - Override blob store URL (for testing)
2382
- * @returns Promise<string> - The patch file content as UTF-8 string
2383
- * @throws Error if blob not found (404) or download fails
2384
- *
2385
- * @example
2386
- * ```typescript
2387
- * const sdk = new SocketSdk('your-api-token')
2388
- * // First get patch metadata
2389
- * const patch = await sdk.viewPatch('my-org', 'patch-uuid')
2390
- * // Then download the actual patched file
2391
- * const fileContent = await sdk.downloadPatch(patch.files['index.js'].socketBlob)
2392
- * ```
2393
- */
2333
+ * Download full scan files as a tar archive.
2334
+ *
2335
+ * Streams the full scan file contents to the specified output path as a tar file.
2336
+ * Includes size limit enforcement to prevent excessive disk usage.
2337
+ *
2338
+ * @param orgSlug - Organization identifier
2339
+ * @param fullScanId - Full scan identifier
2340
+ * @param outputPath - Local file path to write the tar archive
2341
+ * @returns Download result with success/error status
2342
+ * @throws {Error} When server returns 5xx status codes
2343
+ */
2394
2344
  async downloadOrgFullScanFilesAsTar(orgSlug, fullScanId, outputPath) {
2395
2345
  const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/files.tar`;
2396
2346
  try {
2397
- const req = getHttpModule(this.#baseUrl).request(url, {
2398
- method: "GET",
2399
- ...this.#reqOptions
2400
- }).end();
2401
- const res = await getResponse(req);
2402
- if (!isResponseOk(res)) {
2403
- throw new ResponseError(res, "", url);
2404
- }
2405
- const writeStream = (0, import_node_fs3.createWriteStream)(outputPath);
2406
- let bytesWritten = 0;
2407
- res.on("data", (chunk) => {
2408
- if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
2409
- const error = new Error(
2410
- `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
2411
- );
2412
- res.destroy(error);
2413
- writeStream.destroy(error);
2414
- return;
2347
+ const res = await this.#executeWithRetry(async () => {
2348
+ const response = await (0, import_http_request3.httpRequest)(url, {
2349
+ method: "GET",
2350
+ headers: this.#reqOptions.headers,
2351
+ stream: true,
2352
+ timeout: this.#reqOptions.timeout
2353
+ });
2354
+ if (!isResponseOk(response)) {
2355
+ throw new ResponseError(response, "", url);
2415
2356
  }
2416
- bytesWritten += chunk.length;
2357
+ return response;
2417
2358
  });
2418
- res.pipe(writeStream);
2419
- writeStream.on("error", (error) => {
2420
- res.destroy();
2421
- writeStream.destroy(error);
2359
+ const { createWriteStream } = await import("node:fs");
2360
+ await new Promise((resolve, reject) => {
2361
+ const ws = createWriteStream(outputPath);
2362
+ ws.on("error", reject);
2363
+ ws.on("close", resolve);
2364
+ res.rawResponse.pipe(ws);
2422
2365
  });
2423
- await import_node_events.default.once(writeStream, "finish");
2424
2366
  return this.#handleApiSuccess(res);
2425
2367
  } catch (e) {
2426
2368
  return await this.#handleApiError(e);
@@ -2449,90 +2391,34 @@ var SocketSdk = class {
2449
2391
  * ```
2450
2392
  */
2451
2393
  async downloadPatch(hash, options) {
2452
- const https2 = await import("node:https");
2453
- const http2 = await import("node:http");
2454
2394
  const blobPath = `/blob/${encodeURIComponent(hash)}`;
2455
2395
  const blobBaseUrl = options?.baseUrl || SOCKET_PUBLIC_BLOB_STORE_URL;
2456
2396
  const url = `${blobBaseUrl}${blobPath}`;
2457
- const isHttps = url.startsWith("https:");
2458
- return await new Promise((resolve, reject) => {
2459
- const client = isHttps ? https2 : http2;
2460
- client.get(url, (res) => {
2461
- if (res.statusCode === 404) {
2462
- const message = [
2463
- `Blob not found: ${hash}`,
2464
- `\u2192 URL: ${url}`,
2465
- "\u2192 The patch file may have expired or the hash is incorrect.",
2466
- "\u2192 Verify: The blob hash is correct.",
2467
- "\u2192 Note: Blob URLs may expire after a certain time period."
2468
- ].join("\n");
2469
- reject(new Error(message));
2470
- return;
2471
- }
2472
- if (res.statusCode !== 200) {
2473
- const message = [
2474
- `Failed to download blob: ${res.statusCode} ${res.statusMessage}`,
2475
- `\u2192 Hash: ${hash}`,
2476
- `\u2192 URL: ${url}`,
2477
- "\u2192 The blob storage service may be temporarily unavailable.",
2478
- res.statusCode && res.statusCode >= 500 ? "\u2192 Try: Retry the download after a short delay." : "\u2192 Verify: The blob hash and URL are correct."
2479
- ].join("\n");
2480
- reject(new Error(message));
2481
- return;
2482
- }
2483
- let data = "";
2484
- let bytesRead = 0;
2485
- const MAX_PATCH_SIZE = 50 * 1024 * 1024;
2486
- res.on("data", (chunk) => {
2487
- if (bytesRead + chunk.length > MAX_PATCH_SIZE) {
2488
- const error = new Error(
2489
- [
2490
- `Patch file exceeds maximum size of ${MAX_PATCH_SIZE} bytes`,
2491
- `\u2192 Current size: ${bytesRead + chunk.length} bytes`,
2492
- "\u2192 This may indicate an incorrect hash or corrupted blob."
2493
- ].join("\n")
2494
- );
2495
- res.destroy(error);
2496
- reject(error);
2497
- return;
2498
- }
2499
- bytesRead += chunk.length;
2500
- data += chunk.toString("utf8");
2501
- });
2502
- res.on("end", () => {
2503
- resolve(data);
2504
- });
2505
- res.on("error", (err) => {
2506
- reject(err);
2507
- });
2508
- }).on("error", (err) => {
2509
- const nodeErr = err;
2510
- const message = [
2511
- `Error downloading blob: ${hash}`,
2512
- `\u2192 URL: ${url}`,
2513
- `\u2192 Network error: ${nodeErr.message}`
2514
- ];
2515
- if (nodeErr.code === "ENOTFOUND") {
2516
- message.push(
2517
- "\u2192 DNS lookup failed. Cannot resolve blob storage hostname.",
2518
- "\u2192 Check: Internet connection and DNS settings."
2519
- );
2520
- } else if (nodeErr.code === "ECONNREFUSED") {
2521
- message.push(
2522
- "\u2192 Connection refused. Blob storage service is unreachable.",
2523
- "\u2192 Check: Network connectivity and firewall settings."
2524
- );
2525
- } else if (nodeErr.code === "ETIMEDOUT") {
2526
- message.push(
2527
- "\u2192 Connection timed out.",
2528
- "\u2192 Try: Check network connectivity and retry."
2529
- );
2530
- } else if (nodeErr.code) {
2531
- message.push(`\u2192 Error code: ${nodeErr.code}`);
2532
- }
2533
- reject(new Error(message.join("\n"), { cause: err }));
2534
- });
2397
+ const MAX_PATCH_SIZE = 50 * 1024 * 1024;
2398
+ const res = await (0, import_http_request3.httpRequest)(url, {
2399
+ maxResponseSize: MAX_PATCH_SIZE
2535
2400
  });
2401
+ if (res.status === 404) {
2402
+ const message = [
2403
+ `Blob not found: ${hash}`,
2404
+ `\u2192 URL: ${url}`,
2405
+ "\u2192 The patch file may have expired or the hash is incorrect.",
2406
+ "\u2192 Verify: The blob hash is correct.",
2407
+ "\u2192 Note: Blob URLs may expire after a certain time period."
2408
+ ].join("\n");
2409
+ throw new Error(message);
2410
+ }
2411
+ if (res.status !== 200) {
2412
+ const message = [
2413
+ `Failed to download blob: ${res.status} ${res.statusText}`,
2414
+ `\u2192 Hash: ${hash}`,
2415
+ `\u2192 URL: ${url}`,
2416
+ "\u2192 The blob storage service may be temporarily unavailable.",
2417
+ res.status >= 500 ? "\u2192 Try: Retry the download after a short delay." : "\u2192 Verify: The blob hash and URL are correct."
2418
+ ].join("\n");
2419
+ throw new Error(message);
2420
+ }
2421
+ return res.text();
2536
2422
  }
2537
2423
  /**
2538
2424
  * Export scan results in CycloneDX SBOM format.
@@ -2547,7 +2433,7 @@ var SocketSdk = class {
2547
2433
  await createGetRequest(
2548
2434
  this.#baseUrl,
2549
2435
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/sbom/export/cdx`,
2550
- { ...this.#reqOptions, hooks: this.#hooks }
2436
+ this.#reqOptionsWithHooks
2551
2437
  )
2552
2438
  )
2553
2439
  );
@@ -2592,7 +2478,7 @@ var SocketSdk = class {
2592
2478
  await createGetRequest(
2593
2479
  this.#baseUrl,
2594
2480
  `orgs/${encodeURIComponent(orgSlug)}/export/openvex/${encodeURIComponent(id)}${queryString}`,
2595
- { ...this.#reqOptions, hooks: this.#hooks }
2481
+ this.#reqOptionsWithHooks
2596
2482
  )
2597
2483
  )
2598
2484
  );
@@ -2614,7 +2500,7 @@ var SocketSdk = class {
2614
2500
  await createGetRequest(
2615
2501
  this.#baseUrl,
2616
2502
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/sbom/export/spdx`,
2617
- { ...this.#reqOptions, hooks: this.#hooks }
2503
+ this.#reqOptionsWithHooks
2618
2504
  )
2619
2505
  )
2620
2506
  );
@@ -2637,26 +2523,17 @@ var SocketSdk = class {
2637
2523
  };
2638
2524
  const url = `${this.#baseUrl}${urlPath}`;
2639
2525
  try {
2640
- const response = await createGetRequest(this.#baseUrl, urlPath, {
2641
- ...this.#reqOptions,
2642
- hooks: this.#hooks
2643
- });
2644
- if (!isResponseOk(response)) {
2645
- if (throws) {
2646
- throw new ResponseError(response, "", url);
2647
- }
2648
- const errorResult = await this.#handleApiError(
2649
- new ResponseError(response, "", url)
2526
+ const response = await this.#executeWithRetry(async () => {
2527
+ const res = await createGetRequest(
2528
+ this.#baseUrl,
2529
+ urlPath,
2530
+ this.#reqOptionsWithHooks
2650
2531
  );
2651
- return {
2652
- cause: errorResult.cause,
2653
- data: void 0,
2654
- error: errorResult.error,
2655
- status: errorResult.status,
2656
- success: false,
2657
- url: errorResult.url
2658
- };
2659
- }
2532
+ if (!isResponseOk(res)) {
2533
+ throw new ResponseError(res, "", url);
2534
+ }
2535
+ return res;
2536
+ });
2660
2537
  const data = await this.#handleQueryResponseData(
2661
2538
  response,
2662
2539
  responseType
@@ -2668,8 +2545,7 @@ var SocketSdk = class {
2668
2545
  cause: void 0,
2669
2546
  data,
2670
2547
  error: void 0,
2671
- /* c8 ignore next - Defensive fallback: response.statusCode is always defined in Node.js http/https */
2672
- status: response.statusCode ?? 200,
2548
+ status: response.status,
2673
2549
  success: true
2674
2550
  };
2675
2551
  } catch (e) {
@@ -2683,7 +2559,8 @@ var SocketSdk = class {
2683
2559
  data: void 0,
2684
2560
  error: errorResult.error,
2685
2561
  status: errorResult.status,
2686
- success: false
2562
+ success: false,
2563
+ url: errorResult.url
2687
2564
  };
2688
2565
  }
2689
2566
  return this.#createQueryErrorResult(e);
@@ -2702,7 +2579,7 @@ var SocketSdk = class {
2702
2579
  await createGetRequest(
2703
2580
  this.#baseUrl,
2704
2581
  `orgs/${encodeURIComponent(orgSlug)}/tokens`,
2705
- { ...this.#reqOptions, hooks: this.#hooks }
2582
+ this.#reqOptionsWithHooks
2706
2583
  )
2707
2584
  )
2708
2585
  );
@@ -2724,7 +2601,7 @@ var SocketSdk = class {
2724
2601
  await createGetRequest(
2725
2602
  this.#baseUrl,
2726
2603
  `orgs/${encodeURIComponent(orgSlug)}/audit-log?${queryToSearchParams(queryParams)}`,
2727
- { ...this.#reqOptions, hooks: this.#hooks }
2604
+ this.#reqOptionsWithHooks
2728
2605
  )
2729
2606
  )
2730
2607
  );
@@ -2746,7 +2623,7 @@ var SocketSdk = class {
2746
2623
  await createGetRequest(
2747
2624
  this.#baseUrl,
2748
2625
  `orgs/${encodeURIComponent(orgSlug)}/diff-scans/${encodeURIComponent(diffScanId)}`,
2749
- { ...this.#reqOptions, hooks: this.#hooks }
2626
+ this.#reqOptionsWithHooks
2750
2627
  )
2751
2628
  )
2752
2629
  );
@@ -2788,7 +2665,7 @@ var SocketSdk = class {
2788
2665
  await createGetRequest(
2789
2666
  this.#baseUrl,
2790
2667
  `orgs/${encodeURIComponent(orgSlug)}/diff-scans/${encodeURIComponent(diffScanId)}/gfm${options ? `?${queryToSearchParams(options)}` : ""}`,
2791
- { ...this.#reqOptions, hooks: this.#hooks }
2668
+ this.#reqOptionsWithHooks
2792
2669
  )
2793
2670
  )
2794
2671
  );
@@ -2800,7 +2677,7 @@ var SocketSdk = class {
2800
2677
  /**
2801
2678
  * Retrieve the enabled entitlements for an organization.
2802
2679
  *
2803
- * This method fetches the organization's entitlements and filters for only* the enabled ones, returning their keys. Entitlements represent Socket
2680
+ * This method fetches the organization's entitlements and filters for only the enabled ones, returning their keys. Entitlements represent Socket
2804
2681
  * Products that the organization has access to use.
2805
2682
  */
2806
2683
  async getEnabledEntitlements(orgSlug) {
@@ -2809,7 +2686,7 @@ var SocketSdk = class {
2809
2686
  await createGetRequest(
2810
2687
  this.#baseUrl,
2811
2688
  `orgs/${encodeURIComponent(orgSlug)}/entitlements`,
2812
- { ...this.#reqOptions, hooks: this.#hooks }
2689
+ this.#reqOptionsWithHooks
2813
2690
  )
2814
2691
  )
2815
2692
  );
@@ -2828,7 +2705,7 @@ var SocketSdk = class {
2828
2705
  await createGetRequest(
2829
2706
  this.#baseUrl,
2830
2707
  `orgs/${encodeURIComponent(orgSlug)}/entitlements`,
2831
- { ...this.#reqOptions, hooks: this.#hooks }
2708
+ this.#reqOptionsWithHooks
2832
2709
  )
2833
2710
  )
2834
2711
  );
@@ -2867,7 +2744,7 @@ var SocketSdk = class {
2867
2744
  await createGetRequest(
2868
2745
  this.#baseUrl,
2869
2746
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}`,
2870
- { ...this.#reqOptions, hooks: this.#hooks }
2747
+ this.#reqOptionsWithHooks
2871
2748
  )
2872
2749
  )
2873
2750
  );
@@ -2922,7 +2799,7 @@ var SocketSdk = class {
2922
2799
  await createGetRequest(
2923
2800
  this.#baseUrl,
2924
2801
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}/metadata`,
2925
- { ...this.#reqOptions, hooks: this.#hooks }
2802
+ this.#reqOptionsWithHooks
2926
2803
  )
2927
2804
  )
2928
2805
  );
@@ -2957,7 +2834,7 @@ var SocketSdk = class {
2957
2834
  await createGetRequest(
2958
2835
  this.#baseUrl,
2959
2836
  `npm/${encodeURIComponent(pkgName)}/${encodeURIComponent(version)}/issues`,
2960
- { ...this.#reqOptions, hooks: this.#hooks }
2837
+ this.#reqOptionsWithHooks
2961
2838
  )
2962
2839
  )
2963
2840
  );
@@ -3002,7 +2879,7 @@ var SocketSdk = class {
3002
2879
  await createGetRequest(
3003
2880
  this.#baseUrl,
3004
2881
  `orgs/${encodeURIComponent(orgSlug)}/alert-full-scan-search?${queryToSearchParams(options)}`,
3005
- { ...this.#reqOptions, hooks: this.#hooks }
2882
+ this.#reqOptionsWithHooks
3006
2883
  )
3007
2884
  )
3008
2885
  );
@@ -3028,7 +2905,7 @@ var SocketSdk = class {
3028
2905
  await createGetRequest(
3029
2906
  this.#baseUrl,
3030
2907
  `orgs/${encodeURIComponent(orgSlug)}/alerts?${queryToSearchParams(options)}`,
3031
- { ...this.#reqOptions, hooks: this.#hooks }
2908
+ this.#reqOptionsWithHooks
3032
2909
  )
3033
2910
  )
3034
2911
  );
@@ -3050,7 +2927,7 @@ var SocketSdk = class {
3050
2927
  await createGetRequest(
3051
2928
  this.#baseUrl,
3052
2929
  `analytics/org/${encodeURIComponent(time)}`,
3053
- { ...this.#reqOptions, hooks: this.#hooks }
2930
+ this.#reqOptionsWithHooks
3054
2931
  )
3055
2932
  )
3056
2933
  );
@@ -3076,7 +2953,7 @@ var SocketSdk = class {
3076
2953
  await createGetRequest(
3077
2954
  this.#baseUrl,
3078
2955
  `orgs/${encodeURIComponent(orgSlug)}/fixes?${queryToSearchParams(options)}`,
3079
- { ...this.#reqOptions, hooks: this.#hooks }
2956
+ this.#reqOptionsWithHooks
3080
2957
  )
3081
2958
  )
3082
2959
  );
@@ -3086,7 +2963,8 @@ var SocketSdk = class {
3086
2963
  }
3087
2964
  }
3088
2965
  /**
3089
- * Get organization's license policy configuration.* Returns allowed, restricted, and monitored license types.
2966
+ * Get organization's license policy configuration.
2967
+ * Returns allowed, restricted, and monitored license types.
3090
2968
  *
3091
2969
  * @throws {Error} When server returns 5xx status codes
3092
2970
  */
@@ -3097,7 +2975,7 @@ var SocketSdk = class {
3097
2975
  await createGetRequest(
3098
2976
  this.#baseUrl,
3099
2977
  `orgs/${encodeURIComponent(orgSlug)}/settings/license-policy`,
3100
- { ...this.#reqOptions, hooks: this.#hooks }
2978
+ this.#reqOptionsWithHooks
3101
2979
  )
3102
2980
  )
3103
2981
  );
@@ -3107,7 +2985,8 @@ var SocketSdk = class {
3107
2985
  }
3108
2986
  }
3109
2987
  /**
3110
- * Get organization's security policy configuration.* Returns alert rules, severity thresholds, and enforcement settings.
2988
+ * Get organization's security policy configuration.
2989
+ * Returns alert rules, severity thresholds, and enforcement settings.
3111
2990
  *
3112
2991
  * @throws {Error} When server returns 5xx status codes
3113
2992
  */
@@ -3118,7 +2997,7 @@ var SocketSdk = class {
3118
2997
  await createGetRequest(
3119
2998
  this.#baseUrl,
3120
2999
  `orgs/${encodeURIComponent(orgSlug)}/settings/security-policy`,
3121
- { ...this.#reqOptions, hooks: this.#hooks }
3000
+ this.#reqOptionsWithHooks
3122
3001
  )
3123
3002
  )
3124
3003
  );
@@ -3143,7 +3022,7 @@ var SocketSdk = class {
3143
3022
  await createGetRequest(
3144
3023
  this.#baseUrl,
3145
3024
  `orgs/${encodeURIComponent(orgSlug)}/telemetry/config`,
3146
- { ...this.#reqOptions, hooks: this.#hooks }
3025
+ this.#reqOptionsWithHooks
3147
3026
  )
3148
3027
  )
3149
3028
  );
@@ -3165,7 +3044,7 @@ var SocketSdk = class {
3165
3044
  await createGetRequest(
3166
3045
  this.#baseUrl,
3167
3046
  `orgs/${encodeURIComponent(orgSlug)}/triage`,
3168
- { ...this.#reqOptions, hooks: this.#hooks }
3047
+ this.#reqOptionsWithHooks
3169
3048
  )
3170
3049
  )
3171
3050
  );
@@ -3191,7 +3070,7 @@ var SocketSdk = class {
3191
3070
  await createGetRequest(
3192
3071
  this.#baseUrl,
3193
3072
  `orgs/${encodeURIComponent(orgSlug)}/webhooks/${encodeURIComponent(webhookId)}`,
3194
- { ...this.#reqOptions, hooks: this.#hooks }
3073
+ this.#reqOptionsWithHooks
3195
3074
  )
3196
3075
  )
3197
3076
  );
@@ -3217,7 +3096,7 @@ var SocketSdk = class {
3217
3096
  await createGetRequest(
3218
3097
  this.#baseUrl,
3219
3098
  `orgs/${encodeURIComponent(orgSlug)}/webhooks?${queryToSearchParams(options)}`,
3220
- { ...this.#reqOptions, hooks: this.#hooks }
3099
+ this.#reqOptionsWithHooks
3221
3100
  )
3222
3101
  )
3223
3102
  );
@@ -3237,10 +3116,11 @@ var SocketSdk = class {
3237
3116
  const data = await this.#getCached(
3238
3117
  "quota",
3239
3118
  async () => await getResponseJson(
3240
- await createGetRequest(this.#baseUrl, "quota", {
3241
- ...this.#reqOptions,
3242
- hooks: this.#hooks
3243
- })
3119
+ await createGetRequest(
3120
+ this.#baseUrl,
3121
+ "quota",
3122
+ this.#reqOptionsWithHooks
3123
+ )
3244
3124
  ),
3245
3125
  "quota"
3246
3126
  );
@@ -3262,7 +3142,7 @@ var SocketSdk = class {
3262
3142
  await createGetRequest(
3263
3143
  this.#baseUrl,
3264
3144
  `analytics/repo/${encodeURIComponent(repo)}/${encodeURIComponent(time)}`,
3265
- { ...this.#reqOptions, hooks: this.#hooks }
3145
+ this.#reqOptionsWithHooks
3266
3146
  )
3267
3147
  )
3268
3148
  );
@@ -3272,36 +3152,32 @@ var SocketSdk = class {
3272
3152
  }
3273
3153
  }
3274
3154
  /**
3275
- * Get detailed results for a legacy scan report.
3276
- /**
3277
-
3278
- /**
3279
- * Get details for a specific repository.
3280
- *
3281
- * Returns repository configuration, monitoring status, and metadata.
3282
- *
3283
- * @param orgSlug - Organization identifier
3284
- * @param repoSlug - Repository slug/name
3285
- * @param options - Optional parameters including workspace
3286
- * @returns Repository details with configuration
3287
- *
3288
- * @example
3289
- * ```typescript
3290
- * const result = await sdk.getRepository('my-org', 'my-repo')
3291
- *
3292
- * if (result.success) {
3293
- * console.log('Repository:', result.data.name)
3294
- * console.log('Visibility:', result.data.visibility)
3295
- * console.log('Default branch:', result.data.default_branch)
3296
- * }
3297
- * ```
3298
- *
3299
- * @see https://docs.socket.dev/reference/getorgrepo
3300
- * @apiEndpoint GET /orgs/{org_slug}/repos/{repo_slug}
3301
- * @quota 0 units
3302
- * @scopes repo:read
3303
- * @throws {Error} When server returns 5xx status codes
3304
- */
3155
+ * Get details for a specific repository.
3156
+ *
3157
+ * Returns repository configuration, monitoring status, and metadata.
3158
+ *
3159
+ * @param orgSlug - Organization identifier
3160
+ * @param repoSlug - Repository slug/name
3161
+ * @param options - Optional parameters including workspace
3162
+ * @returns Repository details with configuration
3163
+ *
3164
+ * @example
3165
+ * ```typescript
3166
+ * const result = await sdk.getRepository('my-org', 'my-repo')
3167
+ *
3168
+ * if (result.success) {
3169
+ * console.log('Repository:', result.data.name)
3170
+ * console.log('Visibility:', result.data.visibility)
3171
+ * console.log('Default branch:', result.data.default_branch)
3172
+ * }
3173
+ * ```
3174
+ *
3175
+ * @see https://docs.socket.dev/reference/getorgrepo
3176
+ * @apiEndpoint GET /orgs/{org_slug}/repos/{repo_slug}
3177
+ * @quota 0 units
3178
+ * @scopes repo:read
3179
+ * @throws {Error} When server returns 5xx status codes
3180
+ */
3305
3181
  async getRepository(orgSlug, repoSlug, options) {
3306
3182
  const orgSlugParam = encodeURIComponent(orgSlug);
3307
3183
  const repoSlugParam = encodeURIComponent(repoSlug);
@@ -3316,7 +3192,7 @@ var SocketSdk = class {
3316
3192
  await createGetRequest(
3317
3193
  this.#baseUrl,
3318
3194
  `orgs/${orgSlugParam}/repos/${repoSlugParam}${queryString}`,
3319
- { ...this.#reqOptions, hooks: this.#hooks }
3195
+ this.#reqOptionsWithHooks
3320
3196
  )
3321
3197
  )
3322
3198
  );
@@ -3371,7 +3247,7 @@ var SocketSdk = class {
3371
3247
  await createGetRequest(
3372
3248
  this.#baseUrl,
3373
3249
  `orgs/${encodeURIComponent(orgSlug)}/repos/labels/${encodeURIComponent(labelId)}`,
3374
- { ...this.#reqOptions, hooks: this.#hooks }
3250
+ this.#reqOptionsWithHooks
3375
3251
  )
3376
3252
  )
3377
3253
  );
@@ -3406,7 +3282,7 @@ var SocketSdk = class {
3406
3282
  await createGetRequest(
3407
3283
  this.#baseUrl,
3408
3284
  `npm/${encodeURIComponent(pkgName)}/${encodeURIComponent(version)}/score`,
3409
- { ...this.#reqOptions, hooks: this.#hooks }
3285
+ this.#reqOptionsWithHooks
3410
3286
  )
3411
3287
  )
3412
3288
  );
@@ -3448,10 +3324,7 @@ var SocketSdk = class {
3448
3324
  await createGetRequest(
3449
3325
  this.#baseUrl,
3450
3326
  `orgs/${encodeURIComponent(orgSlug)}/supported-files`,
3451
- {
3452
- ...this.#reqOptions,
3453
- hooks: this.#hooks
3454
- }
3327
+ this.#reqOptionsWithHooks
3455
3328
  )
3456
3329
  )
3457
3330
  );
@@ -3460,29 +3333,6 @@ var SocketSdk = class {
3460
3333
  return await this.#handleApiError(e);
3461
3334
  }
3462
3335
  }
3463
- /**
3464
- * Get list of file types and formats supported for scanning.
3465
- * Returns supported manifest files, lockfiles, and configuration formats.
3466
- *
3467
- * @deprecated Use getSupportedFiles() instead. This endpoint has been deprecated
3468
- * since 2023-01-15 and now uses the /report/supported endpoint.
3469
- * @throws {Error} When server returns 5xx status codes
3470
- */
3471
- async getSupportedScanFiles() {
3472
- try {
3473
- const data = await this.#executeWithRetry(
3474
- async () => await getResponseJson(
3475
- await createGetRequest(this.#baseUrl, "report/supported", {
3476
- ...this.#reqOptions,
3477
- hooks: this.#hooks
3478
- })
3479
- )
3480
- );
3481
- return this.#handleApiSuccess(data);
3482
- } catch (e) {
3483
- return await this.#handleApiError(e);
3484
- }
3485
- }
3486
3336
  /**
3487
3337
  * List all full scans for an organization.
3488
3338
  *
@@ -3521,7 +3371,7 @@ var SocketSdk = class {
3521
3371
  await createGetRequest(
3522
3372
  this.#baseUrl,
3523
3373
  `orgs/${encodeURIComponent(orgSlug)}/full-scans?${queryToSearchParams(options)}`,
3524
- { ...this.#reqOptions, hooks: this.#hooks }
3374
+ this.#reqOptionsWithHooks
3525
3375
  )
3526
3376
  )
3527
3377
  );
@@ -3571,10 +3421,11 @@ var SocketSdk = class {
3571
3421
  const data = await this.#getCached(
3572
3422
  "organizations",
3573
3423
  async () => await getResponseJson(
3574
- await createGetRequest(this.#baseUrl, "organizations", {
3575
- ...this.#reqOptions,
3576
- hooks: this.#hooks
3577
- })
3424
+ await createGetRequest(
3425
+ this.#baseUrl,
3426
+ "organizations",
3427
+ this.#reqOptionsWithHooks
3428
+ )
3578
3429
  ),
3579
3430
  "organizations"
3580
3431
  );
@@ -3609,7 +3460,7 @@ var SocketSdk = class {
3609
3460
  await createGetRequest(
3610
3461
  this.#baseUrl,
3611
3462
  `orgs/${encodeURIComponent(orgSlug)}/diff-scans`,
3612
- { ...this.#reqOptions, hooks: this.#hooks }
3463
+ this.#reqOptionsWithHooks
3613
3464
  )
3614
3465
  )
3615
3466
  );
@@ -3655,7 +3506,7 @@ var SocketSdk = class {
3655
3506
  await createGetRequest(
3656
3507
  this.#baseUrl,
3657
3508
  `orgs/${encodeURIComponent(orgSlug)}/repos?${queryToSearchParams(options)}`,
3658
- { ...this.#reqOptions, hooks: this.#hooks }
3509
+ this.#reqOptionsWithHooks
3659
3510
  )
3660
3511
  )
3661
3512
  );
@@ -3711,7 +3562,7 @@ var SocketSdk = class {
3711
3562
  await createGetRequest(
3712
3563
  this.#baseUrl,
3713
3564
  `orgs/${encodeURIComponent(orgSlug)}/repos/labels?${queryToSearchParams(options)}`,
3714
- { ...this.#reqOptions, hooks: this.#hooks }
3565
+ this.#reqOptionsWithHooks
3715
3566
  )
3716
3567
  )
3717
3568
  );
@@ -3748,7 +3599,7 @@ var SocketSdk = class {
3748
3599
  this.#baseUrl,
3749
3600
  `orgs/${encodeURIComponent(orgSlug)}/tokens`,
3750
3601
  tokenData,
3751
- { ...this.#reqOptions, hooks: this.#hooks }
3602
+ this.#reqOptionsWithHooks
3752
3603
  )
3753
3604
  )
3754
3605
  );
@@ -3772,7 +3623,7 @@ var SocketSdk = class {
3772
3623
  this.#baseUrl,
3773
3624
  `orgs/${encodeURIComponent(orgSlug)}/tokens/${encodeURIComponent(tokenId)}/revoke`,
3774
3625
  {},
3775
- { ...this.#reqOptions, hooks: this.#hooks }
3626
+ this.#reqOptionsWithHooks
3776
3627
  )
3777
3628
  )
3778
3629
  );
@@ -3796,7 +3647,7 @@ var SocketSdk = class {
3796
3647
  this.#baseUrl,
3797
3648
  `orgs/${encodeURIComponent(orgSlug)}/tokens/${encodeURIComponent(tokenId)}/rotate`,
3798
3649
  {},
3799
- { ...this.#reqOptions, hooks: this.#hooks }
3650
+ this.#reqOptionsWithHooks
3800
3651
  )
3801
3652
  )
3802
3653
  );
@@ -3820,7 +3671,7 @@ var SocketSdk = class {
3820
3671
  this.#baseUrl,
3821
3672
  `orgs/${encodeURIComponent(orgSlug)}/tokens/${encodeURIComponent(tokenId)}/update`,
3822
3673
  updateData,
3823
- { ...this.#reqOptions, hooks: this.#hooks }
3674
+ this.#reqOptionsWithHooks
3824
3675
  )
3825
3676
  )
3826
3677
  );
@@ -3848,7 +3699,7 @@ var SocketSdk = class {
3848
3699
  this.#baseUrl,
3849
3700
  `orgs/${encodeURIComponent(orgSlug)}/telemetry`,
3850
3701
  telemetryData,
3851
- { ...this.#reqOptions, hooks: this.#hooks }
3702
+ this.#reqOptionsWithHooks
3852
3703
  )
3853
3704
  )
3854
3705
  );
@@ -3860,7 +3711,7 @@ var SocketSdk = class {
3860
3711
  success: true
3861
3712
  };
3862
3713
  } catch (e) {
3863
- return this.#createQueryErrorResult(e);
3714
+ return await this.#handleApiError(e);
3864
3715
  }
3865
3716
  }
3866
3717
  /**
@@ -3878,7 +3729,7 @@ var SocketSdk = class {
3878
3729
  this.#baseUrl,
3879
3730
  "settings",
3880
3731
  { json: selectors },
3881
- { ...this.#reqOptions, hooks: this.#hooks }
3732
+ this.#reqOptionsWithHooks
3882
3733
  )
3883
3734
  )
3884
3735
  );
@@ -3930,7 +3781,7 @@ var SocketSdk = class {
3930
3781
  this.#baseUrl,
3931
3782
  `orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/rescan${queryString}`,
3932
3783
  {},
3933
- { ...this.#reqOptions, hooks: this.#hooks }
3784
+ this.#reqOptionsWithHooks
3934
3785
  )
3935
3786
  )
3936
3787
  );
@@ -3954,7 +3805,7 @@ var SocketSdk = class {
3954
3805
  this.#baseUrl,
3955
3806
  "dependencies/search",
3956
3807
  queryParams,
3957
- { ...this.#reqOptions, hooks: this.#hooks }
3808
+ this.#reqOptionsWithHooks
3958
3809
  )
3959
3810
  )
3960
3811
  );
@@ -3977,14 +3828,21 @@ var SocketSdk = class {
3977
3828
  method = "POST",
3978
3829
  throws = true
3979
3830
  } = { __proto__: null, ...options };
3831
+ const url = `${this.#baseUrl}${urlPath}`;
3980
3832
  try {
3981
- const response = await createRequestWithJson(
3982
- method,
3983
- this.#baseUrl,
3984
- urlPath,
3985
- body,
3986
- { ...this.#reqOptions, hooks: this.#hooks }
3987
- );
3833
+ const response = await this.#executeWithRetry(async () => {
3834
+ const res = await createRequestWithJson(
3835
+ method,
3836
+ this.#baseUrl,
3837
+ urlPath,
3838
+ body,
3839
+ this.#reqOptionsWithHooks
3840
+ );
3841
+ if (!isResponseOk(res)) {
3842
+ throw new ResponseError(res, "", url);
3843
+ }
3844
+ return res;
3845
+ });
3988
3846
  const data = await getResponseJson(response);
3989
3847
  if (throws) {
3990
3848
  return data;
@@ -3993,8 +3851,7 @@ var SocketSdk = class {
3993
3851
  cause: void 0,
3994
3852
  data,
3995
3853
  error: void 0,
3996
- /* c8 ignore next - Defensive fallback: response.statusCode is always defined in Node.js http/https */
3997
- status: response.statusCode ?? 200,
3854
+ status: response.status,
3998
3855
  success: true
3999
3856
  };
4000
3857
  } catch (e) {
@@ -4008,17 +3865,11 @@ var SocketSdk = class {
4008
3865
  data: void 0,
4009
3866
  error: errorResult.error,
4010
3867
  status: errorResult.status,
4011
- success: false
3868
+ success: false,
3869
+ url: errorResult.url
4012
3870
  };
4013
3871
  }
4014
- const errStr = e ? String(e).trim() : "";
4015
- return {
4016
- cause: errStr || import_core.UNKNOWN_ERROR,
4017
- data: void 0,
4018
- error: "API request failed",
4019
- status: 0,
4020
- success: false
4021
- };
3872
+ return this.#createQueryErrorResult(e);
4022
3873
  }
4023
3874
  }
4024
3875
  /**
@@ -4061,57 +3912,33 @@ var SocketSdk = class {
4061
3912
  };
4062
3913
  const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}`;
4063
3914
  try {
4064
- const req = getHttpModule(this.#baseUrl).request(url, {
4065
- method: "GET",
4066
- ...this.#reqOptions
4067
- }).end();
4068
- const res = await getResponse(req);
4069
- if (!isResponseOk(res)) {
4070
- throw new ResponseError(res, "", url);
4071
- }
4072
- if (typeof output === "string") {
4073
- const writeStream = (0, import_node_fs3.createWriteStream)(output);
4074
- let bytesWritten = 0;
4075
- res.on("data", (chunk) => {
4076
- if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
4077
- const error = new Error(
4078
- `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
4079
- );
4080
- res.destroy(error);
4081
- writeStream.destroy(error);
4082
- return;
4083
- }
4084
- bytesWritten += chunk.length;
3915
+ const needsStream = typeof output === "string" || output === true;
3916
+ const res = await this.#executeWithRetry(async () => {
3917
+ const response = await (0, import_http_request3.httpRequest)(url, {
3918
+ method: "GET",
3919
+ headers: this.#reqOptions.headers,
3920
+ stream: needsStream,
3921
+ timeout: this.#reqOptions.timeout,
3922
+ ...!needsStream && { maxResponseSize: MAX_RESPONSE_SIZE }
4085
3923
  });
4086
- res.pipe(writeStream);
4087
- writeStream.on("error", (error) => {
4088
- res.destroy();
4089
- writeStream.destroy(error);
3924
+ if (!isResponseOk(response)) {
3925
+ throw new ResponseError(response, "", url);
3926
+ }
3927
+ return response;
3928
+ });
3929
+ if (typeof output === "string") {
3930
+ const { createWriteStream } = await import("node:fs");
3931
+ await new Promise((resolve, reject) => {
3932
+ const ws = createWriteStream(output);
3933
+ ws.on("error", reject);
3934
+ ws.on("close", resolve);
3935
+ res.rawResponse.pipe(ws);
4090
3936
  });
4091
- await import_node_events.default.once(writeStream, "finish");
4092
3937
  } else if (output === true) {
4093
- let bytesWritten = 0;
4094
- res.on("data", (chunk) => {
4095
- if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
4096
- const error = new Error(
4097
- `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
4098
- );
4099
- res.destroy(error);
4100
- return;
4101
- }
4102
- bytesWritten += chunk.length;
4103
- });
4104
- const stdoutErrorHandler = (_error) => {
4105
- res.destroy();
4106
- process.stdout.removeListener("error", stdoutErrorHandler);
4107
- };
4108
- process.stdout.on("error", stdoutErrorHandler);
4109
- res.pipe(process.stdout);
4110
- res.on("end", () => {
4111
- process.stdout.removeListener("error", stdoutErrorHandler);
4112
- });
4113
- res.on("error", () => {
4114
- process.stdout.removeListener("error", stdoutErrorHandler);
3938
+ await new Promise((resolve, reject) => {
3939
+ res.rawResponse.on("error", reject);
3940
+ res.rawResponse.on("end", resolve);
3941
+ res.rawResponse.pipe(import_node_process2.default.stdout);
4115
3942
  });
4116
3943
  }
4117
3944
  return this.#handleApiSuccess(res);
@@ -4131,43 +3958,34 @@ var SocketSdk = class {
4131
3958
  const urlPath = `orgs/${encodeURIComponent(orgSlug)}/patches/scan?scan_id=${encodeURIComponent(scanId)}`;
4132
3959
  const url = `${this.#baseUrl}${urlPath}`;
4133
3960
  const response = await this.#executeWithRetry(
4134
- async () => await createGetRequest(this.#baseUrl, urlPath, {
4135
- ...this.#reqOptions,
4136
- hooks: this.#hooks
4137
- })
3961
+ async () => await createGetRequest(
3962
+ this.#baseUrl,
3963
+ urlPath,
3964
+ this.#reqOptionsWithHooks
3965
+ )
4138
3966
  );
4139
3967
  if (!isResponseOk(response)) {
4140
3968
  throw new ResponseError(response, "GET Request failed", url);
4141
3969
  }
4142
- const rli = import_node_readline.default.createInterface({
4143
- input: response,
4144
- crlfDelay: Number.POSITIVE_INFINITY
4145
- });
3970
+ const text = response.text();
4146
3971
  return new ReadableStream({
4147
- async start(controller) {
4148
- try {
4149
- for await (const line of rli) {
4150
- const trimmed = line.trim();
4151
- if (!trimmed) {
4152
- continue;
4153
- }
4154
- try {
4155
- const data = JSON.parse(trimmed);
4156
- controller.enqueue(data);
4157
- } catch (e) {
4158
- (0, import_debug2.debugLog)("streamPatchesFromScan", `Failed to parse line: ${e}`);
3972
+ start(controller) {
3973
+ let start = 0;
3974
+ for (let i = 0; i <= text.length; i++) {
3975
+ if (i === text.length || text.charCodeAt(i) === 10) {
3976
+ if (i > start) {
3977
+ const line = text.slice(start, i);
3978
+ try {
3979
+ const data = JSON.parse(line);
3980
+ controller.enqueue(data);
3981
+ } catch (e) {
3982
+ (0, import_debug2.debugLog)("streamPatchesFromScan", `Failed to parse line: ${e}`);
3983
+ }
4159
3984
  }
3985
+ start = i + 1;
4160
3986
  }
4161
- } catch (error) {
4162
- controller.error(error);
4163
- } finally {
4164
- rli.close();
4165
- controller.close();
4166
3987
  }
4167
- },
4168
- /* c8 ignore next 3 - Stream cancellation cleanup, difficult to test reliably. */
4169
- cancel() {
4170
- rli.close();
3988
+ controller.close();
4171
3989
  }
4172
3990
  });
4173
3991
  }
@@ -4186,7 +4004,7 @@ var SocketSdk = class {
4186
4004
  this.#baseUrl,
4187
4005
  `orgs/${encodeURIComponent(orgSlug)}/triage/${encodeURIComponent(alertId)}`,
4188
4006
  triageData,
4189
- { ...this.#reqOptions, hooks: this.#hooks }
4007
+ this.#reqOptionsWithHooks
4190
4008
  )
4191
4009
  )
4192
4010
  );
@@ -4196,7 +4014,8 @@ var SocketSdk = class {
4196
4014
  }
4197
4015
  }
4198
4016
  /**
4199
- * Update organization's license policy configuration.* Modifies allowed, restricted, and monitored license types.
4017
+ * Update organization's license policy configuration.
4018
+ * Modifies allowed, restricted, and monitored license types.
4200
4019
  *
4201
4020
  * @throws {Error} When server returns 5xx status codes
4202
4021
  */
@@ -4209,7 +4028,7 @@ var SocketSdk = class {
4209
4028
  this.#baseUrl,
4210
4029
  `orgs/${encodeURIComponent(orgSlug)}/settings/license-policy?${queryToSearchParams(queryParams)}`,
4211
4030
  policyData,
4212
- { ...this.#reqOptions, hooks: this.#hooks }
4031
+ this.#reqOptionsWithHooks
4213
4032
  )
4214
4033
  )
4215
4034
  );
@@ -4219,7 +4038,8 @@ var SocketSdk = class {
4219
4038
  }
4220
4039
  }
4221
4040
  /**
4222
- * Update organization's security policy configuration.* Modifies alert rules, severity thresholds, and enforcement settings.
4041
+ * Update organization's security policy configuration.
4042
+ * Modifies alert rules, severity thresholds, and enforcement settings.
4223
4043
  *
4224
4044
  * @throws {Error} When server returns 5xx status codes
4225
4045
  */
@@ -4232,7 +4052,7 @@ var SocketSdk = class {
4232
4052
  this.#baseUrl,
4233
4053
  `orgs/${encodeURIComponent(orgSlug)}/settings/security-policy`,
4234
4054
  policyData,
4235
- { ...this.#reqOptions, hooks: this.#hooks }
4055
+ this.#reqOptionsWithHooks
4236
4056
  )
4237
4057
  )
4238
4058
  );
@@ -4260,7 +4080,7 @@ var SocketSdk = class {
4260
4080
  this.#baseUrl,
4261
4081
  `orgs/${encodeURIComponent(orgSlug)}/telemetry/config`,
4262
4082
  telemetryData,
4263
- { ...this.#reqOptions, hooks: this.#hooks }
4083
+ this.#reqOptionsWithHooks
4264
4084
  )
4265
4085
  )
4266
4086
  );
@@ -4289,7 +4109,7 @@ var SocketSdk = class {
4289
4109
  this.#baseUrl,
4290
4110
  `orgs/${encodeURIComponent(orgSlug)}/webhooks/${encodeURIComponent(webhookId)}`,
4291
4111
  webhookData,
4292
- { ...this.#reqOptions, hooks: this.#hooks }
4112
+ this.#reqOptionsWithHooks
4293
4113
  )
4294
4114
  )
4295
4115
  );
@@ -4341,7 +4161,7 @@ var SocketSdk = class {
4341
4161
  this.#baseUrl,
4342
4162
  `orgs/${encodeURIComponent(orgSlug)}/repos/${encodeURIComponent(repoSlug)}${queryString}`,
4343
4163
  params,
4344
- { ...this.#reqOptions, hooks: this.#hooks }
4164
+ this.#reqOptionsWithHooks
4345
4165
  )
4346
4166
  )
4347
4167
  );
@@ -4398,7 +4218,7 @@ var SocketSdk = class {
4398
4218
  this.#baseUrl,
4399
4219
  `orgs/${encodeURIComponent(orgSlug)}/repos/labels/${encodeURIComponent(labelId)}`,
4400
4220
  labelData,
4401
- { ...this.#reqOptions, hooks: this.#hooks }
4221
+ this.#reqOptionsWithHooks
4402
4222
  )
4403
4223
  )
4404
4224
  );
@@ -4494,7 +4314,7 @@ var SocketSdk = class {
4494
4314
  this.#baseUrl,
4495
4315
  `orgs/${encodeURIComponent(orgSlug)}/upload-manifest-files`,
4496
4316
  createRequestBodyForFilepaths(validPaths, basePath),
4497
- { ...this.#reqOptions, hooks: this.#hooks }
4317
+ this.#reqOptionsWithHooks
4498
4318
  )
4499
4319
  )
4500
4320
  );
@@ -4514,55 +4334,39 @@ var SocketSdk = class {
4514
4334
  * vulnerabilities, description, license, and tier information.
4515
4335
  */
4516
4336
  async viewPatch(orgSlug, uuid) {
4517
- const data = await getResponseJson(
4518
- await createGetRequest(
4519
- this.#baseUrl,
4520
- `orgs/${encodeURIComponent(orgSlug)}/patches/view/${encodeURIComponent(uuid)}`,
4521
- { ...this.#reqOptions, hooks: this.#hooks }
4522
- )
4523
- );
4524
- return data;
4337
+ try {
4338
+ const data = await this.#executeWithRetry(
4339
+ async () => await getResponseJson(
4340
+ await createGetRequest(
4341
+ this.#baseUrl,
4342
+ `orgs/${encodeURIComponent(orgSlug)}/patches/view/${encodeURIComponent(uuid)}`,
4343
+ this.#reqOptionsWithHooks
4344
+ )
4345
+ )
4346
+ );
4347
+ return data;
4348
+ } catch (e) {
4349
+ const result = await this.#handleApiError(e);
4350
+ throw new Error(result.error, { cause: result.cause });
4351
+ }
4525
4352
  }
4526
4353
  };
4527
4354
  if ((0, import_debug2.isDebugNs)("heap")) {
4528
- const used = process.memoryUsage();
4355
+ const used = import_node_process2.default.memoryUsage();
4529
4356
  (0, import_debug2.debugLog)("heap", `heap used: ${Math.round(used.heapUsed / 1024 / 1024)}MB`);
4530
4357
  }
4531
4358
  // Annotate the CommonJS export names for ESM import in node:
4532
4359
  0 && (module.exports = {
4533
- DEFAULT_USER_AGENT,
4534
4360
  ResponseError,
4535
4361
  SocketSdk,
4536
4362
  calculateTotalQuotaCost,
4537
- calculateWordSetSimilarity,
4538
- createDeleteRequest,
4539
- createGetRequest,
4540
- createRequestBodyForFilepaths,
4541
- createRequestBodyForJson,
4542
- createRequestWithJson,
4543
- createUploadRequest,
4544
4363
  createUserAgentFromPkgJson,
4545
- filterRedundantCause,
4546
4364
  getAllMethodRequirements,
4547
- getErrorResponseBody,
4548
- getHttpModule,
4549
4365
  getMethodRequirements,
4550
4366
  getMethodsByPermissions,
4551
4367
  getMethodsByQuotaCost,
4552
4368
  getQuotaCost,
4553
4369
  getQuotaUsageSummary,
4554
4370
  getRequiredPermissions,
4555
- getResponse,
4556
- getResponseJson,
4557
- hasQuotaForMethods,
4558
- httpAgentNames,
4559
- isResponseOk,
4560
- normalizeBaseUrl,
4561
- promiseWithResolvers,
4562
- publicPolicy,
4563
- queryToSearchParams,
4564
- reshapeArtifactForPublicPolicy,
4565
- resolveAbsPaths,
4566
- resolveBasePath,
4567
- shouldOmitReason
4371
+ hasQuotaForMethods
4568
4372
  });