@socketsecurity/sdk 3.3.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -71,8 +71,8 @@ module.exports = __toCommonJS(index_exports);
71
71
  // package.json
72
72
  var package_default = {
73
73
  name: "@socketsecurity/sdk",
74
- version: "3.3.0",
75
- packageManager: "pnpm@10.28.1",
74
+ version: "3.3.1",
75
+ packageManager: "pnpm@10.30.3",
76
76
  license: "MIT",
77
77
  description: "SDK for the Socket API client",
78
78
  author: {
@@ -128,7 +128,7 @@ var package_default = {
128
128
  },
129
129
  dependencies: {
130
130
  "@socketregistry/packageurl-js": "1.3.5",
131
- "@socketsecurity/lib": "5.5.3",
131
+ "@socketsecurity/lib": "5.7.0",
132
132
  "form-data": "4.0.5"
133
133
  },
134
134
  devDependencies: {
@@ -137,14 +137,14 @@ var package_default = {
137
137
  "@babel/traverse": "7.26.4",
138
138
  "@babel/types": "7.26.3",
139
139
  "@biomejs/biome": "2.2.4",
140
- "@dotenvx/dotenvx": "^1.51.4",
140
+ "@dotenvx/dotenvx": "^1.52.0",
141
141
  "@eslint/compat": "1.3.2",
142
142
  "@eslint/js": "9.35.0",
143
+ "@sveltejs/acorn-typescript": "1.0.8",
143
144
  "@types/babel__traverse": "7.28.0",
144
145
  "@types/node": "24.9.2",
145
146
  "@typescript/native-preview": "7.0.0-dev.20250926.1",
146
147
  "@vitest/coverage-v8": "4.0.3",
147
- "@sveltejs/acorn-typescript": "1.0.8",
148
148
  acorn: "8.15.0",
149
149
  del: "8.0.1",
150
150
  "dev-null-cli": "2.0.0",
@@ -167,8 +167,7 @@ var package_default = {
167
167
  taze: "19.9.2",
168
168
  "type-coverage": "2.29.7",
169
169
  "typescript-eslint": "8.44.1",
170
- vitest: "4.0.3",
171
- "yoctocolors-cjs": "2.1.3"
170
+ vitest: "4.0.3"
172
171
  },
173
172
  pnpm: {
174
173
  ignoredBuiltDependencies: [
@@ -468,11 +467,12 @@ function sanitizeHeaders(headers) {
468
467
  // src/http-client.ts
469
468
  var ResponseError = class _ResponseError extends Error {
470
469
  response;
470
+ url;
471
471
  /**
472
472
  * Create a new ResponseError from an HTTP response.
473
473
  * Automatically formats error message with status code and message.
474
474
  */
475
- constructor(response, message = "") {
475
+ constructor(response, message = "", url) {
476
476
  const statusCode = response.statusCode ?? "unknown";
477
477
  const statusMessage = response.statusMessage ?? "No status message";
478
478
  super(
@@ -481,6 +481,7 @@ var ResponseError = class _ResponseError extends Error {
481
481
  );
482
482
  this.name = "ResponseError";
483
483
  this.response = response;
484
+ this.url = url;
484
485
  Error.captureStackTrace(this, _ResponseError);
485
486
  }
486
487
  };
@@ -627,10 +628,10 @@ async function getErrorResponseBody(response) {
627
628
  response.setEncoding("utf8");
628
629
  response.on("data", (chunk) => {
629
630
  const chunkBytes = Buffer.byteLength(chunk, "utf8");
630
- totalBytes += chunkBytes;
631
- if (totalBytes > MAX_RESPONSE_SIZE) {
631
+ if (totalBytes + chunkBytes > MAX_RESPONSE_SIZE) {
632
632
  response.destroy();
633
- const sizeMB = (totalBytes / (1024 * 1024)).toFixed(2);
633
+ const projectedSize = totalBytes + chunkBytes;
634
+ const sizeMB = (projectedSize / (1024 * 1024)).toFixed(2);
634
635
  const maxMB = (MAX_RESPONSE_SIZE / (1024 * 1024)).toFixed(2);
635
636
  const message = [
636
637
  `Response exceeds maximum size limit (${sizeMB}MB > ${maxMB}MB)`,
@@ -642,6 +643,7 @@ async function getErrorResponseBody(response) {
642
643
  reject(new Error(message));
643
644
  return;
644
645
  }
646
+ totalBytes += chunkBytes;
645
647
  body += chunk;
646
648
  });
647
649
  response.on("end", () => resolve(body));
@@ -731,13 +733,14 @@ async function getResponse(req) {
731
733
  });
732
734
  });
733
735
  }
734
- async function getResponseJson(response, method) {
736
+ async function getResponseJson(response, method, url) {
735
737
  const stopTimer = (0, import_performance.perfTimer)("http:parse-json");
736
738
  try {
737
739
  if (!isResponseOk(response)) {
738
740
  throw new ResponseError(
739
741
  response,
740
- method ? `${method} Request failed` : void 0
742
+ method ? `${method} Request failed` : void 0,
743
+ url
741
744
  );
742
745
  }
743
746
  const responseBody = await getErrorResponseBody(response);
@@ -809,7 +812,7 @@ function isResponseOk(response) {
809
812
  }
810
813
  function reshapeArtifactForPublicPolicy(data, isAuthenticated, actions) {
811
814
  if (!isAuthenticated) {
812
- const allowedActions = actions ? actions.split(",") : void 0;
815
+ const allowedActions = actions?.trim() ? actions.split(",") : void 0;
813
816
  const reshapeArtifact = (artifact) => ({
814
817
  name: artifact.name,
815
818
  version: artifact.version,
@@ -923,7 +926,7 @@ async function createUploadRequest(baseUrl, urlPath, form, options) {
923
926
  timeout: opts.timeout
924
927
  });
925
928
  req.flushHeaders();
926
- getResponse(req).then(
929
+ void getResponse(req).then(
927
930
  (response) => {
928
931
  hooks?.onResponse?.({
929
932
  method,
@@ -947,7 +950,6 @@ async function createUploadRequest(baseUrl, urlPath, form, options) {
947
950
  );
948
951
  form.pipe(req);
949
952
  form.on("error", fail);
950
- req.on("error", fail);
951
953
  });
952
954
  }
953
955
 
@@ -1124,7 +1126,7 @@ var SocketSdk = class {
1124
1126
  userAgent
1125
1127
  } = { __proto__: null, ...options };
1126
1128
  if (timeout !== void 0) {
1127
- if (typeof timeout !== "number" || timeout < MIN_HTTP_TIMEOUT || timeout > MAX_HTTP_TIMEOUT) {
1129
+ if (typeof timeout !== "number" || Number.isNaN(timeout) || timeout < MIN_HTTP_TIMEOUT || timeout > MAX_HTTP_TIMEOUT) {
1128
1130
  throw new TypeError(
1129
1131
  `"timeout" must be a number between ${MIN_HTTP_TIMEOUT} and ${MAX_HTTP_TIMEOUT} milliseconds`
1130
1132
  );
@@ -1187,22 +1189,26 @@ var SocketSdk = class {
1187
1189
  signal: abortSignal
1188
1190
  });
1189
1191
  const isPublicToken = this.#apiToken === import_socket2.SOCKET_PUBLIC_API_TOKEN;
1190
- for await (const line of rli) {
1191
- const trimmed = line.trim();
1192
- const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1193
- /* c8 ignore next - Empty line handling in batch streaming response parsing. */
1194
- null
1195
- );
1196
- if ((0, import_objects.isObjectObject)(artifact)) {
1197
- yield this.#handleApiSuccess(
1198
- /* c8 ignore next 7 - Public token artifact reshaping branch for policy compliance. */
1199
- isPublicToken ? reshapeArtifactForPublicPolicy(
1200
- artifact,
1201
- false,
1202
- queryParams?.["actions"]
1203
- ) : artifact
1192
+ try {
1193
+ for await (const line of rli) {
1194
+ const trimmed = line.trim();
1195
+ const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1196
+ /* c8 ignore next - Empty line handling in batch streaming response parsing. */
1197
+ null
1204
1198
  );
1199
+ if ((0, import_objects.isObjectObject)(artifact)) {
1200
+ yield this.#handleApiSuccess(
1201
+ /* c8 ignore next 7 - Public token artifact reshaping branch for policy compliance. */
1202
+ isPublicToken ? reshapeArtifactForPublicPolicy(
1203
+ artifact,
1204
+ false,
1205
+ queryParams?.["actions"]
1206
+ ) : artifact
1207
+ );
1208
+ }
1205
1209
  }
1210
+ } finally {
1211
+ rli.close();
1206
1212
  }
1207
1213
  }
1208
1214
  /**
@@ -1210,13 +1216,14 @@ var SocketSdk = class {
1210
1216
  * Internal method for handling PURL batch API calls with retry logic.
1211
1217
  */
1212
1218
  async #createBatchPurlRequest(componentsObj, queryParams) {
1213
- const req = getHttpModule(this.#baseUrl).request(`${this.#baseUrl}purl?${queryToSearchParams(queryParams)}`, {
1219
+ const url = `${this.#baseUrl}purl?${queryToSearchParams(queryParams)}`;
1220
+ const req = getHttpModule(this.#baseUrl).request(url, {
1214
1221
  method: "POST",
1215
1222
  ...this.#reqOptions
1216
1223
  }).end(JSON.stringify(componentsObj));
1217
1224
  const response = await getResponse(req);
1218
1225
  if (!isResponseOk(response)) {
1219
- throw new ResponseError(response);
1226
+ throw new ResponseError(response, "", url);
1220
1227
  }
1221
1228
  return response;
1222
1229
  }
@@ -1450,7 +1457,8 @@ var SocketSdk = class {
1450
1457
  error: errorMessage,
1451
1458
  /* c8 ignore next - fallback for missing status code in edge cases. */
1452
1459
  status: statusCode ?? 0,
1453
- success: false
1460
+ success: false,
1461
+ url: error.url
1454
1462
  };
1455
1463
  }
1456
1464
  /**
@@ -1543,18 +1551,16 @@ var SocketSdk = class {
1543
1551
  * @throws {Error} When server returns 5xx status codes
1544
1552
  */
1545
1553
  async batchOrgPackageFetch(orgSlug, componentsObj, queryParams) {
1554
+ const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/purl?${queryToSearchParams(queryParams)}`;
1546
1555
  let res;
1547
1556
  try {
1548
- const req = getHttpModule(this.#baseUrl).request(
1549
- `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/purl?${queryToSearchParams(queryParams)}`,
1550
- {
1551
- method: "POST",
1552
- ...this.#reqOptions
1553
- }
1554
- ).end(JSON.stringify(componentsObj));
1557
+ const req = getHttpModule(this.#baseUrl).request(url, {
1558
+ method: "POST",
1559
+ ...this.#reqOptions
1560
+ }).end(JSON.stringify(componentsObj));
1555
1561
  res = await getResponse(req);
1556
1562
  if (!isResponseOk(res)) {
1557
- throw new ResponseError(res);
1563
+ throw new ResponseError(res, "", url);
1558
1564
  }
1559
1565
  } catch (e) {
1560
1566
  return await this.#handleApiError(e);
@@ -1568,15 +1574,19 @@ var SocketSdk = class {
1568
1574
  signal: abortSignal
1569
1575
  });
1570
1576
  const results = [];
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);
1577
+ try {
1578
+ for await (const line of rli) {
1579
+ const trimmed = line.trim();
1580
+ const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1581
+ /* c8 ignore next - Empty line handling in batch parsing. */
1582
+ null
1583
+ );
1584
+ if ((0, import_objects.isObjectObject)(artifact)) {
1585
+ results.push(artifact);
1586
+ }
1579
1587
  }
1588
+ } finally {
1589
+ rli.close();
1580
1590
  }
1581
1591
  const compact = (0, import_url.urlSearchParamAsBoolean)(
1582
1592
  (0, import_objects.getOwn)(queryParams, "compact")
@@ -1608,22 +1618,26 @@ var SocketSdk = class {
1608
1618
  });
1609
1619
  const isPublicToken = this.#apiToken === import_socket2.SOCKET_PUBLIC_API_TOKEN;
1610
1620
  const results = [];
1611
- for await (const line of rli) {
1612
- const trimmed = line.trim();
1613
- const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1614
- /* c8 ignore next - Empty line handling in batch parsing. */
1615
- null
1616
- );
1617
- if ((0, import_objects.isObjectObject)(artifact)) {
1618
- results.push(
1619
- /* c8 ignore next 7 - Public token artifact reshaping for policy compliance. */
1620
- isPublicToken ? reshapeArtifactForPublicPolicy(
1621
- artifact,
1622
- false,
1623
- queryParams?.["actions"]
1624
- ) : artifact
1621
+ try {
1622
+ for await (const line of rli) {
1623
+ const trimmed = line.trim();
1624
+ const artifact = trimmed ? (0, import_parse2.jsonParse)(line, { throws: false }) : (
1625
+ /* c8 ignore next - Empty line handling in batch parsing. */
1626
+ null
1625
1627
  );
1628
+ if ((0, import_objects.isObjectObject)(artifact)) {
1629
+ results.push(
1630
+ /* c8 ignore next 7 - Public token artifact reshaping for policy compliance. */
1631
+ isPublicToken ? reshapeArtifactForPublicPolicy(
1632
+ artifact,
1633
+ false,
1634
+ queryParams?.["actions"]
1635
+ ) : artifact
1636
+ );
1637
+ }
1626
1638
  }
1639
+ } finally {
1640
+ rli.close();
1627
1641
  }
1628
1642
  const compact = (0, import_url.urlSearchParamAsBoolean)(
1629
1643
  (0, import_objects.getOwn)(queryParams, "compact")
@@ -1689,11 +1703,13 @@ var SocketSdk = class {
1689
1703
  const { generator, iteratorResult } = await Promise.race(
1690
1704
  running.map((entry) => entry.promise)
1691
1705
  );
1692
- const index2 = running.findIndex((entry) => entry.generator === generator);
1693
- if (index2 === -1) {
1706
+ const runningIndex = running.findIndex(
1707
+ (entry) => entry.generator === generator
1708
+ );
1709
+ if (runningIndex === -1) {
1694
1710
  continue;
1695
1711
  }
1696
- running.splice(index2, 1);
1712
+ running.splice(runningIndex, 1);
1697
1713
  if (iteratorResult.value) {
1698
1714
  yield iteratorResult.value;
1699
1715
  }
@@ -1819,7 +1835,7 @@ var SocketSdk = class {
1819
1835
  *
1820
1836
  * @see https://docs.socket.dev/reference/createorgfullscan
1821
1837
  * @apiEndpoint POST /orgs/{org_slug}/full-scans
1822
- * @quota 1 unit
1838
+ * @quota 0 units
1823
1839
  * @scopes full-scans:create
1824
1840
  * @throws {Error} When server returns 5xx status codes
1825
1841
  */
@@ -1918,16 +1934,43 @@ var SocketSdk = class {
1918
1934
  * Create a diff scan from two full scan IDs.
1919
1935
  * Compares two existing full scans to identify changes.
1920
1936
  *
1937
+ * @param orgSlug - Organization identifier
1938
+ * @param options - Diff scan creation options
1939
+ * @param options.after - ID of the after/head full scan (newer)
1940
+ * @param options.before - ID of the before/base full scan (older)
1941
+ * @param options.description - Description of the diff scan
1942
+ * @param options.external_href - External URL to associate with the diff scan
1943
+ * @param options.merge - Set true for merged commits, false for open PR diffs
1944
+ * @returns Diff scan details
1945
+ *
1946
+ * @example
1947
+ * ```typescript
1948
+ * const result = await sdk.createOrgDiffScanFromIds('my-org', {
1949
+ * before: 'scan-id-1',
1950
+ * after: 'scan-id-2',
1951
+ * description: 'Compare versions',
1952
+ * merge: false
1953
+ * })
1954
+ *
1955
+ * if (result.success) {
1956
+ * console.log('Diff scan created:', result.data.diff_scan.id)
1957
+ * }
1958
+ * ```
1959
+ *
1960
+ * @see https://docs.socket.dev/reference/createorgdiffscanfromids
1961
+ * @apiEndpoint POST /orgs/{org_slug}/diff-scans/from-ids
1962
+ * @quota 0 units
1963
+ * @scopes diff-scans:create, full-scans:list
1921
1964
  * @throws {Error} When server returns 5xx status codes
1922
1965
  */
1923
- async createOrgDiffScanFromIds(orgSlug, queryParams) {
1966
+ async createOrgDiffScanFromIds(orgSlug, options) {
1924
1967
  try {
1925
1968
  const data = await this.#executeWithRetry(
1926
1969
  async () => await getResponseJson(
1927
1970
  await createRequestWithJson(
1928
1971
  "POST",
1929
1972
  this.#baseUrl,
1930
- `orgs/${encodeURIComponent(orgSlug)}/diff-scans?${queryToSearchParams(queryParams)}`,
1973
+ `orgs/${encodeURIComponent(orgSlug)}/diff-scans/from-ids?${queryToSearchParams(options)}`,
1931
1974
  {},
1932
1975
  { ...this.#reqOptions, hooks: this.#hooks }
1933
1976
  )
@@ -2001,15 +2044,22 @@ var SocketSdk = class {
2001
2044
  * Registers a repository for monitoring and security scanning.
2002
2045
  *
2003
2046
  * @param orgSlug - Organization identifier
2004
- * @param params - Repository configuration (name, description, homepage, etc.)
2047
+ * @param repoSlug - Repository name/slug
2048
+ * @param params - Additional repository configuration
2049
+ * @param params.archived - Whether the repository is archived
2050
+ * @param params.default_branch - Default branch of the repository
2051
+ * @param params.description - Description of the repository
2052
+ * @param params.homepage - Homepage URL of the repository
2053
+ * @param params.visibility - Visibility setting ('public' or 'private')
2054
+ * @param params.workspace - Workspace of the repository
2005
2055
  * @returns Created repository details
2006
2056
  *
2007
2057
  * @example
2008
2058
  * ```typescript
2009
- * const result = await sdk.createRepository('my-org', {
2010
- * name: 'my-repo',
2059
+ * const result = await sdk.createRepository('my-org', 'my-repo', {
2011
2060
  * description: 'My project repository',
2012
- * homepage: 'https://example.com'
2061
+ * homepage: 'https://example.com',
2062
+ * visibility: 'private'
2013
2063
  * })
2014
2064
  *
2015
2065
  * if (result.success) {
@@ -2019,11 +2069,11 @@ var SocketSdk = class {
2019
2069
  *
2020
2070
  * @see https://docs.socket.dev/reference/createorgrepo
2021
2071
  * @apiEndpoint POST /orgs/{org_slug}/repos
2022
- * @quota 1 unit
2072
+ * @quota 0 units
2023
2073
  * @scopes repo:write
2024
2074
  * @throws {Error} When server returns 5xx status codes
2025
2075
  */
2026
- async createRepository(orgSlug, params) {
2076
+ async createRepository(orgSlug, repoSlug, params) {
2027
2077
  try {
2028
2078
  const data = await this.#executeWithRetry(
2029
2079
  async () => await getResponseJson(
@@ -2031,7 +2081,7 @@ var SocketSdk = class {
2031
2081
  "POST",
2032
2082
  this.#baseUrl,
2033
2083
  `orgs/${encodeURIComponent(orgSlug)}/repos`,
2034
- params,
2084
+ { ...params, name: repoSlug },
2035
2085
  { ...this.#reqOptions, hooks: this.#hooks }
2036
2086
  )
2037
2087
  )
@@ -2075,7 +2125,7 @@ var SocketSdk = class {
2075
2125
  *
2076
2126
  * @see https://docs.socket.dev/reference/createorgrepolabel
2077
2127
  * @apiEndpoint POST /orgs/{org_slug}/repos/labels
2078
- * @quota 1 unit
2128
+ * @quota 0 units
2079
2129
  * @scopes repo-label:create
2080
2130
  * @throws {Error} When server returns 5xx status codes
2081
2131
  */
@@ -2130,7 +2180,7 @@ var SocketSdk = class {
2130
2180
  *
2131
2181
  * @see https://docs.socket.dev/reference/deleteorgfullscan
2132
2182
  * @apiEndpoint DELETE /orgs/{org_slug}/full-scans/{full_scan_id}
2133
- * @quota 1 unit
2183
+ * @quota 0 units
2134
2184
  * @scopes full-scans:delete
2135
2185
  * @throws {Error} When server returns 5xx status codes
2136
2186
  */
@@ -2232,7 +2282,7 @@ var SocketSdk = class {
2232
2282
  *
2233
2283
  * @see https://docs.socket.dev/reference/deleteorgrepo
2234
2284
  * @apiEndpoint DELETE /orgs/{org_slug}/repos/{repo_slug}
2235
- * @quota 1 unit
2285
+ * @quota 0 units
2236
2286
  * @scopes repo:write
2237
2287
  * @throws {Error} When server returns 5xx status codes
2238
2288
  */
@@ -2290,7 +2340,7 @@ var SocketSdk = class {
2290
2340
  *
2291
2341
  * @see https://docs.socket.dev/reference/deleteorgrepolabel
2292
2342
  * @apiEndpoint DELETE /orgs/{org_slug}/repos/labels/{label_id}
2293
- * @quota 1 unit
2343
+ * @quota 0 units
2294
2344
  * @scopes repo-label:delete
2295
2345
  * @throws {Error} When server returns 5xx status codes
2296
2346
  */
@@ -2349,35 +2399,33 @@ var SocketSdk = class {
2349
2399
  * ```
2350
2400
  */
2351
2401
  async downloadOrgFullScanFilesAsTar(orgSlug, fullScanId, outputPath) {
2402
+ const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/files.tar`;
2352
2403
  try {
2353
- const req = getHttpModule(this.#baseUrl).request(
2354
- `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(fullScanId)}/files.tar`,
2355
- {
2356
- method: "GET",
2357
- ...this.#reqOptions
2358
- }
2359
- ).end();
2404
+ const req = getHttpModule(this.#baseUrl).request(url, {
2405
+ method: "GET",
2406
+ ...this.#reqOptions
2407
+ }).end();
2360
2408
  const res = await getResponse(req);
2361
2409
  if (!isResponseOk(res)) {
2362
- throw new ResponseError(res);
2410
+ throw new ResponseError(res, "", url);
2363
2411
  }
2364
2412
  const writeStream = (0, import_node_fs3.createWriteStream)(outputPath);
2365
2413
  let bytesWritten = 0;
2366
2414
  res.on("data", (chunk) => {
2367
- bytesWritten += chunk.length;
2368
- if (bytesWritten > MAX_STREAM_SIZE) {
2369
- res.destroy();
2370
- writeStream.destroy();
2371
- throw new Error(
2415
+ if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
2416
+ const error = new Error(
2372
2417
  `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
2373
2418
  );
2419
+ res.destroy(error);
2420
+ writeStream.destroy(error);
2421
+ return;
2374
2422
  }
2423
+ bytesWritten += chunk.length;
2375
2424
  });
2376
2425
  res.pipe(writeStream);
2377
2426
  writeStream.on("error", (error) => {
2378
- throw new Error(`Failed to write to file: ${outputPath}`, {
2379
- cause: error
2380
- });
2427
+ res.destroy();
2428
+ writeStream.destroy(error);
2381
2429
  });
2382
2430
  await import_node_events.default.once(writeStream, "finish");
2383
2431
  return this.#handleApiSuccess(res);
@@ -2440,8 +2488,23 @@ var SocketSdk = class {
2440
2488
  return;
2441
2489
  }
2442
2490
  let data = "";
2491
+ let bytesRead = 0;
2492
+ const MAX_PATCH_SIZE = 50 * 1024 * 1024;
2443
2493
  res.on("data", (chunk) => {
2444
- data += chunk;
2494
+ if (bytesRead + chunk.length > MAX_PATCH_SIZE) {
2495
+ const error = new Error(
2496
+ [
2497
+ `Patch file exceeds maximum size of ${MAX_PATCH_SIZE} bytes`,
2498
+ `\u2192 Current size: ${bytesRead + chunk.length} bytes`,
2499
+ "\u2192 This may indicate an incorrect hash or corrupted blob."
2500
+ ].join("\n")
2501
+ );
2502
+ res.destroy(error);
2503
+ reject(error);
2504
+ return;
2505
+ }
2506
+ bytesRead += chunk.length;
2507
+ data += chunk.toString("utf8");
2445
2508
  });
2446
2509
  res.on("end", () => {
2447
2510
  resolve(data);
@@ -2524,7 +2587,7 @@ var SocketSdk = class {
2524
2587
  *
2525
2588
  * @see https://docs.socket.dev/reference/exportopenvex
2526
2589
  * @apiEndpoint GET /orgs/{org_slug}/export/openvex/{id}
2527
- * @quota 1 unit
2590
+ * @quota 0 units
2528
2591
  * @scopes report:read
2529
2592
  * @throws {Error} When server returns 5xx status codes
2530
2593
  */
@@ -2579,6 +2642,7 @@ var SocketSdk = class {
2579
2642
  __proto__: null,
2580
2643
  ...options
2581
2644
  };
2645
+ const url = `${this.#baseUrl}${urlPath}`;
2582
2646
  try {
2583
2647
  const response = await createGetRequest(this.#baseUrl, urlPath, {
2584
2648
  ...this.#reqOptions,
@@ -2586,17 +2650,18 @@ var SocketSdk = class {
2586
2650
  });
2587
2651
  if (!isResponseOk(response)) {
2588
2652
  if (throws) {
2589
- throw new ResponseError(response);
2653
+ throw new ResponseError(response, "", url);
2590
2654
  }
2591
2655
  const errorResult = await this.#handleApiError(
2592
- new ResponseError(response)
2656
+ new ResponseError(response, "", url)
2593
2657
  );
2594
2658
  return {
2595
2659
  cause: errorResult.cause,
2596
2660
  data: void 0,
2597
2661
  error: errorResult.error,
2598
2662
  status: errorResult.status,
2599
- success: false
2663
+ success: false,
2664
+ url: errorResult.url
2600
2665
  };
2601
2666
  }
2602
2667
  const data = await this.#handleQueryResponseData(
@@ -2697,6 +2762,48 @@ var SocketSdk = class {
2697
2762
  return await this.#handleApiError(e);
2698
2763
  }
2699
2764
  }
2765
+ /**
2766
+ * Get GitHub-flavored markdown comments for a diff scan.
2767
+ * Returns dependency overview and alert comments suitable for pull requests.
2768
+ *
2769
+ * @param orgSlug - Organization identifier
2770
+ * @param diffScanId - Diff scan identifier
2771
+ * @param options - Optional query parameters
2772
+ * @param options.github_installation_id - GitHub installation ID for settings
2773
+ * @returns Diff scan metadata with formatted markdown comments
2774
+ *
2775
+ * @example
2776
+ * ```typescript
2777
+ * const result = await sdk.getDiffScanGfm('my-org', 'diff-scan-id')
2778
+ *
2779
+ * if (result.success) {
2780
+ * console.log(result.data.dependency_overview_comment)
2781
+ * console.log(result.data.dependency_alert_comment)
2782
+ * }
2783
+ * ```
2784
+ *
2785
+ * @see https://docs.socket.dev/reference/getdiffscangfm
2786
+ * @apiEndpoint GET /orgs/{org_slug}/diff-scans/{diff_scan_id}/gfm
2787
+ * @quota 0 units
2788
+ * @scopes diff-scans:list
2789
+ * @throws {Error} When server returns 5xx status codes
2790
+ */
2791
+ async getDiffScanGfm(orgSlug, diffScanId, options) {
2792
+ try {
2793
+ const data = await this.#executeWithRetry(
2794
+ async () => await getResponseJson(
2795
+ await createGetRequest(
2796
+ this.#baseUrl,
2797
+ `orgs/${encodeURIComponent(orgSlug)}/diff-scans/${encodeURIComponent(diffScanId)}/gfm${options ? `?${queryToSearchParams(options)}` : ""}`,
2798
+ { ...this.#reqOptions, hooks: this.#hooks }
2799
+ )
2800
+ )
2801
+ );
2802
+ return this.#handleApiSuccess(data);
2803
+ } catch (e) {
2804
+ return await this.#handleApiError(e);
2805
+ }
2806
+ }
2700
2807
  /**
2701
2808
  * Retrieve the enabled entitlements for an organization.
2702
2809
  *
@@ -2756,7 +2863,7 @@ var SocketSdk = class {
2756
2863
  *
2757
2864
  * @see https://docs.socket.dev/reference/getorgfullscan
2758
2865
  * @apiEndpoint GET /orgs/{org_slug}/full-scans/{full_scan_id}
2759
- * @quota 1 unit
2866
+ * @quota 0 units
2760
2867
  * @scopes full-scans:list
2761
2868
  * @throws {Error} When server returns 5xx status codes
2762
2869
  */
@@ -2811,7 +2918,7 @@ var SocketSdk = class {
2811
2918
  *
2812
2919
  * @see https://docs.socket.dev/reference/getorgfullscanmetadata
2813
2920
  * @apiEndpoint GET /orgs/{org_slug}/full-scans/{full_scan_id}/metadata
2814
- * @quota 1 unit
2921
+ * @quota 0 units
2815
2922
  * @scopes full-scans:list
2816
2923
  * @throws {Error} When server returns 5xx status codes
2817
2924
  */
@@ -3198,7 +3305,7 @@ var SocketSdk = class {
3198
3305
  *
3199
3306
  * @see https://docs.socket.dev/reference/getorgrepo
3200
3307
  * @apiEndpoint GET /orgs/{org_slug}/repos/{repo_slug}
3201
- * @quota 1 unit
3308
+ * @quota 0 units
3202
3309
  * @scopes repo:read
3203
3310
  * @throws {Error} When server returns 5xx status codes
3204
3311
  */
@@ -3260,7 +3367,7 @@ var SocketSdk = class {
3260
3367
  *
3261
3368
  * @see https://docs.socket.dev/reference/getorgrepolabel
3262
3369
  * @apiEndpoint GET /orgs/{org_slug}/repos/labels/{label_id}
3263
- * @quota 1 unit
3370
+ * @quota 0 units
3264
3371
  * @scopes repo-label:list
3265
3372
  * @throws {Error} When server returns 5xx status codes
3266
3373
  */
@@ -3315,10 +3422,57 @@ var SocketSdk = class {
3315
3422
  return await this.#handleApiError(e);
3316
3423
  }
3317
3424
  }
3425
+ /**
3426
+ * Get list of supported file types for full scan generation.
3427
+ * Returns glob patterns for supported manifest files, lockfiles, and configuration formats.
3428
+ *
3429
+ * Files whose names match the patterns returned by this endpoint can be uploaded
3430
+ * for report generation. Examples include `package.json`, `package-lock.json`, and `yarn.lock`.
3431
+ *
3432
+ * @param orgSlug - Organization identifier
3433
+ * @returns Nested object with environment and file type patterns
3434
+ *
3435
+ * @example
3436
+ * ```typescript
3437
+ * const result = await sdk.getSupportedFiles('my-org')
3438
+ *
3439
+ * if (result.success) {
3440
+ * console.log('NPM patterns:', result.data.NPM)
3441
+ * console.log('PyPI patterns:', result.data.PyPI)
3442
+ * }
3443
+ * ```
3444
+ *
3445
+ * @see https://docs.socket.dev/reference/getsupportedfiles
3446
+ * @apiEndpoint GET /orgs/{org_slug}/supported-files
3447
+ * @quota 0 units
3448
+ * @scopes No scopes required, but authentication is required
3449
+ * @throws {Error} When server returns 5xx status codes
3450
+ */
3451
+ async getSupportedFiles(orgSlug) {
3452
+ try {
3453
+ const data = await this.#executeWithRetry(
3454
+ async () => await getResponseJson(
3455
+ await createGetRequest(
3456
+ this.#baseUrl,
3457
+ `orgs/${encodeURIComponent(orgSlug)}/supported-files`,
3458
+ {
3459
+ ...this.#reqOptions,
3460
+ hooks: this.#hooks
3461
+ }
3462
+ )
3463
+ )
3464
+ );
3465
+ return this.#handleApiSuccess(data);
3466
+ } catch (e) {
3467
+ return await this.#handleApiError(e);
3468
+ }
3469
+ }
3318
3470
  /**
3319
3471
  * Get list of file types and formats supported for scanning.
3320
3472
  * Returns supported manifest files, lockfiles, and configuration formats.
3321
3473
  *
3474
+ * @deprecated Use getSupportedFiles() instead. This endpoint has been deprecated
3475
+ * since 2023-01-15 and now uses the /report/supported endpoint.
3322
3476
  * @throws {Error} When server returns 5xx status codes
3323
3477
  */
3324
3478
  async getSupportedScanFiles() {
@@ -3363,7 +3517,7 @@ var SocketSdk = class {
3363
3517
  *
3364
3518
  * @see https://docs.socket.dev/reference/getorgfullscanlist
3365
3519
  * @apiEndpoint GET /orgs/{org_slug}/full-scans
3366
- * @quota 1 unit
3520
+ * @quota 0 units
3367
3521
  * @scopes full-scans:list
3368
3522
  * @throws {Error} When server returns 5xx status codes
3369
3523
  */
@@ -3416,7 +3570,7 @@ var SocketSdk = class {
3416
3570
  *
3417
3571
  * @see https://docs.socket.dev/reference/getorganizations
3418
3572
  * @apiEndpoint GET /organizations
3419
- * @quota 1 unit
3573
+ * @quota 0 units
3420
3574
  * @throws {Error} When server returns 5xx status codes
3421
3575
  */
3422
3576
  async listOrganizations() {
@@ -3497,7 +3651,7 @@ var SocketSdk = class {
3497
3651
  *
3498
3652
  * @see https://docs.socket.dev/reference/getorgrepolist
3499
3653
  * @apiEndpoint GET /orgs/{org_slug}/repos
3500
- * @quota 1 unit
3654
+ * @quota 0 units
3501
3655
  * @scopes repo:list
3502
3656
  * @throws {Error} When server returns 5xx status codes
3503
3657
  */
@@ -3553,7 +3707,7 @@ var SocketSdk = class {
3553
3707
  *
3554
3708
  * @see https://docs.socket.dev/reference/getorgrepolabellist
3555
3709
  * @apiEndpoint GET /orgs/{org_slug}/repos/labels
3556
- * @quota 1 unit
3710
+ * @quota 0 units
3557
3711
  * @scopes repo-label:list
3558
3712
  * @throws {Error} When server returns 5xx status codes
3559
3713
  */
@@ -3769,7 +3923,7 @@ var SocketSdk = class {
3769
3923
  *
3770
3924
  * @see https://docs.socket.dev/reference/rescanorgfullscan
3771
3925
  * @apiEndpoint POST /orgs/{org_slug}/full-scans/{full_scan_id}/rescan
3772
- * @quota 1 unit
3926
+ * @quota 0 units
3773
3927
  * @scopes full-scans:create
3774
3928
  * @throws {Error} When server returns 5xx status codes
3775
3929
  */
@@ -3903,7 +4057,7 @@ var SocketSdk = class {
3903
4057
  *
3904
4058
  * @see https://docs.socket.dev/reference/getorgfullscan
3905
4059
  * @apiEndpoint GET /orgs/{org_slug}/full-scans/{full_scan_id}
3906
- * @quota 1 unit
4060
+ * @quota 0 units
3907
4061
  * @scopes full-scans:list
3908
4062
  * @throws {Error} When server returns 5xx status codes
3909
4063
  */
@@ -3912,51 +4066,59 @@ var SocketSdk = class {
3912
4066
  __proto__: null,
3913
4067
  ...options
3914
4068
  };
4069
+ const url = `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}`;
3915
4070
  try {
3916
- const req = getHttpModule(this.#baseUrl).request(
3917
- `${this.#baseUrl}orgs/${encodeURIComponent(orgSlug)}/full-scans/${encodeURIComponent(scanId)}`,
3918
- {
3919
- method: "GET",
3920
- ...this.#reqOptions
3921
- }
3922
- ).end();
4071
+ const req = getHttpModule(this.#baseUrl).request(url, {
4072
+ method: "GET",
4073
+ ...this.#reqOptions
4074
+ }).end();
3923
4075
  const res = await getResponse(req);
3924
4076
  if (!isResponseOk(res)) {
3925
- throw new ResponseError(res);
4077
+ throw new ResponseError(res, "", url);
3926
4078
  }
3927
4079
  if (typeof output === "string") {
3928
4080
  const writeStream = (0, import_node_fs3.createWriteStream)(output);
3929
4081
  let bytesWritten = 0;
3930
4082
  res.on("data", (chunk) => {
3931
- bytesWritten += chunk.length;
3932
- if (bytesWritten > MAX_STREAM_SIZE) {
3933
- res.destroy();
3934
- writeStream.destroy();
3935
- throw new Error(
4083
+ if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
4084
+ const error = new Error(
3936
4085
  `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
3937
4086
  );
4087
+ res.destroy(error);
4088
+ writeStream.destroy(error);
4089
+ return;
3938
4090
  }
4091
+ bytesWritten += chunk.length;
3939
4092
  });
3940
4093
  res.pipe(writeStream);
3941
4094
  writeStream.on("error", (error) => {
3942
- throw new Error(`Failed to write to file: ${output}`, {
3943
- cause: error
3944
- });
4095
+ res.destroy();
4096
+ writeStream.destroy(error);
3945
4097
  });
4098
+ await import_node_events.default.once(writeStream, "finish");
3946
4099
  } else if (output === true) {
3947
4100
  let bytesWritten = 0;
3948
4101
  res.on("data", (chunk) => {
3949
- bytesWritten += chunk.length;
3950
- if (bytesWritten > MAX_STREAM_SIZE) {
3951
- res.destroy();
3952
- throw new Error(
4102
+ if (bytesWritten + chunk.length > MAX_STREAM_SIZE) {
4103
+ const error = new Error(
3953
4104
  `Response exceeds maximum stream size of ${MAX_STREAM_SIZE} bytes`
3954
4105
  );
4106
+ res.destroy(error);
4107
+ return;
3955
4108
  }
4109
+ bytesWritten += chunk.length;
3956
4110
  });
4111
+ const stdoutErrorHandler = (_error) => {
4112
+ res.destroy();
4113
+ process.stdout.removeListener("error", stdoutErrorHandler);
4114
+ };
4115
+ process.stdout.on("error", stdoutErrorHandler);
3957
4116
  res.pipe(process.stdout);
3958
- process.stdout.on("error", (error) => {
3959
- throw new Error("Failed to write to stdout", { cause: error });
4117
+ res.on("end", () => {
4118
+ process.stdout.removeListener("error", stdoutErrorHandler);
4119
+ });
4120
+ res.on("error", () => {
4121
+ process.stdout.removeListener("error", stdoutErrorHandler);
3960
4122
  });
3961
4123
  }
3962
4124
  return this.#handleApiSuccess(res);
@@ -3973,15 +4135,16 @@ var SocketSdk = class {
3973
4135
  * Note: This method returns a ReadableStream for processing large datasets.
3974
4136
  */
3975
4137
  async streamPatchesFromScan(orgSlug, scanId) {
4138
+ const urlPath = `orgs/${encodeURIComponent(orgSlug)}/patches/scan?scan_id=${encodeURIComponent(scanId)}`;
4139
+ const url = `${this.#baseUrl}${urlPath}`;
3976
4140
  const response = await this.#executeWithRetry(
3977
- async () => await createGetRequest(
3978
- this.#baseUrl,
3979
- `orgs/${encodeURIComponent(orgSlug)}/patches/scan?scan_id=${encodeURIComponent(scanId)}`,
3980
- { ...this.#reqOptions, hooks: this.#hooks }
3981
- )
4141
+ async () => await createGetRequest(this.#baseUrl, urlPath, {
4142
+ ...this.#reqOptions,
4143
+ hooks: this.#hooks
4144
+ })
3982
4145
  );
3983
4146
  if (!isResponseOk(response)) {
3984
- throw new ResponseError(response, "GET Request failed");
4147
+ throw new ResponseError(response, "GET Request failed", url);
3985
4148
  }
3986
4149
  const rli = import_node_readline.default.createInterface({
3987
4150
  input: response,
@@ -4005,8 +4168,13 @@ var SocketSdk = class {
4005
4168
  } catch (error) {
4006
4169
  controller.error(error);
4007
4170
  } finally {
4171
+ rli.close();
4008
4172
  controller.close();
4009
4173
  }
4174
+ },
4175
+ /* c8 ignore next 3 - Stream cancellation cleanup, difficult to test reliably. */
4176
+ cancel() {
4177
+ rli.close();
4010
4178
  }
4011
4179
  });
4012
4180
  }
@@ -4162,7 +4330,7 @@ var SocketSdk = class {
4162
4330
  *
4163
4331
  * @see https://docs.socket.dev/reference/updateorgrepo
4164
4332
  * @apiEndpoint POST /orgs/{org_slug}/repos/{repo_slug}
4165
- * @quota 1 unit
4333
+ * @quota 0 units
4166
4334
  * @scopes repo:write
4167
4335
  * @throws {Error} When server returns 5xx status codes
4168
4336
  */
@@ -4224,7 +4392,7 @@ var SocketSdk = class {
4224
4392
  *
4225
4393
  * @see https://docs.socket.dev/reference/updateorgrepolabel
4226
4394
  * @apiEndpoint PUT /orgs/{org_slug}/repos/labels/{label_id}
4227
- * @quota 1 unit
4395
+ * @quota 0 units
4228
4396
  * @scopes repo-label:update
4229
4397
  * @throws {Error} When server returns 5xx status codes
4230
4398
  */