socket 0.0.1 → 0.14.12

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.
@@ -0,0 +1,1253 @@
1
+ 'use strict';
2
+
3
+ var vendor = require('./vendor.js');
4
+ var require$$0 = require('node:fs');
5
+ var require$$1 = require('node:path');
6
+ var link = require('./link.js');
7
+ var require$$0$1 = require('node:events');
8
+ var require$$4 = require('node:https');
9
+ var require$$3 = require('node:readline');
10
+ var require$$1$2 = require('node:stream');
11
+ var require$$8 = require('node:timers/promises');
12
+ var require$$3$1 = require('@socketsecurity/config');
13
+ var require$$1$1 = require('node:net');
14
+ var require$$2 = require('node:os');
15
+ var require$$6 = require('../package.json');
16
+ var sdk = require('./sdk.js');
17
+ var pathResolve = require('./path-resolve.js');
18
+ var require$$21 = require('pacote');
19
+
20
+ var npmInjection$1 = {};
21
+
22
+ var npmInjection = {};
23
+
24
+ var arborist = {};
25
+
26
+ var ttyServer$1 = {};
27
+
28
+ Object.defineProperty(ttyServer$1, "__esModule", {
29
+ value: true
30
+ });
31
+ ttyServer$1.createTTYServer = createTTYServer;
32
+ var _nodeFs$2 = require$$0;
33
+ var _nodeNet = require$$1$1;
34
+ var _nodeOs = require$$2;
35
+ var _nodePath$2 = require$$1;
36
+ var _nodeReadline$1 = require$$3;
37
+ var _nodeStream$1 = require$$1$2;
38
+ var _package = require$$6;
39
+ var _misc$1 = sdk.misc;
40
+ const NEWLINE_CHAR_CODE = 10; /*'\n'*/
41
+
42
+ const TTY_IPC = process.env['SOCKET_SECURITY_TTY_IPC'];
43
+ const sock = _nodePath$2.join(_nodeOs.tmpdir(), `socket-security-tty-${process.pid}.sock`);
44
+ process.env['SOCKET_SECURITY_TTY_IPC'] = sock;
45
+ function createNonStandardTTYServer() {
46
+ return {
47
+ async captureTTY(mutexFn) {
48
+ return await new Promise((resolve, reject) => {
49
+ const conn = _nodeNet.createConnection({
50
+ path: TTY_IPC
51
+ }).on('error', reject);
52
+ let captured = false;
53
+ const buffs = [];
54
+ conn.on('data', function awaitCapture(chunk) {
55
+ buffs.push(chunk);
56
+ let lineBuff = Buffer.concat(buffs);
57
+ if (captured) return;
58
+ try {
59
+ const eolIndex = lineBuff.indexOf(NEWLINE_CHAR_CODE);
60
+ if (eolIndex !== -1) {
61
+ conn.removeListener('data', awaitCapture);
62
+ conn.push(lineBuff.slice(eolIndex + 1));
63
+ const {
64
+ ipc_version: remote_ipc_version,
65
+ capabilities: {
66
+ input: hasInput,
67
+ output: hasOutput,
68
+ colorLevel: ipcColorLevel
69
+ }
70
+ } = JSON.parse(lineBuff.slice(0, eolIndex).toString('utf-8'));
71
+ lineBuff = null;
72
+ captured = true;
73
+ if (remote_ipc_version !== _package.version) {
74
+ throw new Error('Mismatched STDIO tunnel IPC version, ensure you only have 1 version of socket CLI being called.');
75
+ }
76
+ const input = hasInput ? new _nodeStream$1.PassThrough() : null;
77
+ input?.pause();
78
+ if (input) conn.pipe(input);
79
+ const output = hasOutput ? new _nodeStream$1.PassThrough() : null;
80
+ if (output) {
81
+ output.pipe(conn)
82
+ // Make ora happy
83
+ ;
84
+ output.isTTY = true;
85
+ output.cursorTo = function cursorTo(x, y, callback) {
86
+ _nodeReadline$1.cursorTo(this, x, y, callback);
87
+ };
88
+ output.clearLine = function clearLine(dir, callback) {
89
+ _nodeReadline$1.clearLine(this, dir, callback);
90
+ };
91
+ }
92
+ mutexFn(ipcColorLevel, hasInput ? input : undefined, hasOutput ? output : undefined).then(resolve, reject).finally(() => {
93
+ conn.unref();
94
+ conn.end();
95
+ input?.end();
96
+ output?.end();
97
+ // process.exit(13)
98
+ });
99
+ }
100
+ } catch (e) {
101
+ reject(e);
102
+ }
103
+ });
104
+ });
105
+ }
106
+ };
107
+ }
108
+ function createIPCServer(colorLevel, captureState, npmlog) {
109
+ const input = process.stdin;
110
+ const output = process.stderr;
111
+ return new Promise((resolve, reject) => {
112
+ const server = _nodeNet
113
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
114
+ .createServer(async conn => {
115
+ if (captureState.captured) {
116
+ await new Promise(resolve => {
117
+ captureState.pendingCaptures.push({
118
+ resolve() {
119
+ resolve();
120
+ }
121
+ });
122
+ });
123
+ } else {
124
+ captureState.captured = true;
125
+ }
126
+ const wasProgressEnabled = npmlog.progressEnabled;
127
+ npmlog.pause();
128
+ if (wasProgressEnabled) {
129
+ npmlog.disableProgress();
130
+ }
131
+ conn.write(`${JSON.stringify({
132
+ ipc_version: _package.version,
133
+ capabilities: {
134
+ input: Boolean(input),
135
+ output: true,
136
+ colorLevel
137
+ }
138
+ })}\n`);
139
+ conn.on('data', data => {
140
+ output.write(data);
141
+ }).on('error', e => {
142
+ output.write(`there was an error prompting from a sub shell (${e?.message}), socket npm closing`);
143
+ process.exit(1);
144
+ });
145
+ input.on('data', data => {
146
+ conn.write(data);
147
+ }).on('end', () => {
148
+ conn.unref();
149
+ conn.end();
150
+ if (wasProgressEnabled) {
151
+ npmlog.enableProgress();
152
+ }
153
+ npmlog.resume();
154
+ captureState.nextCapture();
155
+ });
156
+ }).listen(sock, () => resolve(server)).on('error', reject).unref();
157
+ process.on('exit', () => {
158
+ server.close();
159
+ tryUnlinkSync(sock);
160
+ });
161
+ resolve(server);
162
+ });
163
+ }
164
+ function createStandardTTYServer(colorLevel, isInteractive, npmlog) {
165
+ const captureState = {
166
+ captured: false,
167
+ nextCapture: () => {
168
+ if (captureState.pendingCaptures.length > 0) {
169
+ const pendingCapture = captureState.pendingCaptures.shift();
170
+ pendingCapture?.resolve();
171
+ } else {
172
+ captureState.captured = false;
173
+ }
174
+ },
175
+ pendingCaptures: []
176
+ };
177
+ tryUnlinkSync(sock);
178
+ const input = isInteractive ? process.stdin : undefined;
179
+ const output = process.stderr;
180
+ let ipcServerPromise;
181
+ if (input) {
182
+ ipcServerPromise = createIPCServer(colorLevel, captureState, npmlog);
183
+ }
184
+ return {
185
+ async captureTTY(mutexFn) {
186
+ await ipcServerPromise;
187
+ if (captureState.captured) {
188
+ const captured = new Promise(resolve => {
189
+ captureState.pendingCaptures.push({
190
+ resolve() {
191
+ resolve();
192
+ }
193
+ });
194
+ });
195
+ await captured;
196
+ } else {
197
+ captureState.captured = true;
198
+ }
199
+ const wasProgressEnabled = npmlog.progressEnabled;
200
+ try {
201
+ npmlog.pause();
202
+ if (wasProgressEnabled) {
203
+ npmlog.disableProgress();
204
+ }
205
+ return await mutexFn(colorLevel, input, output);
206
+ } finally {
207
+ if (wasProgressEnabled) {
208
+ npmlog.enableProgress();
209
+ }
210
+ npmlog.resume();
211
+ captureState.nextCapture();
212
+ }
213
+ }
214
+ };
215
+ }
216
+ function tryUnlinkSync(filepath) {
217
+ try {
218
+ (0, _nodeFs$2.unlinkSync)(filepath);
219
+ } catch (e) {
220
+ if ((0, _misc$1.isErrnoException)(e) && e.code !== 'ENOENT') {
221
+ throw e;
222
+ }
223
+ }
224
+ }
225
+ function createTTYServer(colorLevel, isInteractive, npmlog) {
226
+ return !isInteractive && TTY_IPC ? createNonStandardTTYServer() : createStandardTTYServer(colorLevel, isInteractive, npmlog);
227
+ }
228
+
229
+ var issueRules = {};
230
+
231
+ Object.defineProperty(issueRules, "__esModule", {
232
+ value: true
233
+ });
234
+ issueRules.createIssueUXLookup = createIssueUXLookup;
235
+ //#region UX Constants
236
+
237
+ const IGNORE_UX = {
238
+ block: false,
239
+ display: false
240
+ };
241
+ const WARN_UX = {
242
+ block: false,
243
+ display: true
244
+ };
245
+ const ERROR_UX = {
246
+ block: true,
247
+ display: true
248
+ };
249
+ //#endregion
250
+ //#region utils
251
+
252
+ /**
253
+ * Iterates over all entries with ordered issue rule for deferral. Iterates over
254
+ * all issue rules and finds the first defined value that does not defer otherwise
255
+ * uses the defaultValue. Takes the value and converts into a UX workflow
256
+ */
257
+ function resolveIssueRuleUX(entriesOrderedIssueRules, defaultValue) {
258
+ if (defaultValue === true || defaultValue == null) {
259
+ defaultValue = {
260
+ action: 'error'
261
+ };
262
+ } else if (defaultValue === false) {
263
+ defaultValue = {
264
+ action: 'ignore'
265
+ };
266
+ }
267
+ let block = false;
268
+ let display = false;
269
+ let needDefault = true;
270
+ iterate_entries: for (const issueRuleArr of entriesOrderedIssueRules) {
271
+ for (const rule of issueRuleArr) {
272
+ if (issueRuleValueDoesNotDefer(rule)) {
273
+ needDefault = false;
274
+ const narrowingFilter = uxForDefinedNonDeferValue(rule);
275
+ block = block || narrowingFilter.block;
276
+ display = display || narrowingFilter.display;
277
+ continue iterate_entries;
278
+ }
279
+ }
280
+ const narrowingFilter = uxForDefinedNonDeferValue(defaultValue);
281
+ block = block || narrowingFilter.block;
282
+ display = display || narrowingFilter.display;
283
+ }
284
+ if (needDefault) {
285
+ const narrowingFilter = uxForDefinedNonDeferValue(defaultValue);
286
+ block = block || narrowingFilter.block;
287
+ display = display || narrowingFilter.display;
288
+ }
289
+ return {
290
+ block,
291
+ display
292
+ };
293
+ }
294
+
295
+ /**
296
+ * Negative form because it is narrowing the type
297
+ */
298
+ function issueRuleValueDoesNotDefer(issueRule) {
299
+ if (issueRule === undefined) {
300
+ return false;
301
+ } else if (typeof issueRule === 'object' && issueRule) {
302
+ const {
303
+ action
304
+ } = issueRule;
305
+ if (action === undefined || action === 'defer') {
306
+ return false;
307
+ }
308
+ }
309
+ return true;
310
+ }
311
+
312
+ /**
313
+ * Handles booleans for backwards compatibility
314
+
315
+ */
316
+ function uxForDefinedNonDeferValue(issueRuleValue) {
317
+ if (typeof issueRuleValue === 'boolean') {
318
+ return issueRuleValue ? ERROR_UX : IGNORE_UX;
319
+ }
320
+ const {
321
+ action
322
+ } = issueRuleValue;
323
+ if (action === 'warn') {
324
+ return WARN_UX;
325
+ } else if (action === 'ignore') {
326
+ return IGNORE_UX;
327
+ }
328
+ return ERROR_UX;
329
+ }
330
+ //#endregion
331
+
332
+ //#region exports
333
+
334
+ function createIssueUXLookup(settings) {
335
+ const cachedUX = new Map();
336
+ return context => {
337
+ const key = context.issue.type;
338
+ let ux = cachedUX.get(key);
339
+ if (ux) {
340
+ return ux;
341
+ }
342
+ const entriesOrderedIssueRules = [];
343
+ for (const settingsEntry of settings.entries) {
344
+ const orderedIssueRules = [];
345
+ let target = settingsEntry.start;
346
+ while (target !== null) {
347
+ const resolvedTarget = settingsEntry.settings[target];
348
+ if (!resolvedTarget) {
349
+ break;
350
+ }
351
+ const issueRuleValue = resolvedTarget.issueRules?.[key];
352
+ if (typeof issueRuleValue !== 'undefined') {
353
+ orderedIssueRules.push(issueRuleValue);
354
+ }
355
+ target = resolvedTarget.deferTo ?? null;
356
+ }
357
+ entriesOrderedIssueRules.push(orderedIssueRules);
358
+ }
359
+ const defaultValue = settings.defaults.issueRules[key];
360
+ let resolvedDefaultValue = {
361
+ action: 'error'
362
+ };
363
+ if (defaultValue === false) {
364
+ resolvedDefaultValue = {
365
+ action: 'ignore'
366
+ };
367
+ } else if (defaultValue && defaultValue !== true) {
368
+ resolvedDefaultValue = {
369
+ action: defaultValue.action ?? 'error'
370
+ };
371
+ }
372
+ ux = resolveIssueRuleUX(entriesOrderedIssueRules, resolvedDefaultValue);
373
+ cachedUX.set(key, ux);
374
+ return ux;
375
+ };
376
+ }
377
+
378
+ var _interopRequireWildcard = vendor.interopRequireWildcard.default;
379
+ var _interopRequireDefault = vendor.interopRequireDefault.default;
380
+ Object.defineProperty(arborist, "__esModule", {
381
+ value: true
382
+ });
383
+ arborist.SafeArborist = void 0;
384
+ arborist.installSafeArborist = installSafeArborist;
385
+ var _nodeEvents = require$$0$1;
386
+ var _nodeFs$1 = require$$0;
387
+ var _nodeHttps = require$$4;
388
+ var _nodePath$1 = require$$1;
389
+ var _nodeReadline = require$$3;
390
+ var _nodeStream = require$$1$2;
391
+ var _promises = require$$8;
392
+ var _config = require$$3$1;
393
+ var _chalk = _interopRequireDefault(vendor.source);
394
+ var _isInteractive = _interopRequireDefault(vendor.isInteractive);
395
+ var _ora = _interopRequireWildcard(vendor.ora);
396
+ var _ttyServer = ttyServer$1;
397
+ var _chalkMarkdown = sdk.chalkMarkdown;
398
+ var _issueRules = issueRules;
399
+ var _misc = sdk.misc;
400
+ var _pathResolve = pathResolve.pathResolve;
401
+ var _sdk = sdk.sdk;
402
+ var _settings = sdk.settings;
403
+ var _constants = sdk.constants;
404
+ const LOOP_SENTINEL = 1_000_000;
405
+ const POTENTIALLY_BUG_ERROR_SNIPPET = 'this is potentially a bug with socket-npm caused by changes to the npm cli';
406
+ const distPath$1 = __dirname;
407
+ const rootPath$1 = _nodePath$1.resolve(distPath$1, '..');
408
+ const translations = require(_nodePath$1.join(rootPath$1, 'translations.json'));
409
+ const npmEntrypoint = (0, _nodeFs$1.realpathSync)(`${process.argv[1]}`);
410
+ const npmRootPath = (0, _pathResolve.findRoot)(_nodePath$1.dirname(npmEntrypoint));
411
+ const abortController = new AbortController();
412
+ const {
413
+ signal: abortSignal
414
+ } = abortController;
415
+ if (npmRootPath === undefined) {
416
+ console.error(`Unable to find npm cli install directory, ${POTENTIALLY_BUG_ERROR_SNIPPET}.`);
417
+ console.error(`Searched parent directories of ${npmEntrypoint}`);
418
+ process.exit(127);
419
+ }
420
+ const npmNmPath = _nodePath$1.join(npmRootPath, 'node_modules');
421
+ const arboristClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/arborist/index.js');
422
+ const arboristEdgeClassPath = _nodePath$1.join(npmNmPath, '@npmcli/arborist/lib/edge.js');
423
+ let npmlog;
424
+ try {
425
+ npmlog = require(_nodePath$1.join(npmNmPath, 'proc-log/lib/index.js')).log;
426
+ } catch {}
427
+ if (npmlog === undefined) {
428
+ try {
429
+ npmlog = require(_nodePath$1.join(npmNmPath, 'npmlog/lib/log.js'));
430
+ } catch {}
431
+ }
432
+ if (npmlog === undefined) {
433
+ console.error(`Unable to integrate with npm cli logging infrastructure, ${POTENTIALLY_BUG_ERROR_SNIPPET}.`);
434
+ process.exit(127);
435
+ }
436
+ let tarball;
437
+ try {
438
+ tarball = require(_nodePath$1.join(npmNmPath, 'pacote')).tarball;
439
+ } catch {
440
+ tarball = require$$21.tarball;
441
+ }
442
+ const Arborist = require(arboristClassPath);
443
+ const Edge = require(arboristEdgeClassPath);
444
+ const kCtorArgs = Symbol('ctorArgs');
445
+ const kRiskyReify = Symbol('riskyReify');
446
+ const formatter = new _chalkMarkdown.ChalkOrMarkdown(false);
447
+ const pubToken = (0, _sdk.getDefaultKey)() ?? _sdk.FREE_API_KEY;
448
+ const ttyServer = (0, _ttyServer.createTTYServer)(_chalk.default.level, (0, _isInteractive.default)({
449
+ stream: process.stdin
450
+ }), npmlog);
451
+ let _uxLookup;
452
+ async function uxLookup(settings) {
453
+ while (_uxLookup === undefined) {
454
+ // eslint-disable-next-line no-await-in-loop
455
+ await (0, _promises.setTimeout)(1, {
456
+ signal: abortSignal
457
+ });
458
+ }
459
+ return _uxLookup(settings);
460
+ }
461
+ async function* batchScan(pkgIds) {
462
+ const query = {
463
+ packages: pkgIds.map(pkgid => {
464
+ const {
465
+ name,
466
+ version
467
+ } = pkgidParts(pkgid);
468
+ return {
469
+ eco: 'npm',
470
+ pkg: name,
471
+ ver: version,
472
+ top: true
473
+ };
474
+ })
475
+ };
476
+ // TODO: Migrate to SDK.
477
+ const pkgDataReq = _nodeHttps.request(`${_constants.API_V0_URL}/scan/batch`, {
478
+ method: 'POST',
479
+ headers: {
480
+ Authorization: `Basic ${Buffer.from(`${pubToken}:`).toString('base64url')}`
481
+ },
482
+ signal: abortSignal
483
+ }).end(JSON.stringify(query));
484
+ const {
485
+ 0: res
486
+ } = await _nodeEvents.once(pkgDataReq, 'response');
487
+ const ok = res.statusCode >= 200 && res.statusCode <= 299;
488
+ if (!ok) {
489
+ throw new Error(`Socket API Error: ${res.statusCode}`);
490
+ }
491
+ const rli = _nodeReadline.createInterface(res);
492
+ for await (const line of rli) {
493
+ yield JSON.parse(line);
494
+ }
495
+ }
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
+ function findSocketYmlSync() {
506
+ let prevDir = null;
507
+ let dir = process.cwd();
508
+ while (dir !== prevDir) {
509
+ let ymlPath = _nodePath$1.join(dir, 'socket.yml');
510
+ let yml = maybeReadfileSync(ymlPath);
511
+ if (yml === undefined) {
512
+ ymlPath = _nodePath$1.join(dir, 'socket.yaml');
513
+ yml = maybeReadfileSync(ymlPath);
514
+ }
515
+ if (typeof yml === 'string') {
516
+ try {
517
+ return {
518
+ path: ymlPath,
519
+ parsed: _config.parseSocketConfig(yml)
520
+ };
521
+ } catch {
522
+ throw new Error(`Found file but was unable to parse ${ymlPath}`);
523
+ }
524
+ }
525
+ prevDir = dir;
526
+ dir = _nodePath$1.join(dir, '..');
527
+ }
528
+ return null;
529
+ }
530
+ function findSpecificOverrideSet(first, second) {
531
+ let overrideSet = second;
532
+ while (overrideSet) {
533
+ if (overrideSetsEqual(overrideSet, first)) {
534
+ return second;
535
+ }
536
+ overrideSet = overrideSet.parent;
537
+ }
538
+ overrideSet = first;
539
+ while (overrideSet) {
540
+ if (overrideSetsEqual(overrideSet, second)) {
541
+ return first;
542
+ }
543
+ overrideSet = overrideSet.parent;
544
+ }
545
+ console.error('Conflicting override sets');
546
+ return undefined;
547
+ }
548
+ function maybeReadfileSync(filepath) {
549
+ try {
550
+ return (0, _nodeFs$1.readFileSync)(filepath, 'utf8');
551
+ } catch {}
552
+ return undefined;
553
+ }
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
+ async function packagesHaveRiskyIssues(safeArb, _registry, pkgs, output) {
610
+ let result = false;
611
+ let remaining = pkgs.length;
612
+ if (!remaining) {
613
+ (0, _ora.default)('').succeed('No changes detected');
614
+ return result;
615
+ }
616
+ const getText = () => `Looking up data for ${remaining} packages`;
617
+ const spinner = (0, _ora.default)({
618
+ color: 'cyan',
619
+ stream: output,
620
+ isEnabled: true,
621
+ isSilent: false,
622
+ hideCursor: true,
623
+ discardStdin: true,
624
+ spinner: _ora.spinners.dots
625
+ }).start(getText());
626
+ try {
627
+ for await (const pkgData of batchScan(pkgs.map(pkg => pkg.pkgid))) {
628
+ let failures = [];
629
+ let displayWarning = false;
630
+ const name = pkgData.pkg;
631
+ const version = pkgData.ver;
632
+ const id = `${name}@${version}`;
633
+ if (pkgData.type === 'missing') {
634
+ result = true;
635
+ failures.push({
636
+ type: 'missingDependency'
637
+ });
638
+ } else {
639
+ let blocked = false;
640
+ for (const failure of pkgData.value.issues) {
641
+ // eslint-disable-next-line no-await-in-loop
642
+ const ux = await uxLookup({
643
+ package: {
644
+ name,
645
+ version
646
+ },
647
+ issue: {
648
+ type: failure.type
649
+ }
650
+ });
651
+ if (ux.display || ux.block) {
652
+ failures.push({
653
+ raw: failure,
654
+ block: ux.block
655
+ });
656
+ // Before we ask about problematic issues, check to see if they
657
+ // already existed in the old version if they did, be quiet.
658
+ const pkg = pkgs.find(pkg => pkg.pkgid === id && pkg.existing?.startsWith(`${name}@`));
659
+ if (pkg?.existing) {
660
+ // eslint-disable-next-line no-await-in-loop
661
+ for await (const oldPkgData of batchScan([pkg.existing])) {
662
+ if (oldPkgData.type === 'success') {
663
+ failures = failures.filter(issue => oldPkgData.value.issues.find(oldIssue => oldIssue.type === issue.raw.type) == null);
664
+ }
665
+ }
666
+ }
667
+ }
668
+ if (ux.block) {
669
+ result = true;
670
+ blocked = true;
671
+ }
672
+ if (ux.display) {
673
+ displayWarning = true;
674
+ }
675
+ }
676
+ if (!blocked) {
677
+ const pkg = pkgs.find(pkg => pkg.pkgid === id);
678
+ if (pkg) {
679
+ await tarball.stream(id, stream => {
680
+ stream.resume();
681
+ return stream.promise();
682
+ }, {
683
+ ...safeArb[kCtorArgs][0]
684
+ });
685
+ }
686
+ }
687
+ }
688
+ if (displayWarning) {
689
+ spinner.stop();
690
+ output?.write(`(socket) ${formatter.hyperlink(id, `https://socket.dev/npm/package/${name}/overview/${version}`)} contains risks:\n`);
691
+ failures.sort((a, b) => a.raw.type < b.raw.type ? -1 : 1);
692
+ const lines = new Set();
693
+ for (const failure of failures) {
694
+ const type = failure.raw.type;
695
+ if (type) {
696
+ const issueTypeTranslation = translations.issues[type];
697
+ // TODO: emoji seems to mis-align terminals sometimes
698
+ lines.add(` ${issueTypeTranslation?.title ?? type}${failure.block ? '' : ' (non-blocking)'} - ${issueTypeTranslation?.description ?? ''}\n`);
699
+ }
700
+ }
701
+ for (const line of lines) {
702
+ output?.write(line);
703
+ }
704
+ spinner.start();
705
+ }
706
+ remaining -= 1;
707
+ spinner.text = remaining > 0 ? getText() : '';
708
+ }
709
+ return result;
710
+ } finally {
711
+ if (spinner.isSpinning) {
712
+ spinner.stop();
713
+ }
714
+ }
715
+ }
716
+ function pkgidParts(pkgid) {
717
+ const delimiter = pkgid.lastIndexOf('@');
718
+ const name = pkgid.slice(0, delimiter);
719
+ const version = pkgid.slice(delimiter + 1);
720
+ return {
721
+ name,
722
+ version
723
+ };
724
+ }
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
+ function toPURL(pkgid, resolved) {
735
+ const repo = resolved.replace(/#[\s\S]*$/u, '').replace(/\?[\s\S]*$/u, '').replace(/\/[^/]*\/-\/[\s\S]*$/u, '');
736
+ const {
737
+ name,
738
+ version
739
+ } = pkgidParts(pkgid);
740
+ return {
741
+ type: 'npm',
742
+ namespace_and_name: name,
743
+ version,
744
+ repository_url: repo
745
+ };
746
+ }
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
+ function walk(diff_, needInfoOn = []) {
826
+ const queue = [diff_];
827
+ let pos = 0;
828
+ let {
829
+ length: queueLength
830
+ } = queue;
831
+ while (pos < queueLength) {
832
+ if (pos === LOOP_SENTINEL) {
833
+ throw new Error('Detected infinite loop while walking Arborist diff');
834
+ }
835
+ const diff = queue[pos++];
836
+ if (!diff) {
837
+ continue;
838
+ }
839
+ if (diff.action) {
840
+ const sameVersion = diff.actual?.package.version === diff.ideal?.package.version;
841
+ let keep = false;
842
+ let existing = null;
843
+ if (diff.action === 'CHANGE') {
844
+ if (!sameVersion) {
845
+ existing = diff.actual.pkgid;
846
+ keep = true;
847
+ }
848
+ } else {
849
+ keep = diff.action !== 'REMOVE';
850
+ }
851
+ if (keep && diff.ideal?.pkgid && diff.ideal.resolved && (!diff.actual || diff.actual.resolved)) {
852
+ needInfoOn.push({
853
+ existing,
854
+ action: diff.action,
855
+ location: diff.ideal.location,
856
+ pkgid: diff.ideal.pkgid,
857
+ newPackage: toPURL(diff.ideal.pkgid, diff.ideal.resolved),
858
+ oldPackage: diff.actual && diff.actual.resolved ? toPURL(diff.actual.pkgid, diff.actual.resolved) : null,
859
+ resolved: diff.ideal.resolved
860
+ });
861
+ }
862
+ }
863
+ if (diff.children) {
864
+ for (const child of diff.children) {
865
+ queue[queueLength++] = child;
866
+ }
867
+ }
868
+ }
869
+ return needInfoOn;
870
+ }
871
+
872
+ // Copied from
873
+ // https://github.com/npm/cli/blob/v10.9.0/workspaces/arborist/lib/edge.js:
874
+ // The npm application
875
+ // Copyright (c) npm, Inc. and Contributors
876
+ // Licensed on the terms of The Artistic License 2.0
877
+ //
878
+ // An edge in the dependency graph.
879
+ // Represents a dependency relationship of some kind.
880
+
881
+ class SafeEdge extends Edge {
882
+ #safeAccept;
883
+ #safeError;
884
+ #safeExplanation;
885
+ #safeFrom;
886
+ #safeTo;
887
+ constructor(options) {
888
+ const {
889
+ accept,
890
+ from
891
+ } = options;
892
+ // Defer to supper to validate options and assign non-private values.
893
+ super(options);
894
+ if (accept !== undefined) {
895
+ this.#safeAccept = accept || '*';
896
+ }
897
+ this.#safeError = null;
898
+ this.#safeExplanation = null;
899
+ this.#safeFrom = from;
900
+ this.#safeTo = null;
901
+ this.reload(true);
902
+ }
903
+
904
+ // Return the edge data, and an explanation of how that edge came to be here.
905
+ // @ts-ignore: Edge#explain is defined with an unused `seen = []` param.
906
+ explain() {
907
+ if (!this.#safeExplanation) {
908
+ const explanation = {
909
+ type: this.type,
910
+ name: this.name,
911
+ spec: this.spec,
912
+ bundled: false,
913
+ overridden: false,
914
+ error: undefined,
915
+ from: undefined,
916
+ rawSpec: undefined
917
+ };
918
+ if (this.rawSpec !== this.spec) {
919
+ explanation.rawSpec = this.rawSpec;
920
+ explanation.overridden = true;
921
+ }
922
+ if (this.bundled) {
923
+ explanation.bundled = this.bundled;
924
+ }
925
+ if (this.error) {
926
+ explanation.error = this.error;
927
+ }
928
+ if (this.#safeFrom) {
929
+ explanation.from = this.#safeFrom.explain();
930
+ }
931
+ this.#safeExplanation = explanation;
932
+ }
933
+ return this.#safeExplanation;
934
+ }
935
+ get bundled() {
936
+ return !!this.#safeFrom?.package?.bundleDependencies?.includes(this.name);
937
+ }
938
+
939
+ // @ts-ignore: Incorrectly typed as a property instead of an accessor.
940
+ get spec() {
941
+ if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this.name) {
942
+ if (this.overrides.value.startsWith('$')) {
943
+ const ref = this.overrides.value.slice(1);
944
+ // We may be a virtual root, if we are we want to resolve reference
945
+ // overrides from the real root, not the virtual one.
946
+ const pkg = this.#safeFrom?.sourceReference ? this.#safeFrom.sourceReference.root.package : this.#safeFrom?.root.package;
947
+ if (pkg?.devDependencies?.[ref]) {
948
+ return pkg.devDependencies[ref];
949
+ }
950
+ if (pkg?.optionalDependencies?.[ref]) {
951
+ return pkg.optionalDependencies[ref];
952
+ }
953
+ if (pkg?.dependencies?.[ref]) {
954
+ return pkg.dependencies[ref];
955
+ }
956
+ if (pkg?.peerDependencies?.[ref]) {
957
+ return pkg.peerDependencies[ref];
958
+ }
959
+ throw new Error(`Unable to resolve reference ${this.overrides.value}`);
960
+ }
961
+ return this.overrides.value;
962
+ }
963
+ return this.rawSpec;
964
+ }
965
+ get accept() {
966
+ return this.#safeAccept;
967
+ }
968
+ get error() {
969
+ if (!this.#safeError) {
970
+ if (!this.#safeTo) {
971
+ if (this.optional) {
972
+ this.#safeError = null;
973
+ } else {
974
+ this.#safeError = 'MISSING';
975
+ }
976
+ } else if (this.peer && this.#safeFrom === this.#safeTo.parent && !this.#safeFrom?.isTop) {
977
+ this.#safeError = 'PEER LOCAL';
978
+ } else if (!this.satisfiedBy(this.#safeTo)) {
979
+ this.#safeError = 'INVALID';
980
+ } else {
981
+ this.#safeError = 'OK';
982
+ }
983
+ }
984
+ if (this.#safeError === 'OK') {
985
+ return null;
986
+ }
987
+ return this.#safeError;
988
+ }
989
+ reload(hard = false) {
990
+ this.#safeExplanation = null;
991
+ if (this.#safeFrom?.overrides) {
992
+ this.overrides = this.#safeFrom.overrides.getEdgeRule(this);
993
+ } else {
994
+ this.overrides = undefined;
995
+ }
996
+ const newTo = this.#safeFrom?.resolve(this.name);
997
+ if (newTo !== this.#safeTo) {
998
+ 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);
1002
+ }
1003
+ this.#safeTo = newTo ?? null;
1004
+ this.#safeError = null;
1005
+ if (this.#safeTo) {
1006
+ this.#safeTo.addEdgeIn(this);
1007
+ }
1008
+ } else if (hard) {
1009
+ this.#safeError = null;
1010
+ }
1011
+ }
1012
+ detach() {
1013
+ this.#safeExplanation = null;
1014
+ 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);
1018
+ }
1019
+ if (this.#safeFrom) {
1020
+ this.#safeFrom.edgesOut.delete(this.name);
1021
+ }
1022
+ this.#safeTo = null;
1023
+ this.#safeError = 'DETACHED';
1024
+ this.#safeFrom = null;
1025
+ }
1026
+
1027
+ // @ts-ignore: Incorrectly typed as a property instead of an accessor.
1028
+ get from() {
1029
+ return this.#safeFrom;
1030
+ }
1031
+
1032
+ // @ts-ignore: Incorrectly typed as a property instead of an accessor.
1033
+ get to() {
1034
+ return this.#safeTo;
1035
+ }
1036
+ }
1037
+ class SafeArborist extends Arborist {
1038
+ constructor(...ctorArgs) {
1039
+ const mutedArguments = [{
1040
+ ...ctorArgs[0],
1041
+ audit: true,
1042
+ dryRun: true,
1043
+ ignoreScripts: true,
1044
+ save: false,
1045
+ saveBundle: false,
1046
+ // progress: false,
1047
+ fund: false
1048
+ }, ctorArgs.slice(1)];
1049
+ super(...mutedArguments);
1050
+ this[kCtorArgs] = ctorArgs;
1051
+ }
1052
+ async [kRiskyReify](...args) {
1053
+ // SafeArborist has suffered side effects and must be rebuilt from scratch.
1054
+ const arb = new Arborist(...this[kCtorArgs]);
1055
+ const ret = await arb.reify(...args);
1056
+ Object.assign(this, arb);
1057
+ return ret;
1058
+ }
1059
+
1060
+ // @ts-ignore Incorrectly typed.
1061
+ async reify(...args) {
1062
+ const options = args[0] ? {
1063
+ ...args[0]
1064
+ } : {};
1065
+ if (options.dryRun) {
1066
+ return await this[kRiskyReify](...args);
1067
+ }
1068
+ const old = {
1069
+ ...options,
1070
+ dryRun: false,
1071
+ save: Boolean(options['save'] ?? true),
1072
+ saveBundle: Boolean(options['saveBundle'] ?? false)
1073
+ };
1074
+ args[0] = options;
1075
+ options.dryRun = true;
1076
+ options['save'] = false;
1077
+ options['saveBundle'] = false;
1078
+ // TODO: Make this deal w/ any refactor to private fields by punching the
1079
+ // class itself.
1080
+ await super.reify(...args);
1081
+ const diff = walk(this['diff']);
1082
+ options.dryRun = old.dryRun;
1083
+ options['save'] = old.save;
1084
+ options['saveBundle'] = old.saveBundle;
1085
+ // Nothing to check, mmm already installed or all private?
1086
+ if (diff.findIndex(c => c.newPackage.repository_url === 'https://registry.npmjs.org') === -1) {
1087
+ return await this[kRiskyReify](...args);
1088
+ }
1089
+ let proceed = _constants.ENV.UPDATE_SOCKET_OVERRIDES_IN_PACKAGE_LOCK_FILE;
1090
+ if (!proceed) {
1091
+ proceed = await ttyServer.captureTTY(async (colorLevel, input, output) => {
1092
+ _chalk.default.level = colorLevel;
1093
+ if (input && output) {
1094
+ const risky = await packagesHaveRiskyIssues(this, this['registry'], diff, output);
1095
+ if (!risky) {
1096
+ return true;
1097
+ }
1098
+ const rlin = new _nodeStream.PassThrough();
1099
+ input.pipe(rlin);
1100
+ const rlout = new _nodeStream.PassThrough();
1101
+ rlout.pipe(output, {
1102
+ end: false
1103
+ });
1104
+ const rli = _nodeReadline.createInterface(rlin, rlout);
1105
+ try {
1106
+ while (true) {
1107
+ // eslint-disable-next-line no-await-in-loop
1108
+ const answer = await new Promise(resolve => {
1109
+ rli.question('Accept risks of installing these packages (y/N)?\n', {
1110
+ signal: abortSignal
1111
+ }, resolve);
1112
+ });
1113
+ if (/^\s*y(?:es)?\s*$/i.test(answer)) {
1114
+ return true;
1115
+ }
1116
+ if (/^(?:\s*no?\s*|)$/i.test(answer)) {
1117
+ return false;
1118
+ }
1119
+ }
1120
+ } finally {
1121
+ rli.close();
1122
+ }
1123
+ } else if (await packagesHaveRiskyIssues(this, this['registry'], diff, output)) {
1124
+ throw new Error('Socket npm Unable to prompt to accept risk, need TTY to do so');
1125
+ }
1126
+ return true;
1127
+ });
1128
+ }
1129
+ if (proceed) {
1130
+ return await this[kRiskyReify](...args);
1131
+ } else {
1132
+ throw new Error('Socket npm exiting due to risks');
1133
+ }
1134
+ }
1135
+ }
1136
+ arborist.SafeArborist = SafeArborist;
1137
+ function installSafeArborist() {
1138
+ require.cache[arboristEdgeClassPath].exports = SafeEdge;
1139
+ require.cache[arboristClassPath].exports = SafeArborist;
1140
+ }
1141
+ void (async () => {
1142
+ const remoteSettings = await (async () => {
1143
+ try {
1144
+ const socketSdk = await (0, _sdk.setupSdk)(pubToken);
1145
+ const orgResult = await socketSdk.getOrganizations();
1146
+ if (!orgResult.success) {
1147
+ throw new Error('Failed to fetch Socket organization info: ' + orgResult.error.message);
1148
+ }
1149
+ const orgs = [];
1150
+ for (const org of Object.values(orgResult.data.organizations)) {
1151
+ if (org) {
1152
+ orgs.push(org);
1153
+ }
1154
+ }
1155
+ const result = await socketSdk.postSettings(orgs.map(org => {
1156
+ return {
1157
+ organization: org.id
1158
+ };
1159
+ }));
1160
+ if (!result.success) {
1161
+ throw new Error('Failed to fetch API key settings: ' + result.error.message);
1162
+ }
1163
+ return {
1164
+ orgs,
1165
+ settings: result.data
1166
+ };
1167
+ } catch (e) {
1168
+ if (typeof e === 'object' && e !== null && 'cause' in e) {
1169
+ const {
1170
+ cause
1171
+ } = e;
1172
+ if ((0, _misc.isErrnoException)(cause)) {
1173
+ if (cause.code === 'ENOTFOUND' || cause.code === 'ECONNREFUSED') {
1174
+ throw new Error('Unable to connect to socket.dev, ensure internet connectivity before retrying', {
1175
+ cause: e
1176
+ });
1177
+ }
1178
+ }
1179
+ }
1180
+ throw e;
1181
+ }
1182
+ })();
1183
+ const {
1184
+ orgs,
1185
+ settings
1186
+ } = remoteSettings;
1187
+ const enforcedOrgs = (0, _settings.getSetting)('enforcedOrgs') ?? [];
1188
+
1189
+ // remove any organizations not being enforced
1190
+ for (const {
1191
+ 0: i,
1192
+ 1: org
1193
+ } of orgs.entries()) {
1194
+ if (!enforcedOrgs.includes(org.id)) {
1195
+ settings.entries.splice(i, 1);
1196
+ }
1197
+ }
1198
+ const socketYml = findSocketYmlSync();
1199
+ if (socketYml) {
1200
+ settings.entries.push({
1201
+ start: socketYml.path,
1202
+ // @ts-ignore
1203
+ settings: {
1204
+ [socketYml.path]: {
1205
+ deferTo: null,
1206
+ issueRules: socketYml.parsed.issueRules
1207
+ }
1208
+ }
1209
+ });
1210
+ }
1211
+ _uxLookup = (0, _issueRules.createIssueUXLookup)(settings);
1212
+ })();
1213
+
1214
+ var _nodeFs = require$$0;
1215
+ var _nodePath = require$$1;
1216
+ var _link = link.link;
1217
+ var _arborist = arborist;
1218
+ const distPath = __dirname;
1219
+ const rootPath = _nodePath.resolve(distPath, '..');
1220
+ const binPath = _nodePath.join(rootPath, 'bin');
1221
+
1222
+ // shadow `npm` and `npx` to mitigate subshells
1223
+ (0, _link.installLinks)((0, _nodeFs.realpathSync)(binPath), 'npm');
1224
+ (0, _arborist.installSafeArborist)();
1225
+
1226
+ (function (exports) {
1227
+
1228
+ var _interopRequireWildcard = vendor.interopRequireWildcard.default;
1229
+ Object.defineProperty(exports, "__esModule", {
1230
+ value: true
1231
+ });
1232
+ var _exportNames = {};
1233
+ Object.defineProperty(exports, "default", {
1234
+ enumerable: true,
1235
+ get: function () {
1236
+ return _npmInjection.default;
1237
+ }
1238
+ });
1239
+ var _npmInjection = _interopRequireWildcard(npmInjection, true);
1240
+ Object.keys(_npmInjection).forEach(function (key) {
1241
+ if (key === "default" || key === "__esModule") return;
1242
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
1243
+ if (key in exports && exports[key] === _npmInjection[key]) return;
1244
+ Object.defineProperty(exports, key, {
1245
+ enumerable: true,
1246
+ get: function () {
1247
+ return _npmInjection[key];
1248
+ }
1249
+ });
1250
+ });
1251
+ } (npmInjection$1));
1252
+
1253
+ module.exports = npmInjection$1;