socket 0.14.14 → 0.14.15

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,10 @@ 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 sdk = require('./sdk.js');
13
14
  var require$$1$1 = require('node:net');
14
15
  var require$$2 = require('node:os');
15
16
  var require$$6 = require('../package.json');
16
- var sdk = require('./sdk.js');
17
17
  var pathResolve = require('./path-resolve.js');
18
18
  var require$$8 = require('pacote');
19
19
 
@@ -393,14 +393,15 @@ var _config = require$$3$1;
393
393
  var _chalk = _interopRequireDefault(vendor.source);
394
394
  var _isInteractive = _interopRequireDefault(vendor.isInteractive);
395
395
  var _ora = _interopRequireWildcard(vendor.ora);
396
+ var _constants = sdk.constants;
396
397
  var _ttyServer = ttyServer$1;
397
398
  var _chalkMarkdown = sdk.chalkMarkdown;
398
399
  var _issueRules = issueRules;
399
400
  var _misc = sdk.misc;
401
+ var _objects = sdk.objects;
400
402
  var _pathResolve = pathResolve.pathResolve;
401
403
  var _sdk = sdk.sdk;
402
404
  var _settings = sdk.settings;
403
- var _constants = sdk.constants;
404
405
  const LOOP_SENTINEL = 1_000_000;
405
406
  const POTENTIALLY_BUG_ERROR_SNIPPET = 'this is potentially a bug with socket-npm caused by changes to the npm cli';
406
407
  const distPath$1 = __dirname;
