@socketsecurity/cli-with-sentry 0.15.59 → 0.15.61

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/vendor.js CHANGED
@@ -32895,7 +32895,7 @@ var isInteractiveExports = /*@__PURE__*/ requireIsInteractive();
32895
32895
  var dist$e = {};
32896
32896
 
32897
32897
  var name$2 = "@socketsecurity/sdk";
32898
- var version$5 = "1.4.43";
32898
+ var version$5 = "1.4.44";
32899
32899
  var license = "MIT";
32900
32900
  var description = "SDK for the Socket API client";
32901
32901
  var author = {
@@ -32978,21 +32978,21 @@ var scripts = {
32978
32978
  "update:deps": "npx --yes npm-check-updates"
32979
32979
  };
32980
32980
  var dependencies = {
32981
- "@socketsecurity/registry": "1.0.205"
32981
+ "@socketsecurity/registry": "1.0.207"
32982
32982
  };
32983
32983
  var devDependencies = {
32984
32984
  "@biomejs/biome": "1.9.4",
32985
- "@dotenvx/dotenvx": "1.44.1",
32985
+ "@dotenvx/dotenvx": "1.44.2",
32986
32986
  "@eslint/compat": "1.2.9",
32987
32987
  "@eslint/js": "9.28.0",
32988
- "@types/node": "22.15.30",
32989
- "@typescript-eslint/parser": "8.33.1",
32990
- "@vitest/coverage-v8": "3.2.2",
32988
+ "@types/node": "24.0.0",
32989
+ "@typescript-eslint/parser": "8.34.0",
32990
+ "@vitest/coverage-v8": "3.2.3",
32991
32991
  "del-cli": "6.0.0",
32992
32992
  eslint: "9.28.0",
32993
32993
  "eslint-import-resolver-typescript": "4.4.3",
32994
32994
  "eslint-plugin-import-x": "4.15.1",
32995
- "eslint-plugin-jsdoc": "50.7.1",
32995
+ "eslint-plugin-jsdoc": "50.8.0",
32996
32996
  "eslint-plugin-n": "17.19.0",
32997
32997
  "eslint-plugin-sort-destructure-keys": "2.0.0",
32998
32998
  "eslint-plugin-unicorn": "56.0.1",
@@ -33003,11 +33003,11 @@ var devDependencies = {
33003
33003
  nock: "14.0.5",
33004
33004
  "npm-run-all2": "8.0.4",
33005
33005
  "openapi-typescript": "6.7.6",
33006
- oxlint: "0.18.0",
33006
+ oxlint: "1.0.0",
33007
33007
  "type-coverage": "2.29.7",
33008
33008
  typescript: "~5.8.3",
33009
- "typescript-eslint": "8.33.1",
33010
- vitest: "3.2.2"
33009
+ "typescript-eslint": "8.34.0",
33010
+ vitest: "3.2.3"
33011
33011
  };
33012
33012
  var overrides = {
33013
33013
  vite: "6.3.5"
@@ -33124,83 +33124,116 @@ function requireDist$e () {
33124
33124
  ];
33125
33125
  }
33126
33126
  async function createUploadRequest(baseUrl, urlPath, requestBodyNoBoundaries, options) {
33127
- // Generate a unique boundary for multipart encoding.
33128
- const boundary = `NodeMultipartBoundary${Date.now()}`;
33129
- const boundarySep = `--${boundary}\r\n`;
33130
- const finalBoundary = `--${boundary}--\r\n`;
33131
- const requestBody = [
33132
- ...requestBodyNoBoundaries.flatMap(part => [
33133
- boundarySep,
33134
- ...(Array.isArray(part) ? part : [part])
33135
- ]),
33136
- finalBoundary
33137
- ];
33138
- const url = new URL(urlPath, baseUrl);
33139
- const req = getHttpModule(baseUrl).request(url, {
33140
- method: 'POST',
33141
- ...options,
33142
- headers: {
33143
- ...options?.headers,
33144
- 'Content-Type': `multipart/form-data; boundary=${boundary}`
33145
- }
33146
- });
33147
- let aborted = false;
33148
- req.on('error', _err => {
33149
- aborted = true;
33150
- });
33151
- req.on('close', () => {
33152
- aborted = true;
33153
- });
33154
- try {
33155
- // Send the request body (headers + files).
33156
- for (const part of requestBody) {
33157
- if (aborted) {
33158
- break;
33127
+ // Note: this will create a regular http request and stream in the file content
33128
+ // implicitly. The outgoing buffer is (implicitly) flushed periodically
33129
+ // by node. When this happens first it will send the headers to the server
33130
+ // which may decide to reject the request, immediately send a response and
33131
+ // then cut the connection (EPIPE or ECONNRESET errors may follow while
33132
+ // writing the files).
33133
+ // We have to make sure to guard for sudden reject responses because if we
33134
+ // don't then the file streaming will fail with random errors and it gets
33135
+ // hard to debug what's going on why.
33136
+ // Example : `socket scan create --org badorg` should fail gracefully.
33137
+ // eslint-disable-next-line no-async-promise-executor
33138
+ return await new Promise(async (pass, fail) => {
33139
+ // Generate a unique boundary for multipart encoding.
33140
+ const boundary = `NodeMultipartBoundary${Date.now()}`;
33141
+ const boundarySep = `--${boundary}\r\n`;
33142
+ const finalBoundary = `--${boundary}--\r\n`;
33143
+ const requestBody = [
33144
+ ...requestBodyNoBoundaries.flatMap(part => [
33145
+ boundarySep,
33146
+ ...(Array.isArray(part) ? part : [part])
33147
+ ]),
33148
+ finalBoundary
33149
+ ];
33150
+ const url = new URL(urlPath, baseUrl);
33151
+ const req = getHttpModule(baseUrl).request(url, {
33152
+ method: 'POST',
33153
+ ...options,
33154
+ headers: {
33155
+ ...options?.headers,
33156
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`
33159
33157
  }
33160
- if (typeof part === 'string') {
33161
- req.write(part);
33158
+ });
33159
+ // Send the headers now. If the server would reject this request, it should
33160
+ // do so asap. This prevents us from sending more data to it then necessary.
33161
+ // If it will reject we could just await the `req.on(response` now but if it
33162
+ // accepts the request then the response will not come until after the final
33163
+ // file. So we can't await the response at this time. Just proceed, carefully.
33164
+ req.flushHeaders();
33165
+ // Wait for the response. It may arrive at any point during the request or
33166
+ // afterwards. Node will flush the output buffer at some point, initiating
33167
+ // the request, and the server can decide to reject the request immediately
33168
+ // or at any point later (ike a timeout). We should handle those cases.
33169
+ getResponse(req).then(res => {
33170
+ // Note: this returns the response to the caller to createUploadRequest
33171
+ pass(res);
33172
+ }, async (err) => {
33173
+ // Note: this will throw an error for the caller to createUploadRequest
33174
+ if (err.response && !isResponseOk(err.response)) {
33175
+ fail(new ResponseError(err.response, `${err.method} request failed`));
33162
33176
  }
33163
- else if (typeof part?.pipe === 'function') {
33164
- part.pipe(req, { end: false });
33165
- // Wait for file streaming to complete.
33166
- // eslint-disable-next-line no-await-in-loop
33167
- await new Promise((resolve, reject) => {
33168
- const cleanup = () => {
33169
- part.off('end', onEnd);
33170
- part.off('error', onError);
33171
- };
33172
- const onEnd = () => {
33173
- cleanup();
33174
- resolve();
33175
- };
33176
- const onError = (e) => {
33177
- cleanup();
33178
- reject(e);
33179
- };
33180
- part.on('end', onEnd);
33181
- part.on('error', onError);
33182
- });
33183
- if (!aborted) {
33184
- // Ensure a new line after file content.
33185
- req.write('\r\n');
33177
+ fail(err);
33178
+ });
33179
+ let aborted = false;
33180
+ req.on('error', _err => {
33181
+ aborted = true;
33182
+ });
33183
+ req.on('close', () => {
33184
+ aborted = true;
33185
+ });
33186
+ try {
33187
+ // Send the request body (headers + files).
33188
+ for (const part of requestBody) {
33189
+ if (aborted) {
33190
+ break;
33191
+ }
33192
+ if (typeof part === 'string') {
33193
+ req.write(part);
33194
+ }
33195
+ else if (typeof part?.pipe === 'function') {
33196
+ part.pipe(req, { end: false });
33197
+ // Wait for file streaming to complete.
33198
+ // eslint-disable-next-line no-await-in-loop
33199
+ await new Promise((resolve, reject) => {
33200
+ const cleanup = () => {
33201
+ part.off('end', onEnd);
33202
+ part.off('error', onError);
33203
+ };
33204
+ const onEnd = () => {
33205
+ cleanup();
33206
+ resolve();
33207
+ };
33208
+ const onError = (e) => {
33209
+ cleanup();
33210
+ reject(e);
33211
+ };
33212
+ part.on('end', onEnd);
33213
+ part.on('error', onError);
33214
+ });
33215
+ if (!aborted) {
33216
+ // Ensure a new line after file content.
33217
+ req.write('\r\n');
33218
+ }
33219
+ }
33220
+ else {
33221
+ throw new TypeError('Socket API - Invalid multipart part, expected string or stream');
33186
33222
  }
33187
- }
33188
- else {
33189
- throw new TypeError('Socket API - Invalid multipart part, expected string or stream');
33190
33223
  }
33191
33224
  }
33192
- }
33193
- catch (e) {
33194
- req.destroy(e);
33195
- throw e;
33196
- }
33197
- finally {
33198
- if (!aborted) {
33199
- // Close request after writing all data.
33200
- req.end();
33225
+ catch (e) {
33226
+ req.destroy(e);
33227
+ fail(e);
33201
33228
  }
33202
- }
33203
- return await getResponse(req);
33229
+ finally {
33230
+ if (!aborted) {
33231
+ // Close request after writing all data.
33232
+ req.end();
33233
+ }
33234
+ }
33235
+ pass(getResponse(req));
33236
+ });
33204
33237
  }
33205
33238
  async function getErrorResponseBody(response) {
33206
33239
  const chunks = [];
@@ -33233,39 +33266,33 @@ function requireDist$e () {
33233
33266
  return protocol === 'https:' ? node_https_1.default : node_http_1.default;
33234
33267
  }
33235
33268
  async function getResponse(req) {
33236
- try {
33237
- const res = await new Promise((resolve, reject) => {
33238
- const cleanup = () => {
33239
- req.off('response', onResponse);
33240
- req.off('error', onError);
33241
- abort_signal_1.default?.removeEventListener('abort', onAbort);
33242
- };
33243
- const onAbort = () => {
33244
- cleanup();
33245
- req.destroy();
33246
- reject(new Error('Request aborted by signal'));
33247
- };
33248
- const onError = (e) => {
33249
- cleanup();
33250
- reject(e);
33251
- };
33252
- const onResponse = (res) => {
33253
- cleanup();
33254
- resolve(res);
33255
- };
33256
- req.on('response', onResponse);
33257
- req.on('error', onError);
33258
- abort_signal_1.default?.addEventListener('abort', onAbort);
33259
- });
33260
- if (!isResponseOk(res)) {
33261
- throw new ResponseError(res, `${req.method} request failed`);
33262
- }
33263
- return res;
33264
- }
33265
- catch (e) {
33266
- req.destroy();
33267
- throw e;
33269
+ const res = await new Promise((resolve, reject) => {
33270
+ const cleanup = () => {
33271
+ req.off('response', onResponse);
33272
+ req.off('error', onError);
33273
+ abort_signal_1.default?.removeEventListener('abort', onAbort);
33274
+ };
33275
+ const onAbort = () => {
33276
+ cleanup();
33277
+ req.destroy();
33278
+ reject(new Error('Request aborted by signal'));
33279
+ };
33280
+ const onError = (e) => {
33281
+ cleanup();
33282
+ reject(e);
33283
+ };
33284
+ const onResponse = (res) => {
33285
+ cleanup();
33286
+ resolve(res);
33287
+ };
33288
+ req.on('response', onResponse);
33289
+ req.on('error', onError);
33290
+ abort_signal_1.default?.addEventListener('abort', onAbort);
33291
+ });
33292
+ if (!isResponseOk(res)) {
33293
+ throw new ResponseError(res, `${req.method} request failed`);
33268
33294
  }
33295
+ return res;
33269
33296
  }
33270
33297
  async function getResponseJson(response) {
33271
33298
  let data = '';
@@ -164963,5 +164990,5 @@ exports.terminalLinkExports = terminalLinkExports;
164963
164990
  exports.updater = updater$1;
164964
164991
  exports.yargsParser = yargsParser;
164965
164992
  exports.yoctocolorsCjsExports = yoctocolorsCjsExports;
164966
- //# debugId=54cac667-1a93-40c1-a094-bf9382b9516d
164993
+ //# debugId=be0a51af-50b1-4eef-9fe4-20717e6a7a65
164967
164994
  //# sourceMappingURL=vendor.js.map
@@ -212320,7 +212320,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
212320
212320
  }
212321
212321
 
212322
212322
  // dist/version.js
212323
- var version2 = "14.9.22";
212323
+ var version2 = "14.9.24";
212324
212324
 
212325
212325
  // ../../node_modules/.pnpm/axios@1.9.0/node_modules/axios/lib/helpers/bind.js
212326
212326
  function bind2(fn2, thisArg) {
@@ -215646,14 +215646,20 @@ async function scanForVulnerabilitiesSocketMode(dependencyTree) {
215646
215646
  const data2 = {
215647
215647
  components: Object.keys(purlStringsToIdentifier).map((purl) => ({ purl }))
215648
215648
  };
215649
- const componentsString = (await axios_default2.post(url3, data2, {
215649
+ const componentsResponse = (await axios_default2.post(url3, data2, {
215650
215650
  headers: {
215651
215651
  "Content-Type": "application/json",
215652
215652
  Accept: "application/json",
215653
215653
  Authorization: `Basic ${btoa(`${process.env.SOCKET_CLI_API_TOKEN}:`)}`
215654
215654
  }
215655
215655
  })).data;
215656
- components = JSON.parse(`[${componentsString.trim().replace(/\n/g, ",")}]`);
215656
+ if (typeof componentsResponse === "object") {
215657
+ components = [componentsResponse];
215658
+ } else if (typeof componentsResponse === "string") {
215659
+ components = JSON.parse(`[${componentsResponse.trim().replace(/\n/g, ",")}]`);
215660
+ } else {
215661
+ throw new Error(`Unexpected response type from Socket API: ${typeof componentsResponse}`);
215662
+ }
215657
215663
  } catch (e) {
215658
215664
  logger.error("Failed to scan for vulnerabilities in socket mode");
215659
215665
  logger.error("error", e);
@@ -215812,11 +215818,11 @@ function getNamespaceAndName(ecosystem, packageName) {
215812
215818
  }
215813
215819
 
215814
215820
  // dist/internal/socket-report.js
215815
- function toSocketFacts(report, dependencyTrees) {
215821
+ function toSocketFacts(report, dependencyTrees, subPjToWsPathToDirectDependencies) {
215816
215822
  const components = [];
215817
215823
  const purlToIndex = /* @__PURE__ */ new Map();
215818
215824
  for (const dependencyTree of dependencyTrees) {
215819
- const depIdentifierToPurl = Object.fromEntries(Object.entries(dependencyTree.dependencyTree.transitiveDependencies).map(([depIdentifier, dep]) => {
215825
+ const depIdentifierToPurl = Object.fromEntries(Object.entries(dependencyTree.dependencyTree.transitiveDependencies).filter(([_depIdentifier, dep]) => dep.purlObj).map(([depIdentifier, dep]) => {
215820
215826
  const purl = dep.purlObj.purlString;
215821
215827
  if (purl && !purlToIndex.has(purl)) {
215822
215828
  purlToIndex.set(purl, components.length);
@@ -215831,8 +215837,10 @@ function toSocketFacts(report, dependencyTrees) {
215831
215837
  artifact_id: depTreeNode.purlObj.artifact_id,
215832
215838
  artifactId: depTreeNode.purlObj.artifactId,
215833
215839
  qualifiers: depTreeNode.purlObj.qualifiers,
215834
- // direct: false, // TODO: add direct flag
215835
- // dev: false, // TODO: add dev flag
215840
+ direct: false,
215841
+ // Use false as default, and set to true if actually direct
215842
+ dev: true,
215843
+ // Use true as default, and set to false if the artifact is found as prod, prod&dev or missing for any dependency chain.
215836
215844
  dependencies: []
215837
215845
  };
215838
215846
  }
@@ -215840,15 +215848,40 @@ function toSocketFacts(report, dependencyTrees) {
215840
215848
  }));
215841
215849
  for (const [depIdentifier, purl] of Object.entries(depIdentifierToPurl)) {
215842
215850
  const depTreeNode = dependencyTree.dependencyTree.transitiveDependencies[depIdentifier];
215851
+ if (!depTreeNode.purlObj) {
215852
+ continue;
215853
+ }
215843
215854
  const component = components[purlToIndex.get(purl)];
215844
215855
  depTreeNode.dependencies?.forEach((dep) => {
215845
215856
  const depPurl = depIdentifierToPurl[dep];
215846
215857
  const depIndex = purlToIndex.get(depPurl);
215847
- if (!component.dependencies?.includes(depIndex.toString())) {
215858
+ if (depIndex && !component.dependencies?.includes(depIndex.toString())) {
215848
215859
  component.dependencies.push(depIndex.toString());
215849
215860
  }
215850
215861
  });
215851
215862
  }
215863
+ for (const depIdentifier of dependencyTree.dependencyTree.dependencies ?? []) {
215864
+ const depTreeNode = dependencyTree.dependencyTree.transitiveDependencies[depIdentifier];
215865
+ const component = components[purlToIndex.get(depTreeNode.purlObj.purlString)];
215866
+ component.direct = true;
215867
+ }
215868
+ for (const depIdentifier of dependencyTree.dependencyTree.dependencies ?? []) {
215869
+ let updateDependencyType2 = function(id) {
215870
+ if (visitedIds.has(id.toString()))
215871
+ return;
215872
+ visitedIds.add(id.toString());
215873
+ const component = components[id];
215874
+ if (dependencyType !== "dev") {
215875
+ component.dev = false;
215876
+ }
215877
+ component.dependencies?.forEach((depId) => updateDependencyType2(parseInt(depId)));
215878
+ };
215879
+ var updateDependencyType = updateDependencyType2;
215880
+ const depTreeNode = dependencyTree.dependencyTree.transitiveDependencies[depIdentifier];
215881
+ const dependencyType = subPjToWsPathToDirectDependencies[dependencyTree.subprojectPath][dependencyTree.workspacePath][depTreeNode.packageName];
215882
+ const visitedIds = /* @__PURE__ */ new Set();
215883
+ updateDependencyType2(purlToIndex.get(depTreeNode.purlObj.purlString));
215884
+ }
215852
215885
  }
215853
215886
  for (const vulnerability of report.vulnerabilities) {
215854
215887
  const component = components[purlToIndex.get(vulnerability.purl)];
@@ -216015,9 +216048,9 @@ var CliCore = class {
216015
216048
  const gitData = await getGitDataToMetadataIfAvailable(this.rootWorkingDirectory);
216016
216049
  this.reportId = await createReport(this.options.repoUrl, this.options.projectName, version2, gitData?.sha, gitData?.branchName, omit(this.options, "apiKey", "print-report", "repoUrl", "projectName", "writeReportToFile"), this.apiKey, this.options.runEnv);
216017
216050
  }
216018
- const report = await this.computeReport();
216051
+ const { report, subPjToWsPathToDirectDependencies } = await this.computeReport();
216019
216052
  logger.info("Report computed successfully");
216020
- await this.outputAndShareReport(report);
216053
+ await this.outputAndShareReport(report, subPjToWsPathToDirectDependencies);
216021
216054
  this.spinner.stop();
216022
216055
  return report;
216023
216056
  } catch (e) {
@@ -216046,13 +216079,13 @@ var CliCore = class {
216046
216079
  if (this.reportId)
216047
216080
  await sendLogToDashboard(await this.getLogContent(), this.reportId, this.apiKey);
216048
216081
  }
216049
- async outputAndShareReport(report) {
216082
+ async outputAndShareReport(report, subPjToWsPathToDirectDependencies) {
216050
216083
  const outputDir = this.options.outputDir;
216051
216084
  if (this.options.socketMode) {
216052
216085
  if (!this.reportDependencyTrees) {
216053
216086
  throw new Error("Dependency trees should be available when using --socket-mode");
216054
216087
  }
216055
- const socketReport = toSocketFacts(report, this.reportDependencyTrees);
216088
+ const socketReport = toSocketFacts(report, this.reportDependencyTrees, subPjToWsPathToDirectDependencies);
216056
216089
  const outputFile = resolve24(this.options.socketMode);
216057
216090
  await writeFile10(outputFile, JSON.stringify(socketReport, null, 2));
216058
216091
  logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
@@ -216140,7 +216173,16 @@ var CliCore = class {
216140
216173
  vulnerabilities: allVulnerabilities,
216141
216174
  ...await this.createMetadataForReport(startTime)
216142
216175
  };
216143
- return report;
216176
+ const reportAndSubPjToWsPathToDirectDependencies = {
216177
+ report,
216178
+ subPjToWsPathToDirectDependencies: workspacesOutput.reduce((acc, { subprojectPath, workspacePath, directDependencies }) => {
216179
+ if (!acc[subprojectPath])
216180
+ acc[subprojectPath] = {};
216181
+ acc[subprojectPath][workspacePath] = directDependencies;
216182
+ return acc;
216183
+ }, {})
216184
+ };
216185
+ return reportAndSubPjToWsPathToDirectDependencies;
216144
216186
  }
216145
216187
  async updateSpinnerTextOnNewSubproject(subprojectAndWsPath, numberSubprojects, index2) {
216146
216188
  this.spinner.start();
@@ -216293,8 +216335,6 @@ var CliCore = class {
216293
216335
  ];
216294
216336
  } catch (e) {
216295
216337
  logger.error(`Scanning for vulnerabilities failed for subproject ${subprojectPath} in workspace ${workspacePath}`);
216296
- logger.error(JSON.stringify(dependencyTree, null, 2));
216297
- await new Promise((resolve25) => setTimeout(resolve25, 1e4));
216298
216338
  throw e;
216299
216339
  } finally {
216300
216340
  this.sendProgress("SCAN_FOR_VULNERABILITIES", false, subprojectPath, workspacePath);