socket 0.14.14 → 0.14.16

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/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts","../src/utils/formatting.ts","../src/utils/sorts.ts","../src/flags.ts","../src/utils/meow-with-subcommands.ts","../src/commands/cdxgen.ts","../src/utils/api-helpers.ts","../src/utils/objects.ts","../src/utils/format-issues.ts","../src/commands/info.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/npm.ts","../src/commands/npx.ts","../src/utils/fs.ts","../src/utils/json.ts","../src/utils/strings.ts","../src/utils/package-manager-detector.ts","../src/utils/arrays.ts","../src/utils/promises.ts","../src/utils/regexps.ts","../src/commands/optimize.ts","../src/commands/organization.ts","../src/commands/raw-npm.ts","../src/commands/raw-npx.ts","../src/commands/report/view.ts","../src/commands/report/create.ts","../src/commands/report/index.ts","../src/commands/wrapper.ts","../src/commands/scan/create.ts","../src/commands/scan/delete.ts","../src/commands/scan/list.ts","../src/commands/scan/metadata.ts","../src/commands/scan/stream.ts","../src/commands/scan/index.ts","../src/commands/audit-log.ts","../src/commands/repos/create.ts","../src/commands/repos/delete.ts","../src/commands/repos/list.ts","../src/commands/repos/update.ts","../src/commands/repos/view.ts","../src/commands/repos/index.ts","../src/commands/dependencies.ts","../src/commands/analytics.ts","../src/commands/diff-scan/get.ts","../src/commands/diff-scan/index.ts","../src/commands/threat-feed.ts","../src/commands/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts","../src/utils/formatting.ts","../src/utils/sorts.ts","../src/flags.ts","../src/utils/meow-with-subcommands.ts","../src/commands/cdxgen.ts","../src/utils/api-helpers.ts","../src/utils/format-issues.ts","../src/commands/info.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/npm.ts","../src/commands/npx.ts","../src/utils/fs.ts","../src/utils/json.ts","../src/utils/strings.ts","../src/utils/package-manager-detector.ts","../src/utils/arrays.ts","../src/utils/promises.ts","../src/utils/regexps.ts","../src/commands/optimize.ts","../src/commands/organization.ts","../src/commands/raw-npm.ts","../src/commands/raw-npx.ts","../src/commands/report/view.ts","../src/commands/report/create.ts","../src/commands/report/index.ts","../src/commands/wrapper.ts","../src/commands/scan/create.ts","../src/commands/scan/delete.ts","../src/commands/scan/list.ts","../src/commands/scan/metadata.ts","../src/commands/scan/stream.ts","../src/commands/scan/index.ts","../src/commands/audit-log.ts","../src/commands/repos/create.ts","../src/commands/repos/delete.ts","../src/commands/repos/list.ts","../src/commands/repos/update.ts","../src/commands/repos/view.ts","../src/commands/repos/index.ts","../src/commands/dependencies.ts","../src/commands/analytics.ts","../src/commands/diff-scan/get.ts","../src/commands/diff-scan/index.ts","../src/commands/threat-feed.ts","../src/commands/index.ts"],"names":[],"mappings":""}
package/dist/cli.js CHANGED
@@ -324,45 +324,13 @@ async function queryAPI(path, apiKey) {
324
324
 
325
325
  var formatIssues = {};
326
326
 
327
- var objects = {};
328
-
329
- Object.defineProperty(objects, "__esModule", {
330
- value: true
331
- });
332
- objects.hasOwn = hasOwn;
333
- objects.isObjectObject = isObjectObject;
334
- objects.objectSome = objectSome;
335
- objects.pick = pick;
336
- function hasOwn(obj, propKey) {
337
- if (obj === null || obj === undefined) return false;
338
- return Object.hasOwn(obj, propKey);
339
- }
340
- function isObjectObject(value) {
341
- return value !== null && typeof value === 'object' && !Array.isArray(value);
342
- }
343
- function objectSome(obj) {
344
- for (const key in obj) {
345
- if (obj[key]) {
346
- return true;
347
- }
348
- }
349
- return false;
350
- }
351
- function pick(input, keys) {
352
- const result = {};
353
- for (const key of keys) {
354
- result[key] = input[key];
355
- }
356
- return result;
357
- }
358
-
359
327
  Object.defineProperty(formatIssues, "__esModule", {
360
328
  value: true
361
329
  });
362
330
  formatIssues.formatSeverityCount = formatSeverityCount;
363
331
  formatIssues.getSeverityCount = getSeverityCount;
364
332
  var _misc$2 = sdk.misc;
365
- var _objects$4 = objects;
333
+ var _objects$4 = sdk.objects;
366
334
  const SEVERITIES_BY_ORDER = ['critical', 'high', 'middle', 'low'];
367
335
  function getDesiredSeverities(lowestToInclude) {
368
336
  const result = [];
@@ -448,7 +416,7 @@ var _chalkMarkdown$3 = sdk.chalkMarkdown;
448
416
  var _errors$k = sdk.errors;
449
417
  var _formatIssues$1 = formatIssues;
450
418
  var _formatting$m = formatting;
451
- var _objects$3 = objects;
419
+ var _objects$3 = sdk.objects;
452
420
  var _sdk$j = sdk.sdk;
453
421
  const info = info$1.info = {
454
422
  description: 'Look up info regarding a package',
@@ -820,8 +788,8 @@ const description$5 = 'npm wrapper functionality';
820
788
  npm.npm = {
821
789
  description: description$5,
822
790
  async run(argv, _importMeta, _ctx) {
823
- process.exitCode = 1;
824
791
  const wrapperPath = _nodePath$6.join(distPath$3, 'npm-cli.js');
792
+ process.exitCode = 1;
825
793
  const spawnPromise = _promiseSpawn$5(process.execPath, [wrapperPath, ...argv], {
826
794
  stdio: 'inherit'
827
795
  });
@@ -928,7 +896,7 @@ Object.defineProperty(json, "__esModule", {
928
896
  value: true
929
897
  });
930
898
  json.parseJSONObject = parseJSONObject;
931
- var _objects$2 = objects;
899
+ var _objects$2 = sdk.objects;
932
900
  function parseJSONObject(jsonStr) {
933
901
  try {
934
902
  const value = JSON.parse(jsonStr);
@@ -962,7 +930,7 @@ var _semver$1 = require$$3$1;
962
930
  var _which = require$$5$1;
963
931
  var _fs = fs;
964
932
  var _json = json;
965
- var _objects$1 = objects;
933
+ var _objects$1 = sdk.objects;
966
934
  var _strings$1 = strings;
967
935
  const AGENTS = packageManagerDetector.AGENTS = ['bun', 'npm', 'pnpm', 'yarn'];
968
936
  const numericCollator = new Intl.Collator(undefined, {
@@ -1241,7 +1209,7 @@ var _pacote = require$$8;
1241
1209
  var _semver = require$$3$1;
1242
1210
  var _flags$j = flags$1;
1243
1211
  var _formatting$k = formatting;
1244
- var _objects = objects;
1212
+ var _objects = sdk.objects;
1245
1213
  var _packageManagerDetector = packageManagerDetector;
1246
1214
  var _promises$2 = promises;
1247
1215
  var _regexps = regexps;
@@ -1727,7 +1695,7 @@ async function setupCommand$j(name, description, argv, importMeta) {
1727
1695
  cli.showHelp();
1728
1696
  return;
1729
1697
  }
1730
- const spawnPromise = _promiseSpawn$1('npm', [argv.join(' ')], {
1698
+ const spawnPromise = _promiseSpawn$1('npm', argv, {
1731
1699
  stdio: 'inherit'
1732
1700
  });
1733
1701
  spawnPromise.process.on('exit', (code, signal) => {
package/dist/npm-cli.js CHANGED
@@ -21,13 +21,10 @@ const realFilename = (0, _nodeFs.realpathSync)(__filename);
21
21
  const realDirname = _nodePath.dirname(realFilename);
22
22
  const npmPath = (0, _link.installLinks)(_nodePath.join(realDirname, 'bin'), 'npm');
23
23
  const injectionPath = _nodePath.join(realDirname, 'npm-injection.js');
24
- process.exitCode = 1;
25
24
 
26
- /*
27
- Adding the `--quiet` and `--no-progress` flags when the `proc-log` module
28
- is found to fix a UX issue when running the command with recent versions of npm
29
- (input swallowed by the standard npm spinner)
30
- */
25
+ // Adding the `--quiet` and `--no-progress` flags when the `proc-log` module
26
+ // is found to fix a UX issue when running the command with recent versions of
27
+ // npm (input swallowed by the standard npm spinner)
31
28
  let npmArgs = [];
32
29
  if (process.argv.slice(2).includes('install')) {
33
30
  const npmEntrypoint = (0, _nodeFs.realpathSync)(npmPath);
@@ -44,9 +41,11 @@ if (process.argv.slice(2).includes('install')) {
44
41
  npmArgs = ['--quiet', '--no-progress'];
45
42
  }
46
43
  }
47
- _promiseSpawn(process.execPath, ['--require', injectionPath, npmPath, ...process.argv.slice(2), ...npmArgs], {
44
+ process.exitCode = 1;
45
+ const spawnPromise = _promiseSpawn(process.execPath, ['--require', injectionPath, npmPath, ...process.argv.slice(2), ...npmArgs], {
48
46
  stdio: 'inherit'
49
- }).process.on('exit', (code, signal) => {
47
+ });
48
+ spawnPromise.process.on('exit', (code, signal) => {
50
49
  if (signal) {
51
50
  process.kill(process.pid, signal);
52
51
  } else if (code !== null) {
@@ -10,10 +10,12 @@ var require$$3 = require('node:readline');
10
10
  var require$$5 = require('node:stream');
11
11
  var require$$8$1 = require('node:timers/promises');
12
12
  var require$$3$1 = require('@socketsecurity/config');
13
+ var require$$6$1 = require('npm-package-arg');
14
+ var require$$3$2 = require('semver');
15
+ var sdk = require('./sdk.js');
13
16
  var require$$1$1 = require('node:net');
14
17
  var require$$2 = require('node:os');
15
18
  var require$$6 = require('../package.json');
16
- var sdk = require('./sdk.js');
17
19
  var pathResolve = require('./path-resolve.js');
18
20
  var require$$8 = require('pacote');
19
21
 
@@ -393,14 +395,17 @@ var _config = require$$3$1;
393
395
  var _chalk = _interopRequireDefault(vendor.source);
394
396
  var _isInteractive = _interopRequireDefault(vendor.isInteractive);
395
397
  var _ora = _interopRequireWildcard(vendor.ora);
398
+ var _npmPackageArg = require$$6$1;
399
+ var _semver = require$$3$2;
400
+ var _constants = sdk.constants;
396
401
  var _ttyServer = ttyServer$1;
397
402
  var _chalkMarkdown = sdk.chalkMarkdown;
398
403
  var _issueRules = issueRules;
399
404
  var _misc = sdk.misc;
405
+ var _objects = sdk.objects;
400
406
  var _pathResolve = pathResolve.pathResolve;
401
407
  var _sdk = sdk.sdk;
402
408
  var _settings = sdk.settings;
403
- var _constants = sdk.constants;
404
409
  const LOOP_SENTINEL = 1_000_000;
405
410
  const POTENTIALLY_BUG_ERROR_SNIPPET = 'this is potentially a bug with socket-npm caused by changes to the npm cli';
406
411
  const distPath$1 = __dirname;
@@ -420,6 +425,8 @@ if (npmRootPath === undefined) {
420
425
  const npmNmPath = _nodePath$1.join(npmRootPath, 'node_modules');
421
426
  const arboristClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/arborist/index.js');
422
427
  const arboristEdgeClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/edge.js');
428
+ const arboristNodeClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/node.js');
429
+ const arboristOverrideSetClassPatch = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/override-set.js');
423
430
  let npmlog;
424
431
  try {
425
432
  npmlog = require(_nodePath$1.join(npmNmPath, 'proc-log/lib/index.js')).log;
@@ -441,6 +448,8 @@ try {
441
448
  }
442
449
  const Arborist = require(arboristClassPath);
443
450
  const Edge = require(arboristEdgeClassPath);
451
+ const Node = require(arboristNodeClassPath);
452
+ const OverrideSet = require(arboristOverrideSetClassPatch);
444
453
  const kCtorArgs = Symbol('ctorArgs');
445
454
  const kRiskyReify = Symbol('riskyReify');
446
455
  const formatter = new _chalkMarkdown.ChalkOrMarkdown(false);
@@ -493,15 +502,6 @@ async function* batchScan(pkgIds) {
493
502
  yield JSON.parse(line);
494
503
  }
495
504
  }
496
- function deleteEdgeIn(node, edge) {
497
- node.edgesIn.delete(edge);
498
- const {
499
- overrides
500
- } = edge;
501
- if (overrides) {
502
- updateNodeOverrideSetDueToEdgeRemoval(node, overrides);
503
- }
504
- }
505
505
  function findSocketYmlSync() {
506
506
  let prevDir = null;
507
507
  let dir = process.cwd();
@@ -527,17 +527,20 @@ function findSocketYmlSync() {
527
527
  }
528
528
  return null;
529
529
  }
530
+
531
+ // Patch adding findSpecificOverrideSet is based on
532
+ // https://github.com/npm/cli/pull/7025.
530
533
  function findSpecificOverrideSet(first, second) {
531
534
  let overrideSet = second;
532
535
  while (overrideSet) {
533
- if (overrideSetsEqual(overrideSet, first)) {
536
+ if (overrideSet.isEqual(first)) {
534
537
  return second;
535
538
  }
536
539
  overrideSet = overrideSet.parent;
537
540
  }
538
541
  overrideSet = first;
539
542
  while (overrideSet) {
540
- if (overrideSetsEqual(overrideSet, second)) {
543
+ if (overrideSet.isEqual(second)) {
541
544
  return first;
542
545
  }
543
546
  overrideSet = overrideSet.parent;
@@ -551,61 +554,6 @@ function maybeReadfileSync(filepath) {
551
554
  } catch {}
552
555
  return undefined;
553
556
  }
554
- function overrideSetsChildrenAreEqual(overrideSet, other) {
555
- const queue = [[overrideSet, other]];
556
- let pos = 0;
557
- let {
558
- length: queueLength
559
- } = queue;
560
- while (pos < queueLength) {
561
- if (pos === LOOP_SENTINEL) {
562
- throw new Error('Detected infinite loop while comparing override sets');
563
- }
564
- const {
565
- 0: currSet,
566
- 1: currOtherSet
567
- } = queue[pos++];
568
- const {
569
- children
570
- } = currSet;
571
- const {
572
- children: otherChildren
573
- } = currOtherSet;
574
- if (children.size !== otherChildren.size) {
575
- return false;
576
- }
577
- for (const key of children.keys()) {
578
- if (!otherChildren.has(key)) {
579
- return false;
580
- }
581
- const child = children.get(key);
582
- const otherChild = otherChildren.get(key);
583
- if (child.value !== otherChild.value) {
584
- return false;
585
- }
586
- queue[queueLength++] = [child, otherChild];
587
- }
588
- }
589
- return true;
590
- }
591
- function overrideSetsEqual(overrideSet, other) {
592
- if (overrideSet === other) {
593
- return true;
594
- }
595
- if (!other) {
596
- return false;
597
- }
598
- if (overrideSet.key !== other.key || overrideSet.value !== other.value) {
599
- return false;
600
- }
601
- if (!overrideSetsChildrenAreEqual(overrideSet, other)) {
602
- return false;
603
- }
604
- if (!overrideSet.parent) {
605
- return !other.parent;
606
- }
607
- return overrideSetsEqual(overrideSet.parent, other.parent);
608
- }
609
557
  async function packagesHaveRiskyIssues(safeArb, _registry, pkgs, output) {
610
558
  let result = false;
611
559
  let remaining = pkgs.length;
@@ -722,15 +670,6 @@ function pkgidParts(pkgid) {
722
670
  version
723
671
  };
724
672
  }
725
- function recalculateOutEdgesOverrides(node) {
726
- // For each edge out propagate the new overrides through.
727
- for (const edge of node.edgesOut.values()) {
728
- edge.reload(true);
729
- if (edge.to) {
730
- updateNodeOverrideSet(edge.to, edge.overrides);
731
- }
732
- }
733
- }
734
673
  function toPURL(pkgid, resolved) {
735
674
  const repo = resolved.replace(/#[\s\S]*$/u, '').replace(/\?[\s\S]*$/u, '').replace(/\/[^/]*\/-\/[\s\S]*$/u, '');
736
675
  const {
@@ -744,84 +683,6 @@ function toPURL(pkgid, resolved) {
744
683
  repository_url: repo
745
684
  };
746
685
  }
747
- function updateNodeOverrideSetDueToEdgeRemoval(node, other) {
748
- const {
749
- overrides
750
- } = node;
751
- // If this edge's overrides isn't equal to this node's overrides, then removing
752
- // it won't change newOverrideSet later.
753
- if (!overrides || !overrideSetsEqual(overrides, other)) {
754
- return false;
755
- }
756
- let newOverrideSet;
757
- for (const edge of node.edgesIn) {
758
- const {
759
- overrides: edgeOverrides
760
- } = edge;
761
- if (newOverrideSet) {
762
- newOverrideSet = findSpecificOverrideSet(edgeOverrides, newOverrideSet);
763
- } else {
764
- newOverrideSet = edgeOverrides;
765
- }
766
- }
767
- if (overrideSetsEqual(overrides, newOverrideSet)) {
768
- return false;
769
- }
770
- node.overrides = newOverrideSet;
771
- if (newOverrideSet) {
772
- // Optimization: If there's any override set at all, then no non-extraneous
773
- // node has an empty override set. So if we temporarily have no override set
774
- // (for example, we removed all the edges in), there's no use updating all
775
- // the edges out right now. Let's just wait until we have an actual override
776
- // set later.
777
- recalculateOutEdgesOverrides(node);
778
- }
779
- return true;
780
- }
781
-
782
- // This logic isn't perfect either. When we have two edges in that have different
783
- // override sets, then we have to decide which set is correct. This function
784
- // assumes the more specific override set is applicable, so if we have dependencies
785
- // A->B->C and A->C and an override set that specifies what happens for C under
786
- // A->B, this will work even if the new A->C edge comes along and tries to change
787
- // the override set. The strictly correct logic is not to allow two edges with
788
- // different overrides to point to the same node, because even if this node can
789
- // satisfy both, one of its dependencies might need to be different depending on
790
- // the edge leading to it. However, this might cause a lot of duplication, because
791
- // the conflict in the dependencies might never actually happen.
792
- function updateNodeOverrideSet(node, otherOverrideSet) {
793
- if (!node.overrides) {
794
- // Assuming there are any overrides at all, the overrides field is never
795
- // undefined for any node at the end state of the tree. So if the new edge's
796
- // overrides is undefined it will be updated later. So we can wait with
797
- // updating the node's overrides field.
798
- if (!otherOverrideSet) {
799
- return false;
800
- }
801
- node.overrides = otherOverrideSet;
802
- recalculateOutEdgesOverrides(node);
803
- return true;
804
- }
805
- const {
806
- overrides
807
- } = node;
808
- if (overrideSetsEqual(overrides, otherOverrideSet)) {
809
- return false;
810
- }
811
- const newOverrideSet = findSpecificOverrideSet(overrides, otherOverrideSet);
812
- if (newOverrideSet) {
813
- if (overrideSetsEqual(overrides, newOverrideSet)) {
814
- return false;
815
- }
816
- node.overrides = newOverrideSet;
817
- recalculateOutEdgesOverrides(node);
818
- return true;
819
- }
820
- // This is an error condition. We can only get here if the new override set is
821
- // in conflict with the existing.
822
- console.error('Conflicting override sets');
823
- return false;
824
- }
825
686
  function walk(diff_, needInfoOn = []) {
826
687
  const queue = [diff_];
827
688
  let pos = 0;
@@ -869,15 +730,18 @@ function walk(diff_, needInfoOn = []) {
869
730
  return needInfoOn;
870
731
  }
871
732
 
872
- // Copied from
873
- // https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/edge.js:
733
+ // The Edge class makes heavy use of private properties which subclasses do NOT
734
+ // have access to. So we have to recreate any functionality that relies on those
735
+ // private properties and use our own "safe" prefixed non-conflicting private
736
+ // properties. Implementation code not related to patch https://github.com/npm/cli/pull/7025
737
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/edge.js.
738
+ //
874
739
  // The npm application
875
740
  // Copyright (c) npm, Inc. and Contributors
876
741
  // Licensed on the terms of The Artistic License 2.0
877
742
  //
878
743
  // An edge in the dependency graph.
879
744
  // Represents a dependency relationship of some kind.
880
-
881
745
  class SafeEdge extends Edge {
882
746
  #safeAccept;
883
747
  #safeError;
@@ -939,11 +803,20 @@ class SafeEdge extends Edge {
939
803
  // @ts-ignore: Incorrectly typed as a property instead of an accessor.
940
804
  get spec() {
941
805
  if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this.name) {
806
+ // Patch adding "if" condition is based on
807
+ // https://github.com/npm/cli/pull/7025.
808
+ //
809
+ // If this edge has the same overrides field as the source, then we're not
810
+ // applying an override for this edge.
811
+ if (this.overrides === this.#safeFrom?.overrides) {
812
+ // The Edge rawSpec getter will retrieve the private Edge #spec property.
813
+ return this.rawSpec;
814
+ }
942
815
  if (this.overrides.value.startsWith('$')) {
943
816
  const ref = this.overrides.value.slice(1);
944
817
  // We may be a virtual root, if we are we want to resolve reference
945
818
  // overrides from the real root, not the virtual one.
946
- const pkg = this.#safeFrom?.sourceReference ? this.#safeFrom.sourceReference.root.package : this.#safeFrom?.root.package;
819
+ const pkg = this.#safeFrom?.sourceReference ? this.#safeFrom.sourceReference.root.package : this.#safeFrom?.root?.package;
947
820
  if (pkg?.devDependencies?.[ref]) {
948
821
  return pkg.devDependencies[ref];
949
822
  }
@@ -977,6 +850,16 @@ class SafeEdge extends Edge {
977
850
  this.#safeError = 'PEER LOCAL';
978
851
  } else if (!this.satisfiedBy(this.#safeTo)) {
979
852
  this.#safeError = 'INVALID';
853
+ }
854
+ // Patch adding "else if" condition is based on
855
+ // https://github.com/npm/cli/pull/7025.
856
+ else if (this.overrides && this.#safeTo.edgesOut.size && !findSpecificOverrideSet(this.overrides, this.#safeTo.overrides)) {
857
+ // Any inconsistency between the edge's override set and the target's
858
+ // override set is potentially problematic. But we only say the edge is
859
+ // in error if the override sets are plainly conflicting. Note that if
860
+ // the target doesn't have any dependencies of their own, then this
861
+ // inconsistency is irrelevant.
862
+ this.#safeError = 'INVALID';
980
863
  } else {
981
864
  this.#safeError = 'OK';
982
865
  }
@@ -988,17 +871,34 @@ class SafeEdge extends Edge {
988
871
  }
989
872
  reload(hard = false) {
990
873
  this.#safeExplanation = null;
874
+
875
+ // Patch adding newOverrideSet and oldOverrideSet is based on
876
+ // https://github.com/npm/cli/pull/7025.
877
+ let newOverrideSet;
878
+ let oldOverrideSet;
991
879
  if (this.#safeFrom?.overrides) {
992
- this.overrides = this.#safeFrom.overrides.getEdgeRule(this);
880
+ // Patch replacing
881
+ // this.overrides = this.#safeFrom.overrides.getEdgeRule(this)
882
+ // is based on https://github.com/npm/cli/pull/7025.
883
+ const newOverrideSet = this.#safeFrom.overrides.getEdgeRule(this);
884
+ if (newOverrideSet && !newOverrideSet.isEqual(this.overrides)) {
885
+ // If there's a new different override set we need to propagate it to
886
+ // the nodes. If we're deleting the override set then there's no point
887
+ // propagating it right now since it will be filled with another value
888
+ // later.
889
+ oldOverrideSet = this.overrides;
890
+ this.overrides = newOverrideSet;
891
+ }
993
892
  } else {
994
893
  this.overrides = undefined;
995
894
  }
996
895
  const newTo = this.#safeFrom?.resolve(this.name);
997
896
  if (newTo !== this.#safeTo) {
998
897
  if (this.#safeTo) {
999
- // Instead of `this.#safeTo.edgesIn.delete(this)` we patch based on
1000
- // https://github.com/npm/cli/pull/7025.
1001
- deleteEdgeIn(this.#safeTo, this);
898
+ // Patch replacing
899
+ // this.#safeTo.edgesIn.delete(this)
900
+ // is based on https://github.com/npm/cli/pull/7025.
901
+ this.#safeTo.deleteEdgeIn(this);
1002
902
  }
1003
903
  this.#safeTo = newTo ?? null;
1004
904
  this.#safeError = null;
@@ -1008,13 +908,21 @@ class SafeEdge extends Edge {
1008
908
  } else if (hard) {
1009
909
  this.#safeError = null;
1010
910
  }
911
+ // Patch adding "else if" condition based on
912
+ // https://github.com/npm/cli/pull/7025
913
+ else if (oldOverrideSet) {
914
+ // Propagate the new override set to the target node.
915
+ this.#safeTo.updateOverridesEdgeInRemoved(oldOverrideSet);
916
+ this.#safeTo.updateOverridesEdgeInAdded(newOverrideSet);
917
+ }
1011
918
  }
1012
919
  detach() {
1013
920
  this.#safeExplanation = null;
1014
921
  if (this.#safeTo) {
1015
- // Instead of `this.#safeTo.edgesIn.delete(this)` we patch based on
1016
- // https://github.com/npm/cli/pull/7025.
1017
- deleteEdgeIn(this.#safeTo, this);
922
+ // Patch replacing
923
+ // this.#safeTo.edgesIn.delete(this)
924
+ // is based on https://github.com/npm/cli/pull/7025.
925
+ this.#safeTo.deleteEdgeIn(this);
1018
926
  }
1019
927
  if (this.#safeFrom) {
1020
928
  this.#safeFrom.edgesOut.delete(this.name);
@@ -1034,6 +942,333 @@ class SafeEdge extends Edge {
1034
942
  return this.#safeTo;
1035
943
  }
1036
944
  }
945
+
946
+ // Implementation code not related to patch https://github.com/npm/cli/pull/7025
947
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/node.js:
948
+ class SafeNode extends Node {
949
+ // Is it safe to replace one node with another? check the edges to
950
+ // make sure no one will get upset. Note that the node might end up
951
+ // having its own unmet dependencies, if the new node has new deps.
952
+ // Note that there are cases where Arborist will opt to insert a node
953
+ // into the tree even though this function returns false! This is
954
+ // necessary when a root dependency is added or updated, or when a
955
+ // root dependency brings peer deps along with it. In that case, we
956
+ // will go ahead and create the invalid state, and then try to resolve
957
+ // it with more tree construction, because it's a user request.
958
+ canReplaceWith(node, ignorePeers) {
959
+ if (this.name !== node.name || this.packageName !== node.packageName) {
960
+ return false;
961
+ }
962
+ // Patch replacing
963
+ // if (node.overrides !== this.overrides) {
964
+ // return false
965
+ // }
966
+ // is based on https://github.com/npm/cli/pull/7025.
967
+ //
968
+ // If this node has no dependencies, then it's irrelevant to check the
969
+ // override rules of the replacement node.
970
+ if (this.edgesOut.size) {
971
+ // XXX need to check for two root nodes?
972
+ if (node.overrides) {
973
+ if (!node.overrides.isEqual(this.overrides)) {
974
+ return false;
975
+ }
976
+ } else {
977
+ if (this.overrides) {
978
+ return false;
979
+ }
980
+ }
981
+ }
982
+ // To satisfy the patch we ensure `node.overrides === this.overrides`
983
+ // so that the condition we want to replace,
984
+ // if (this.overrides !== node.overrides) {
985
+ // , is not hit.`
986
+ const oldOverrideSet = this.overrides;
987
+ let result = true;
988
+ if (oldOverrideSet !== node.overrides) {
989
+ this.overrides = node.overrides;
990
+ }
991
+ try {
992
+ result = super.canReplaceWith(node, ignorePeers);
993
+ this.overrides = oldOverrideSet;
994
+ } catch (e) {
995
+ this.overrides = oldOverrideSet;
996
+ throw e;
997
+ }
998
+ return result;
999
+ }
1000
+ deleteEdgeIn(edge) {
1001
+ this.edgesIn.delete(edge);
1002
+ const {
1003
+ overrides
1004
+ } = edge;
1005
+ if (overrides) {
1006
+ this.updateOverridesEdgeInRemoved(overrides);
1007
+ }
1008
+ }
1009
+ addEdgeIn(edge) {
1010
+ // Patch replacing
1011
+ // if (edge.overrides) {
1012
+ // this.overrides = edge.overrides
1013
+ // }
1014
+ // is based on https://github.com/npm/cli/pull/7025.
1015
+ //
1016
+ // We need to handle the case where the new edge in has an overrides field
1017
+ // which is different from the current value.
1018
+ if (!this.overrides || !this.overrides.isEqual(edge.overrides)) {
1019
+ this.updateOverridesEdgeInAdded(edge.overrides);
1020
+ }
1021
+ this.edgesIn.add(edge);
1022
+ // Try to get metadata from the yarn.lock file.
1023
+ this.root.meta?.addEdge(edge);
1024
+ }
1025
+
1026
+ // @ts-ignore: Incorrectly typed as a property instead of an accessor.
1027
+ get overridden() {
1028
+ // Patch replacing
1029
+ // return !!(this.overrides && this.overrides.value && this.overrides.name === this.name)
1030
+ // is based on https://github.com/npm/cli/pull/7025.
1031
+ if (!this.overrides || !this.overrides.value || this.overrides.name !== this.name) {
1032
+ return false;
1033
+ }
1034
+ // The overrides rule is for a package with this name, but some override rules
1035
+ // only apply to specific versions. To make sure this package was actually
1036
+ // overridden, we check whether any edge going in had the rule applied to it,
1037
+ // in which case its overrides set is different than its source node.
1038
+ for (const edge of this.edgesIn) {
1039
+ if (this.overrides.isEqual(edge.overrides)) {
1040
+ if (!edge.overrides?.isEqual(edge.from?.overrides)) {
1041
+ return true;
1042
+ }
1043
+ }
1044
+ }
1045
+ return false;
1046
+ }
1047
+
1048
+ // Patch adding recalculateOutEdgesOverrides is based on
1049
+ // https://github.com/npm/cli/pull/7025.
1050
+ recalculateOutEdgesOverrides() {
1051
+ // For each edge out propagate the new overrides through.
1052
+ for (const edge of this.edgesOut.values()) {
1053
+ edge.reload(true);
1054
+ if (edge.to) {
1055
+ edge.to.updateOverridesEdgeInAdded(edge.overrides);
1056
+ }
1057
+ }
1058
+ }
1059
+
1060
+ // @ts-ignore: Incorrectly typed to accept null.
1061
+ set root(newRoot) {
1062
+ // Patch removing
1063
+ // if (!this.overrides && this.parent && this.parent.overrides) {
1064
+ // this.overrides = this.parent.overrides.getNodeRule(this)
1065
+ // }
1066
+ // is based on https://github.com/npm/cli/pull/7025.
1067
+ //
1068
+ // The "root" setter is a really large and complex function. To satisfy the
1069
+ // patch we add a dummy value to `this.overrides` so that the condition we
1070
+ // want to remove,
1071
+ // if (!this.overrides && this.parent && this.parent.overrides) {
1072
+ // , is not hit.
1073
+ if (!this.overrides) {
1074
+ this.overrides = new OverrideSet({
1075
+ overrides: ''
1076
+ });
1077
+ }
1078
+ try {
1079
+ super.root = newRoot;
1080
+ this.overrides = undefined;
1081
+ } catch (e) {
1082
+ this.overrides = undefined;
1083
+ throw e;
1084
+ }
1085
+ }
1086
+
1087
+ // Patch adding updateOverridesEdgeInAdded is based on
1088
+ // https://github.com/npm/cli/pull/7025.
1089
+ //
1090
+ // This logic isn't perfect either. When we have two edges in that have
1091
+ // different override sets, then we have to decide which set is correct. This
1092
+ // function assumes the more specific override set is applicable, so if we have
1093
+ // dependencies A->B->C and A->C and an override set that specifies what happens
1094
+ // for C under A->B, this will work even if the new A->C edge comes along and
1095
+ // tries to change the override set. The strictly correct logic is not to allow
1096
+ // two edges with different overrides to point to the same node, because even
1097
+ // if this node can satisfy both, one of its dependencies might need to be
1098
+ // different depending on the edge leading to it. However, this might cause a
1099
+ // lot of duplication, because the conflict in the dependencies might never
1100
+ // actually happen.
1101
+ updateOverridesEdgeInAdded(otherOverrideSet) {
1102
+ if (!otherOverrideSet) {
1103
+ // Assuming there are any overrides at all, the overrides field is never
1104
+ // undefined for any node at the end state of the tree. So if the new edge's
1105
+ // overrides is undefined it will be updated later. So we can wait with
1106
+ // updating the node's overrides field.
1107
+ return false;
1108
+ }
1109
+ if (!this.overrides) {
1110
+ this.overrides = otherOverrideSet;
1111
+ this.recalculateOutEdgesOverrides();
1112
+ return true;
1113
+ }
1114
+ if (this.overrides.isEqual(otherOverrideSet)) {
1115
+ return false;
1116
+ }
1117
+ const newOverrideSet = findSpecificOverrideSet(this.overrides, otherOverrideSet);
1118
+ if (newOverrideSet) {
1119
+ if (this.overrides.isEqual(newOverrideSet)) {
1120
+ return false;
1121
+ }
1122
+ this.overrides = newOverrideSet;
1123
+ this.recalculateOutEdgesOverrides();
1124
+ return true;
1125
+ }
1126
+ // This is an error condition. We can only get here if the new override set is
1127
+ // in conflict with the existing.
1128
+ console.error('Conflicting override sets');
1129
+ return false;
1130
+ }
1131
+
1132
+ // Patch adding updateOverridesEdgeInRemoved is based on
1133
+ // https://github.com/npm/cli/pull/7025.
1134
+ updateOverridesEdgeInRemoved(otherOverrideSet) {
1135
+ // If this edge's overrides isn't equal to this node's overrides,
1136
+ // then removing it won't change newOverrideSet later.
1137
+ if (!this.overrides || !this.overrides.isEqual(otherOverrideSet)) {
1138
+ return false;
1139
+ }
1140
+ let newOverrideSet;
1141
+ for (const edge of this.edgesIn) {
1142
+ const {
1143
+ overrides: edgeOverrides
1144
+ } = edge;
1145
+ if (newOverrideSet && edgeOverrides) {
1146
+ newOverrideSet = findSpecificOverrideSet(edgeOverrides, newOverrideSet);
1147
+ } else {
1148
+ newOverrideSet = edgeOverrides;
1149
+ }
1150
+ }
1151
+ if (this.overrides.isEqual(newOverrideSet)) {
1152
+ return false;
1153
+ }
1154
+ this.overrides = newOverrideSet;
1155
+ if (newOverrideSet) {
1156
+ // Optimization: If there's any override set at all, then no non-extraneous
1157
+ // node has an empty override set. So if we temporarily have no override set
1158
+ // (for example, we removed all the edges in), there's no use updating all
1159
+ // the edges out right now. Let's just wait until we have an actual override
1160
+ // set later.
1161
+ this.recalculateOutEdgesOverrides();
1162
+ }
1163
+ return true;
1164
+ }
1165
+ }
1166
+
1167
+ // Implementation code not related to patch https://github.com/npm/cli/pull/7025
1168
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/override-set.js:
1169
+ class SafeOverrideSet extends OverrideSet {
1170
+ // Patch adding childrenAreEqual is based on
1171
+ // https://github.com/npm/cli/pull/7025.
1172
+ childrenAreEqual(otherOverrideSet) {
1173
+ const queue = [[this, otherOverrideSet]];
1174
+ let pos = 0;
1175
+ let {
1176
+ length: queueLength
1177
+ } = queue;
1178
+ while (pos < queueLength) {
1179
+ if (pos === LOOP_SENTINEL) {
1180
+ throw new Error('Detected infinite loop while comparing override sets');
1181
+ }
1182
+ const {
1183
+ 0: currSet,
1184
+ 1: currOtherSet
1185
+ } = queue[pos++];
1186
+ const {
1187
+ children
1188
+ } = currSet;
1189
+ const {
1190
+ children: otherChildren
1191
+ } = currOtherSet;
1192
+ if (children.size !== otherChildren.size) {
1193
+ return false;
1194
+ }
1195
+ for (const key of children.keys()) {
1196
+ if (!otherChildren.has(key)) {
1197
+ return false;
1198
+ }
1199
+ const child = children.get(key);
1200
+ const otherChild = otherChildren.get(key);
1201
+ if (child.value !== otherChild.value) {
1202
+ return false;
1203
+ }
1204
+ queue[queueLength++] = [child, otherChild];
1205
+ }
1206
+ }
1207
+ return true;
1208
+ }
1209
+ getEdgeRule(edge) {
1210
+ for (const rule of this.ruleset.values()) {
1211
+ if (rule.name !== edge.name) {
1212
+ continue;
1213
+ }
1214
+ // If keySpec is * we found our override.
1215
+ if (rule.keySpec === '*') {
1216
+ return rule;
1217
+ }
1218
+ // Patch replacing
1219
+ // let spec = npa(`${edge.name}@${edge.spec}`)
1220
+ // is based on https://github.com/npm/cli/pull/7025.
1221
+ //
1222
+ // We need to use the rawSpec here, because the spec has the overrides
1223
+ // applied to it already.
1224
+ let spec = _npmPackageArg(`${edge.name}@${edge.rawSpec}`);
1225
+ if (spec.type === 'alias') {
1226
+ spec = spec.subSpec;
1227
+ }
1228
+ if (spec.type === 'git') {
1229
+ if (spec.gitRange && rule.keySpec && _semver.intersects(spec.gitRange, rule.keySpec)) {
1230
+ return rule;
1231
+ }
1232
+ continue;
1233
+ }
1234
+ if (spec.type === 'range' || spec.type === 'version') {
1235
+ if (rule.keySpec && _semver.intersects(spec.fetchSpec, rule.keySpec)) {
1236
+ return rule;
1237
+ }
1238
+ continue;
1239
+ }
1240
+ // If we got this far, the spec type is one of tag, directory or file
1241
+ // which means we have no real way to make version comparisons, so we
1242
+ // just accept the override.
1243
+ return rule;
1244
+ }
1245
+ return this;
1246
+ }
1247
+
1248
+ // Patch adding isEqual is based on
1249
+ // https://github.com/npm/cli/pull/7025.
1250
+ isEqual(otherOverrideSet) {
1251
+ if (this === otherOverrideSet) {
1252
+ return true;
1253
+ }
1254
+ if (!otherOverrideSet) {
1255
+ return false;
1256
+ }
1257
+ if (this.key !== otherOverrideSet.key || this.value !== otherOverrideSet.value) {
1258
+ return false;
1259
+ }
1260
+ if (!this.childrenAreEqual(otherOverrideSet)) {
1261
+ return false;
1262
+ }
1263
+ if (!this.parent) {
1264
+ return !otherOverrideSet.parent;
1265
+ }
1266
+ return this.parent.isEqual(otherOverrideSet.parent);
1267
+ }
1268
+ }
1269
+
1270
+ // Implementation code not related to our custom behavior is based on
1271
+ // https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/arborist/index.js:
1037
1272
  class SafeArborist extends Arborist {
1038
1273
  constructor(...ctorArgs) {
1039
1274
  const mutedArguments = [{
@@ -1135,8 +1370,10 @@ class SafeArborist extends Arborist {
1135
1370
  }
1136
1371
  arborist.SafeArborist = SafeArborist;
1137
1372
  function installSafeArborist() {
1138
- require.cache[arboristEdgeClassPath].exports = SafeEdge;
1139
1373
  require.cache[arboristClassPath].exports = SafeArborist;
1374
+ require.cache[arboristEdgeClassPath].exports = SafeEdge;
1375
+ require.cache[arboristNodeClassPath].exports = SafeNode;
1376
+ require.cache[arboristOverrideSetClassPatch].exports = SafeOverrideSet;
1140
1377
  }
1141
1378
  void (async () => {
1142
1379
  const remoteSettings = await (async () => {
@@ -1152,11 +1389,9 @@ void (async () => {
1152
1389
  orgs.push(org);
1153
1390
  }
1154
1391
  }
1155
- const result = await socketSdk.postSettings(orgs.map(org => {
1156
- return {
1157
- organization: org.id
1158
- };
1159
- }));
1392
+ const result = await socketSdk.postSettings(orgs.map(org => ({
1393
+ organization: org.id
1394
+ })));
1160
1395
  if (!result.success) {
1161
1396
  throw new Error('Failed to fetch API key settings: ' + result.error.message);
1162
1397
  }
@@ -1165,7 +1400,7 @@ void (async () => {
1165
1400
  settings: result.data
1166
1401
  };
1167
1402
  } catch (e) {
1168
- if (typeof e === 'object' && e !== null && 'cause' in e) {
1403
+ if ((0, _objects.isObject)(e) && 'cause' in e) {
1169
1404
  const {
1170
1405
  cause
1171
1406
  } = e;
@@ -1186,7 +1421,7 @@ void (async () => {
1186
1421
  } = remoteSettings;
1187
1422
  const enforcedOrgs = (0, _settings.getSetting)('enforcedOrgs') ?? [];
1188
1423
 
1189
- // remove any organizations not being enforced
1424
+ // Remove any organizations not being enforced.
1190
1425
  for (const {
1191
1426
  0: i,
1192
1427
  1: org
package/dist/sdk.d.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  /// <reference types="node" />
2
2
  import { SocketSdk } from '@socketsecurity/sdk';
3
+ declare function hasOwn(obj: any, propKey: PropertyKey): boolean;
4
+ declare function isObject(value: any): value is object;
5
+ declare function isObjectObject(value: any): value is {
6
+ [key: string]: any;
7
+ };
8
+ declare function objectSome(obj: Record<string, any>): boolean;
9
+ declare function pick<T extends Record<string, any>, K extends keyof T>(input: T, keys: K[] | ReadonlyArray<K>): Pick<T, K>;
3
10
  declare function createDebugLogger(printDebugLogs?: boolean): typeof console.error;
4
11
  declare function isErrnoException(value: unknown): value is NodeJS.ErrnoException;
5
12
  declare function stringJoinWithSeparateFinalSeparator(list: (string | undefined)[], separator?: string): string;
@@ -10,4 +17,4 @@ declare const ENV: Readonly<{
10
17
  declare const FREE_API_KEY = "sktsec_t_--RAN5U4ivauy4w37-6aoKyYPDt5ZbaT5JBVMqiwKo_api";
11
18
  declare function getDefaultKey(): string | undefined;
12
19
  declare function setupSdk(apiKey?: string | undefined, apiBaseUrl?: string | undefined, proxy?: string | undefined): Promise<SocketSdk>;
13
- export { createDebugLogger, isErrnoException, stringJoinWithSeparateFinalSeparator, API_V0_URL, ENV, FREE_API_KEY, getDefaultKey, setupSdk };
20
+ export { hasOwn, isObject, isObjectObject, objectSome, pick, createDebugLogger, isErrnoException, stringJoinWithSeparateFinalSeparator, API_V0_URL, ENV, FREE_API_KEY, getDefaultKey, setupSdk };
package/dist/sdk.js CHANGED
@@ -143,6 +143,42 @@ function stringJoinWithSeparateFinalSeparator(list, separator = ' and ') {
143
143
  return values.join(', ') + separator + finalValue;
144
144
  }
145
145
 
146
+ var objects = {};
147
+
148
+ Object.defineProperty(objects, "__esModule", {
149
+ value: true
150
+ });
151
+ objects.hasOwn = hasOwn;
152
+ objects.isObject = isObject;
153
+ objects.isObjectObject = isObjectObject;
154
+ objects.objectSome = objectSome;
155
+ objects.pick = pick;
156
+ function hasOwn(obj, propKey) {
157
+ if (obj === null || obj === undefined) return false;
158
+ return Object.hasOwn(obj, propKey);
159
+ }
160
+ function isObject(value) {
161
+ return value !== null && typeof value === 'object';
162
+ }
163
+ function isObjectObject(value) {
164
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
165
+ }
166
+ function objectSome(obj) {
167
+ for (const key in obj) {
168
+ if (obj[key]) {
169
+ return true;
170
+ }
171
+ }
172
+ return false;
173
+ }
174
+ function pick(input, keys) {
175
+ const result = {};
176
+ for (const key of keys) {
177
+ result[key] = input[key];
178
+ }
179
+ return result;
180
+ }
181
+
146
182
  var sdk = {};
147
183
 
148
184
  var settings$1 = {};
@@ -266,5 +302,6 @@ exports.chalkMarkdown = chalkMarkdown;
266
302
  exports.constants = constants;
267
303
  exports.errors = errors;
268
304
  exports.misc = misc;
305
+ exports.objects = objects;
269
306
  exports.sdk = sdk;
270
307
  exports.settings = settings$1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket",
3
- "version": "0.14.14",
3
+ "version": "0.14.16",
4
4
  "description": "CLI tool for Socket.dev",
5
5
  "homepage": "http://github.com/SocketDev/socket-cli",
6
6
  "license": "MIT",
@@ -118,7 +118,6 @@
118
118
  "eslint-plugin-depend": "^0.11.0",
119
119
  "eslint-plugin-n": "^17.11.1",
120
120
  "eslint-plugin-unicorn": "^56.0.0",
121
- "globby": "^14.0.2",
122
121
  "husky": "^9.1.6",
123
122
  "is-interactive": "^2.0.0",
124
123
  "is-unicode-supported": "^2.1.0",
@@ -161,9 +160,11 @@
161
160
  "indent-string": "npm:@socketregistry/indent-string@^1",
162
161
  "is-core-module": "npm:@socketregistry/is-core-module@^1",
163
162
  "isarray": "npm:@socketregistry/isarray@^1",
163
+ "npm-package-arg": "$npm-package-arg",
164
164
  "path-parse": "npm:@socketregistry/path-parse@^1",
165
165
  "safe-buffer": "npm:@socketregistry/safe-buffer@^1",
166
166
  "safer-buffer": "npm:@socketregistry/safer-buffer@^1",
167
+ "semver": "$semver",
167
168
  "set-function-length": "npm:@socketregistry/set-function-length@^1",
168
169
  "side-channel": "npm:@socketregistry/side-channel@^1"
169
170
  },
@@ -180,9 +181,11 @@
180
181
  "indent-string": "npm:@socketregistry/indent-string@^1",
181
182
  "is-core-module": "npm:@socketregistry/is-core-module@^1",
182
183
  "isarray": "npm:@socketregistry/isarray@^1",
184
+ "npm-package-arg": "^12.0.0",
183
185
  "path-parse": "npm:@socketregistry/path-parse@^1",
184
186
  "safe-buffer": "npm:@socketregistry/safe-buffer@^1",
185
187
  "safer-buffer": "npm:@socketregistry/safer-buffer@^1",
188
+ "semver": "^7.6.3",
186
189
  "set-function-length": "npm:@socketregistry/set-function-length@^1",
187
190
  "side-channel": "npm:@socketregistry/side-channel@^1"
188
191
  },