@@ -420,6 +421,8 @@ if (npmRootPath === undefined) {
420
421
  const npmNmPath = _nodePath$1.join(npmRootPath, 'node_modules');
421
422
  const arboristClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/arborist/index.js');
422
423
  const arboristEdgeClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/edge.js');
424
+ const arboristNodeClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/node.js');
425
+ const arboristOverrideSetClassPatch = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/override-set.js');
423
426
  let npmlog;
424
427
  try {
425
428
  npmlog = require(_nodePath$1.join(npmNmPath, 'proc-log/lib/index.js')).log;
@@ -441,6 +444,8 @@ try {
441
444
  }
442
445
  const Arborist = require(arboristClassPath);
443
446
  const Edge = require(arboristEdgeClassPath);
447
+ const Node = require(arboristNodeClassPath);
448
+ const OverrideSet = require(arboristOverrideSetClassPatch);
444
449
  const kCtorArgs = Symbol('ctorArgs');
445
450
  const kRiskyReify = Symbol('riskyReify');
446
451
  const formatter = new _chalkMarkdown.ChalkOrMarkdown(false);
@@ -493,15 +498,6 @@ async function* batchScan(pkgIds) {
493
498
  yield JSON.parse(line);
494
499
  }
495
500
  }
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
501
  function findSocketYmlSync() {
506
502
  let prevDir = null;
507
503
  let dir = process.cwd();
@@ -527,17 +523,20 @@ function findSocketYmlSync() {
527
523
  }
528
524
  return null;
529
525
  }
526
+
527
+ // Patch adding findSpecificOverrideSet is based on
528
+ // https://github.com/npm/cli/pull/7025.
530
529
  function findSpecificOverrideSet(first, second) {
531
530
  let overrideSet = second;
532
531
  while (overrideSet) {
533
- if (overrideSetsEqual(overrideSet, first)) {
532
+ if (overrideSet.isEqual(first)) {
534
533
  return second;
535
534
  }
536
535
  overrideSet = overrideSet.parent;
537
536
  }
538
537
  overrideSet = first;
539
538
  while (overrideSet) {
540
- if (overrideSetsEqual(overrideSet, second)) {
539
+ if (overrideSet.isEqual(second)) {
541
540
  return first;
542
541
  }
543
542
  overrideSet = overrideSet.parent;
@@ -551,61 +550,6 @@ function maybeReadfileSync(filepath) {
551
550
  } catch {}
552
551
  return undefined;
553
552
  }
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
553
  async function packagesHaveRiskyIssues(safeArb, _registry, pkgs, output) {
610
554
  let result = false;
611
555
  let remaining = pkgs.length;
@@ -722,15 +666,6 @@ function pkgidParts(pkgid) {
722
666
  version
723
667
  };
724
668
  }
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
669
  function toPURL(pkgid, resolved) {
735
670
  const repo = resolved.replace(/#[\s\S]*$/u, '').replace(/\?[\s\S]*$/u, '').replace(/\/[^/]*\/-\/[\s\S]*$/u, '');
736
671
  const {
@@ -744,84 +679,6 @@ function toPURL(pkgid, resolved) {
744
679
  repository_url: repo
745
680
  };
746
681
  }
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
682
  function walk(diff_, needInfoOn = []) {
826
683
  const queue = [diff_];
827
684
  let pos = 0;
@@ -869,15 +726,18 @@ function walk(diff_, needInfoOn = []) {
869
726
  return needInfoOn;
870
727
  }
871
728
 
872
- // Copied from
873
- // https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/edge.js:
729
+ // The Edge class makes heavy use of private properties which subclasses do NOT
730
+ // have access to. So we have to recreate any functionality that relies on those
731
+ // private properties and use our own "safe" prefixed non-conflicting private
732
+ // properties. Implementation code not related to patch https://github.com/npm/cli/pull/7025
733
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/edge.js.
734
+ //
874
735
  // The npm application
875
736
  // Copyright (c) npm, Inc. and Contributors
876
737
  // Licensed on the terms of The Artistic License 2.0
877
738
  //
878
739
  // An edge in the dependency graph.
879
740
  // Represents a dependency relationship of some kind.
880
-
881
741
  class SafeEdge extends Edge {
882
742
  #safeAccept;
883
743
  #safeError;
@@ -939,11 +799,20 @@ class SafeEdge extends Edge {
939
799
  // @ts-ignore: Incorrectly typed as a property instead of an accessor.
940
800
  get spec() {
941
801
  if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this.name) {
802
+ // Patch adding "if" condition is based on
803
+ // https://github.com/npm/cli/pull/7025.
804
+ //
805
+ // If this edge has the same overrides field as the source, then we're not
806
+ // applying an override for this edge.
807
+ if (this.overrides === this.#safeFrom?.overrides) {
808
+ // The Edge rawSpec getter will retrieve the private Edge #spec property.
809
+ return this.rawSpec;
810
+ }
942
811
  if (this.overrides.value.startsWith('$')) {
943
812
  const ref = this.overrides.value.slice(1);
944
813
  // We may be a virtual root, if we are we want to resolve reference
945
814
  // overrides from the real root, not the virtual one.
946
- const pkg = this.#safeFrom?.sourceReference ? this.#safeFrom.sourceReference.root.package : this.#safeFrom?.root.package;
815
+ const pkg = this.#safeFrom?.sourceReference ? this.#safeFrom.sourceReference.root.package : this.#safeFrom?.root?.package;
947
816
  if (pkg?.devDependencies?.[ref]) {
948
817
  return pkg.devDependencies[ref];
949
818
  }
@@ -977,6 +846,16 @@ class SafeEdge extends Edge {
977
846
  this.#safeError = 'PEER LOCAL';
978
847
  } else if (!this.satisfiedBy(this.#safeTo)) {
979
848
  this.#safeError = 'INVALID';
849
+ }
850
+ // Patch adding "else if" condition is based on
851
+ // https://github.com/npm/cli/pull/7025.
852
+ else if (this.overrides && this.#safeTo.edgesOut.size && !findSpecificOverrideSet(this.overrides, this.#safeTo.overrides)) {
853
+ // Any inconsistency between the edge's override set and the target's
854
+ // override set is potentially problematic. But we only say the edge is
855
+ // in error if the override sets are plainly conflicting. Note that if
856
+ // the target doesn't have any dependencies of their own, then this
857
+ // inconsistency is irrelevant.
858
+ this.#safeError = 'INVALID';
980
859
  } else {
981
860
  this.#safeError = 'OK';
982
861
  }
@@ -988,17 +867,34 @@ class SafeEdge extends Edge {
988
867
  }
989
868
  reload(hard = false) {
990
869
  this.#safeExplanation = null;
870
+
871
+ // Patch adding newOverrideSet and oldOverrideSet is based on
872
+ // https://github.com/npm/cli/pull/7025.
873
+ let newOverrideSet;
874
+ let oldOverrideSet;
991
875
  if (this.#safeFrom?.overrides) {
992
- this.overrides = this.#safeFrom.overrides.getEdgeRule(this);
876
+ // Patch replacing
877
+ // this.overrides = this.#safeFrom.overrides.getEdgeRule(this)
878
+ // is based on https://github.com/npm/cli/pull/7025.
879
+ const newOverrideSet = this.#safeFrom.overrides.getEdgeRule(this);
880
+ if (newOverrideSet && !newOverrideSet.isEqual(this.overrides)) {
881
+ // If there's a new different override set we need to propagate it to
882
+ // the nodes. If we're deleting the override set then there's no point
883
+ // propagating it right now since it will be filled with another value
884
+ // later.
885
+ oldOverrideSet = this.overrides;
886
+ this.overrides = newOverrideSet;
887
+ }
993
888
  } else {
994
889
  this.overrides = undefined;
995
890
  }
996
891
  const newTo = this.#safeFrom?.resolve(this.name);
997
892
  if (newTo !== this.#safeTo) {
998
893
  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);
894
+ // Patch replacing
895
+ // this.#safeTo.edgesIn.delete(this)
896
+ // is based on https://github.com/npm/cli/pull/7025.
897
+ this.#safeTo.deleteEdgeIn(this);
1002
898
  }
1003
899
  this.#safeTo = newTo ?? null;
1004
900
  this.#safeError = null;
@@ -1008,13 +904,21 @@ class SafeEdge extends Edge {
1008
904
  } else if (hard) {
1009
905
  this.#safeError = null;
1010
906
  }
907
+ // Patch adding "else if" condition based on
908
+ // https://github.com/npm/cli/pull/7025
909
+ else if (oldOverrideSet) {
910
+ // Propagate the new override set to the target node.
911
+ this.#safeTo.updateOverridesEdgeInRemoved(oldOverrideSet);
912
+ this.#safeTo.updateOverridesEdgeInAdded(newOverrideSet);
913
+ }
1011
914
  }
1012
915
  detach() {
1013
916
  this.#safeExplanation = null;
1014
917
  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);
918
+ // Patch replacing
919
+ // this.#safeTo.edgesIn.delete(this)
920
+ // is based on https://github.com/npm/cli/pull/7025.
921
+ this.#safeTo.deleteEdgeIn(this);
1018
922
  }
1019
923
  if (this.#safeFrom) {
1020
924
  this.#safeFrom.edgesOut.delete(this.name);
@@ -1034,6 +938,295 @@ class SafeEdge extends Edge {
1034
938
  return this.#safeTo;
1035
939
  }
1036
940
  }
941
+
942
+ // Implementation code not related to patch https://github.com/npm/cli/pull/7025
943
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/node.js:
944
+ class SafeNode extends Node {
945
+ // Is it safe to replace one node with another? check the edges to
946
+ // make sure no one will get upset. Note that the node might end up
947
+ // having its own unmet dependencies, if the new node has new deps.
948
+ // Note that there are cases where Arborist will opt to insert a node
949
+ // into the tree even though this function returns false! This is
950
+ // necessary when a root dependency is added or updated, or when a
951
+ // root dependency brings peer deps along with it. In that case, we
952
+ // will go ahead and create the invalid state, and then try to resolve
953
+ // it with more tree construction, because it's a user request.
954
+ canReplaceWith(node, ignorePeers) {
955
+ if (this.name !== node.name || this.packageName !== node.packageName) {
956
+ return false;
957
+ }
958
+ // Patch replacing
959
+ // if (node.overrides !== this.overrides) {
960
+ // return false
961
+ // }
962
+ // is based on https://github.com/npm/cli/pull/7025.
963
+ //
964
+ // If this node has no dependencies, then it's irrelevant to check the
965
+ // override rules of the replacement node.
966
+ if (this.edgesOut.size) {
967
+ // XXX need to check for two root nodes?
968
+ if (node.overrides) {
969
+ if (!node.overrides.isEqual(this.overrides)) {
970
+ return false;
971
+ }
972
+ } else {
973
+ if (this.overrides) {
974
+ return false;
975
+ }
976
+ }
977
+ }
978
+ // To satisfy the patch we ensure `node.overrides === this.overrides`
979
+ // so that the condition we want to replace,
980
+ // if (this.overrides !== node.overrides) {
981
+ // , is not hit.`
982
+ const oldOverrideSet = this.overrides;
983
+ let result = true;
984
+ if (oldOverrideSet !== node.overrides) {
985
+ this.overrides = node.overrides;
986
+ }
987
+ try {
988
+ result = super.canReplaceWith(node, ignorePeers);
989
+ this.overrides = oldOverrideSet;
990
+ } catch (e) {
991
+ this.overrides = oldOverrideSet;
992
+ throw e;
993
+ }
994
+ return result;
995
+ }
996
+ deleteEdgeIn(edge) {
997
+ this.edgesIn.delete(edge);
998
+ const {
999
+ overrides
1000
+ } = edge;
1001
+ if (overrides) {
1002
+ this.updateOverridesEdgeInRemoved(overrides);
1003
+ }
1004
+ }
1005
+ addEdgeIn(edge) {
1006
+ // Patch replacing
1007
+ // if (edge.overrides) {
1008
+ // this.overrides = edge.overrides
1009
+ // }
1010
+ // is based on https://github.com/npm/cli/pull/7025.
1011
+ //
1012
+ // We need to handle the case where the new edge in has an overrides field
1013
+ // which is different from the current value.
1014
+ if (!this.overrides || !this.overrides.isEqual(edge.overrides)) {
1015
+ this.updateOverridesEdgeInAdded(edge.overrides);
1016
+ }
1017
+ this.edgesIn.add(edge);
1018
+ // Try to get metadata from the yarn.lock file.
1019
+ this.root.meta?.addEdge(edge);
1020
+ }
1021
+
1022
+ // @ts-ignore: Incorrectly typed as a property instead of an accessor.
1023
+ get overridden() {
1024
+ // Patch replacing
1025
+ // return !!(this.overrides && this.overrides.value && this.overrides.name === this.name)
1026
+ // is based on https://github.com/npm/cli/pull/7025.
1027
+ if (!this.overrides || !this.overrides.value || this.overrides.name !== this.name) {
1028
+ return false;
1029
+ }
1030
+ // The overrides rule is for a package with this name, but some override rules
1031
+ // only apply to specific versions. To make sure this package was actually
1032
+ // overridden, we check whether any edge going in had the rule applied to it,
1033
+ // in which case its overrides set is different than its source node.
1034
+ for (const edge of this.edgesIn) {
1035
+ if (this.overrides.isEqual(edge.overrides)) {
1036
+ if (!edge.overrides?.isEqual(edge.from?.overrides)) {
1037
+ return true;
1038
+ }
1039
+ }
1040
+ }
1041
+ return false;
1042
+ }
1043
+
1044
+ // Patch adding recalculateOutEdgesOverrides is based on
1045
+ // https://github.com/npm/cli/pull/7025.
1046
+ recalculateOutEdgesOverrides() {
1047
+ // For each edge out propagate the new overrides through.
1048
+ for (const edge of this.edgesOut.values()) {
1049
+ edge.reload(true);
1050
+ if (edge.to) {
1051
+ edge.to.updateOverridesEdgeInAdded(edge.overrides);
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ // @ts-ignore: Incorrectly typed to accept null.
1057
+ set root(newRoot) {
1058
+ // Patch removing
1059
+ // if (!this.overrides && this.parent && this.parent.overrides) {
1060
+ // this.overrides = this.parent.overrides.getNodeRule(this)
1061
+ // }
1062
+ // is based on https://github.com/npm/cli/pull/7025.
1063
+ //
1064
+ // The "root" setter is a really large and complex function. To satisfy the
1065
+ // patch we add a dummy value to `this.overrides` so that the condition we
1066
+ // want to remove,
1067
+ // if (!this.overrides && this.parent && this.parent.overrides) {
1068
+ // , is not hit.
1069
+ if (!this.overrides) {
1070
+ this.overrides = new OverrideSet({
1071
+ overrides: ''
1072
+ });
1073
+ }
1074
+ try {
1075
+ super.root = newRoot;
1076
+ this.overrides = undefined;
1077
+ } catch (e) {
1078
+ this.overrides = undefined;
1079
+ throw e;
1080
+ }
1081
+ }
1082
+
1083
+ // Patch adding updateOverridesEdgeInAdded is based on
1084
+ // https://github.com/npm/cli/pull/7025.
1085
+ //
1086
+ // This logic isn't perfect either. When we have two edges in that have
1087
+ // different override sets, then we have to decide which set is correct. This
1088
+ // function assumes the more specific override set is applicable, so if we have
1089
+ // dependencies A->B->C and A->C and an override set that specifies what happens
1090
+ // for C under A->B, this will work even if the new A->C edge comes along and
1091
+ // tries to change the override set. The strictly correct logic is not to allow
1092
+ // two edges with different overrides to point to the same node, because even
1093
+ // if this node can satisfy both, one of its dependencies might need to be
1094
+ // different depending on the edge leading to it. However, this might cause a
1095
+ // lot of duplication, because the conflict in the dependencies might never
1096
+ // actually happen.
1097
+ updateOverridesEdgeInAdded(otherOverrideSet) {
1098
+ if (!otherOverrideSet) {
1099
+ // Assuming there are any overrides at all, the overrides field is never
1100
+ // undefined for any node at the end state of the tree. So if the new edge's
1101
+ // overrides is undefined it will be updated later. So we can wait with
1102
+ // updating the node's overrides field.
1103
+ return false;
1104
+ }
1105
+ if (!this.overrides) {
1106
+ this.overrides = otherOverrideSet;
1107
+ this.recalculateOutEdgesOverrides();
1108
+ return true;
1109
+ }
1110
+ if (this.overrides.isEqual(otherOverrideSet)) {
1111
+ return false;
1112
+ }
1113
+ const newOverrideSet = findSpecificOverrideSet(this.overrides, otherOverrideSet);
1114
+ if (newOverrideSet) {
1115
+ if (this.overrides.isEqual(newOverrideSet)) {
1116
+ return false;
1117
+ }
1118
+ this.overrides = newOverrideSet;
1119
+ this.recalculateOutEdgesOverrides();
1120
+ return true;
1121
+ }
1122
+ // This is an error condition. We can only get here if the new override set is
1123
+ // in conflict with the existing.
1124
+ console.error('Conflicting override sets');
1125
+ return false;
1126
+ }
1127
+
1128
+ // Patch adding updateOverridesEdgeInRemoved is based on
1129
+ // https://github.com/npm/cli/pull/7025.
1130
+ updateOverridesEdgeInRemoved(otherOverrideSet) {
1131
+ // If this edge's overrides isn't equal to this node's overrides,
1132
+ // then removing it won't change newOverrideSet later.
1133
+ if (!this.overrides || !this.overrides.isEqual(otherOverrideSet)) {
1134
+ return false;
1135
+ }
1136
+ let newOverrideSet;
1137
+ for (const edge of this.edgesIn) {
1138
+ const {
1139
+ overrides: edgeOverrides
1140
+ } = edge;
1141
+ if (newOverrideSet && edgeOverrides) {
1142
+ newOverrideSet = findSpecificOverrideSet(edgeOverrides, newOverrideSet);
1143
+ } else {
1144
+ newOverrideSet = edgeOverrides;
1145
+ }
1146
+ }
1147
+ if (this.overrides.isEqual(newOverrideSet)) {
1148
+ return false;
1149
+ }
1150
+ this.overrides = newOverrideSet;
1151
+ if (newOverrideSet) {
1152
+ // Optimization: If there's any override set at all, then no non-extraneous
1153
+ // node has an empty override set. So if we temporarily have no override set
1154
+ // (for example, we removed all the edges in), there's no use updating all
1155
+ // the edges out right now. Let's just wait until we have an actual override
1156
+ // set later.
1157
+ this.recalculateOutEdgesOverrides();
1158
+ }
1159
+ return true;
1160
+ }
1161
+ }
1162
+
1163
+ // Implementation code not related to patch https://github.com/npm/cli/pull/7025
1164
+ // is based on https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/override-set.js:
1165
+ class SafeOverrideSet extends OverrideSet {
1166
+ // Patch adding childrenAreEqual is based on
1167
+ // https://github.com/npm/cli/pull/7025.
1168
+ childrenAreEqual(otherOverrideSet) {
1169
+ const queue = [[this, otherOverrideSet]];
1170
+ let pos = 0;
1171
+ let {
1172
+ length: queueLength
1173
+ } = queue;
1174
+ while (pos < queueLength) {
1175
+ if (pos === LOOP_SENTINEL) {
1176
+ throw new Error('Detected infinite loop while comparing override sets');
1177
+ }
1178
+ const {
1179
+ 0: currSet,
1180
+ 1: currOtherSet
1181
+ } = queue[pos++];
1182
+ const {
1183
+ children
1184
+ } = currSet;
1185
+ const {
1186
+ children: otherChildren
1187
+ } = currOtherSet;
1188
+ if (children.size !== otherChildren.size) {
1189
+ return false;
1190
+ }
1191
+ for (const key of children.keys()) {
1192
+ if (!otherChildren.has(key)) {
1193
+ return false;
1194
+ }
1195
+ const child = children.get(key);
1196
+ const otherChild = otherChildren.get(key);
1197
+ if (child.value !== otherChild.value) {
1198
+ return false;
1199
+ }
1200
+ queue[queueLength++] = [child, otherChild];
1201
+ }
1202
+ }
1203
+ return true;
1204
+ }
1205
+
1206
+ // Patch adding isEqual is based on
1207
+ // https://github.com/npm/cli/pull/7025.
1208
+ isEqual(otherOverrideSet) {
1209
+ if (this === otherOverrideSet) {
1210
+ return true;
1211
+ }
1212
+ if (!otherOverrideSet) {
1213
+ return false;
1214
+ }
1215
+ if (this.key !== otherOverrideSet.key || this.value !== otherOverrideSet.value) {
1216
+ return false;
1217
+ }
1218
+ if (!this.childrenAreEqual(otherOverrideSet)) {
1219
+ return false;
1220
+ }
1221
+ if (!this.parent) {
1222
+ return !otherOverrideSet.parent;
1223
+ }
1224
+ return this.parent.isEqual(otherOverrideSet.parent);
1225
+ }
1226
+ }
1227
+
1228
+ // Implementation code not related to our custom behavior is based on
1229
+ // https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/arborist/index.js:
1037
1230
  class SafeArborist extends Arborist {
1038
1231
  constructor(...ctorArgs) {
1039
1232
  const mutedArguments = [{
@@ -1135,8 +1328,10 @@ class SafeArborist extends Arborist {
1135
1328
  }
1136
1329
  arborist.SafeArborist = SafeArborist;
1137
1330
  function installSafeArborist() {
1138
- require.cache[arboristEdgeClassPath].exports = SafeEdge;
1139
1331
  require.cache[arboristClassPath].exports = SafeArborist;
1332
+ require.cache[arboristEdgeClassPath].exports = SafeEdge;
1333
+ require.cache[arboristNodeClassPath].exports = SafeNode;
1334
+ require.cache[arboristOverrideSetClassPatch].exports = SafeOverrideSet;
1140
1335
  }
1141
1336
  void (async () => {
1142
1337
  const remoteSettings = await (async () => {
@@ -1152,11 +1347,9 @@ void (async () => {
1152
1347
  orgs.push(org);
1153
1348
  }
1154
1349
  }
1155
- const result = await socketSdk.postSettings(orgs.map(org => {
1156
- return {
1157
- organization: org.id
1158
- };
1159
- }));
1350
+ const result = await socketSdk.postSettings(orgs.map(org => ({
1351
+ organization: org.id
1352
+ })));
1160
1353
  if (!result.success) {
1161
1354
  throw new Error('Failed to fetch API key settings: ' + result.error.message);
1162
1355
  }
@@ -1165,7 +1358,7 @@ void (async () => {
1165
1358
  settings: result.data
1166
1359
  };
1167
1360
  } catch (e) {
1168
- if (typeof e === 'object' && e !== null && 'cause' in e) {
1361
+ if ((0, _objects.isObject)(e) && 'cause' in e) {
1169
1362
  const {
1170
1363
  cause
1171
1364
  } = e;
@@ -1186,7 +1379,7 @@ void (async () => {
1186
1379
  } = remoteSettings;
1187
1380
  const enforcedOrgs = (0, _settings.getSetting)('enforcedOrgs') ?? [];
1188
1381
 
1189
- // remove any organizations not being enforced
1382
+ // Remove any organizations not being enforced.
1190
1383
  for (const {
1191
1384
  0: i,
1192
1385
  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.15",
4
4
  "description": "CLI tool for Socket.dev",
5
5
  "homepage": "http://github.com/SocketDev/socket-cli",
6
6
  "license": "MIT",