socket 0.14.40-alpha.9 → 0.14.41

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.
@@ -8,6 +8,6 @@ declare function findBinPathDetails(binName: string): Promise<{
8
8
  path: string | undefined;
9
9
  shadowed: boolean;
10
10
  }>;
11
- declare function getPackageFiles(cwd: string, inputPaths: string[], config: SocketYml | undefined, supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data'], debugLog?: typeof console.error): Promise<string[]>;
11
+ declare function getPackageFiles(cwd: string, inputPaths: string[], config: SocketYml | undefined, supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data']): Promise<string[]>;
12
12
  declare function getPackageFilesFullScans(cwd: string, inputPaths: string[], supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data'], debugLog?: typeof console.error): Promise<string[]>;
13
13
  export { directoryPatterns, findRoot, findBinPathDetails, getPackageFiles, getPackageFilesFullScans };
@@ -11,12 +11,56 @@ function _socketInterop(e) {
11
11
 
12
12
  var fs = require('node:fs');
13
13
  var path = require('node:path');
14
+ var process = require('node:process');
14
15
  var ignore = _socketInterop(require('ignore'));
15
16
  var micromatch = _socketInterop(require('micromatch'));
16
17
  var tinyglobby = _socketInterop(require('tinyglobby'));
17
18
  var which = _socketInterop(require('which'));
19
+ var colors = _socketInterop(require('yoctocolors-cjs'));
20
+ var isUnicodeSupported = require('@socketregistry/is-unicode-supported/index.cjs');
21
+ var spinner = require('@socketsecurity/registry/lib/spinner');
18
22
  var constants = require('./constants.js');
19
23
 
24
+ const logSymbols = isUnicodeSupported() ? {
25
+ __proto__: null,
26
+ info: colors.blue('ℹ'),
27
+ success: colors.green('✔'),
28
+ warning: colors.yellow('⚠'),
29
+ error: colors.red('✖️')
30
+ } : {
31
+ __proto__: null,
32
+ info: colors.blue('i'),
33
+ success: colors.green('√'),
34
+ warning: colors.yellow('‼'),
35
+ error: colors.red('×')
36
+ };
37
+ class Logger {
38
+ #spinnerLogger;
39
+ constructor() {
40
+ this.#spinnerLogger = new spinner.Spinner();
41
+ }
42
+ error(text) {
43
+ this.#spinnerLogger.error(text);
44
+ }
45
+ info(text) {
46
+ this.#spinnerLogger.info(text);
47
+ }
48
+ warn(text) {
49
+ this.#spinnerLogger.warning(text);
50
+ }
51
+ }
52
+ const logger = new Logger();
53
+
54
+ function isDebug() {
55
+ // Lazily access constants.ENV.
56
+ return constants.ENV.SOCKET_CLI_DEBUG;
57
+ }
58
+ function debugLog(...args) {
59
+ if (isDebug()) {
60
+ console.error(logSymbols.info, ...args);
61
+ }
62
+ }
63
+
20
64
  const ignoredDirs = [
21
65
  // Taken from ignore-by-default:
22
66
  // https://github.com/novemberborn/ignore-by-default/blob/v2.1.0/index.js
@@ -170,7 +214,7 @@ async function findBinPathDetails(binName) {
170
214
  shadowed: shadowIndex !== -1
171
215
  };
172
216
  }
173
- async function getPackageFiles(cwd, inputPaths, config, supportedFiles, debugLog = () => {}) {
217
+ async function getPackageFiles(cwd, inputPaths, config, supportedFiles) {
174
218
  debugLog(`Globbed resolving ${inputPaths.length} paths:`, inputPaths);
175
219
  const entries = await globWithGitIgnore(pathsToPatterns(inputPaths), {
176
220
  cwd,
@@ -192,7 +236,11 @@ async function getPackageFilesFullScans(cwd, inputPaths, supportedFiles, debugLo
192
236
  return packageFiles;
193
237
  }
194
238
 
239
+ exports.debugLog = debugLog;
195
240
  exports.findBinPathDetails = findBinPathDetails;
196
241
  exports.findRoot = findRoot;
197
242
  exports.getPackageFiles = getPackageFiles;
198
243
  exports.getPackageFilesFullScans = getPackageFilesFullScans;
244
+ exports.isDebug = isDebug;
245
+ exports.logSymbols = logSymbols;
246
+ exports.logger = logger;
@@ -1,9 +1,14 @@
1
+ import config from '@socketsecurity/config';
1
2
  interface Settings {
2
3
  apiKey?: string | null;
3
4
  enforcedOrgs?: string[] | null;
4
5
  apiBaseUrl?: string | null;
5
6
  apiProxy?: string | null;
6
7
  }
8
+ declare function findSocketYmlSync(): {
9
+ path: string;
10
+ parsed: config.SocketYml;
11
+ } | null;
7
12
  declare function getSetting<Key extends keyof Settings>(key: Key): Settings[Key];
8
13
  declare function updateSetting<Key extends keyof Settings>(key: Key, value: Settings[Key]): void;
9
- export { getSetting, updateSetting };
14
+ export { findSocketYmlSync, getSetting, updateSetting };
@@ -1,2 +1,2 @@
1
- declare function shadow(binName: 'npm' | 'npx', binArgs?: string[]): Promise<void>;
2
- export { shadow as default };
1
+ declare function shadowBin(binName: 'npm' | 'npx', binArgs?: string[]): Promise<void>;
2
+ export { shadowBin as default };
@@ -10,15 +10,12 @@ function _socketInterop(e) {
10
10
  }
11
11
 
12
12
  var path = require('node:path');
13
+ var process = require('node:process');
13
14
  var spawn = _socketInterop(require('@npmcli/promise-spawn'));
14
15
  var cmdShim = _socketInterop(require('cmd-shim'));
15
16
  var constants = require('./constants.js');
16
17
  var pathResolve = require('./path-resolve.js');
17
18
 
18
- const {
19
- WIN32,
20
- rootDistPath
21
- } = constants;
22
19
  async function installLinks(realBinPath, binName) {
23
20
  // Find package manager being shadowed by this process.
24
21
  const {
@@ -31,6 +28,10 @@ async function installLinks(realBinPath, binName) {
31
28
  console.error(`Socket unable to locate ${binName}; ensure it is available in the PATH environment variable.`);
32
29
  process.exit(127);
33
30
  }
31
+ // Lazily access constants.WIN32.
32
+ const {
33
+ WIN32
34
+ } = constants;
34
35
  // TODO: Is this early exit needed?
35
36
  if (WIN32 && binPath) {
36
37
  return binPath;
@@ -38,7 +39,9 @@ async function installLinks(realBinPath, binName) {
38
39
  // Move our bin directory to front of PATH so its found first.
39
40
  if (!shadowed) {
40
41
  if (WIN32) {
41
- await cmdShim(path.join(rootDistPath, `${binName}-cli.js`), path.join(realBinPath, binName));
42
+ await cmdShim(
43
+ // Lazily access constants.rootDistPath.
44
+ path.join(constants.rootDistPath, `${binName}-cli.js`), path.join(realBinPath, binName));
42
45
  }
43
46
  process.env['PATH'] = `${realBinPath}${path.delimiter}${process.env['PATH']}`;
44
47
  }
@@ -49,7 +52,7 @@ const {
49
52
  NPM,
50
53
  abortSignal
51
54
  } = constants;
52
- async function shadow(binName, binArgs = process.argv.slice(2)) {
55
+ async function shadowBin(binName, binArgs = process.argv.slice(2)) {
53
56
  process.exitCode = 1;
54
57
  const spawnPromise = spawn(
55
58
  // Lazily access constants.execPath.
@@ -80,4 +83,4 @@ async function shadow(binName, binArgs = process.argv.slice(2)) {
80
83
  await spawnPromise;
81
84
  }
82
85
 
83
- module.exports = shadow;
86
+ module.exports = shadowBin;
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ import { SocketSdk } from "@socketsecurity/sdk";
3
+ import { ObjectEncodingOptions, OpenMode, PathLike } from "node:fs";
4
+ import { promises as fs } from "node:fs";
5
+ import { readFileSync as fsReadFileSync } from "node:fs";
6
+ import { Abortable } from "node:events";
7
+ import { FileHandle } from "node:fs/promises";
8
+ import indentString from "@socketregistry/indent-string/index.cjs";
9
+ import { logSymbols } from "./logging.js";
10
+ declare function getDefaultToken(): string | undefined;
11
+ declare function getPublicToken(): string;
12
+ declare function setupSdk(apiToken?: string | undefined, apiBaseUrl?: string | undefined, proxy?: string | undefined): Promise<SocketSdk>;
13
+ declare function findUp(name: string | string[], { cwd }: {
14
+ cwd: string | undefined;
15
+ }): Promise<string | undefined>;
16
+ type ReadFileOptions = ObjectEncodingOptions & Abortable & {
17
+ flag?: OpenMode | undefined;
18
+ };
19
+ declare function readFileBinary(filepath: PathLike | FileHandle, options?: ReadFileOptions): Promise<Buffer>;
20
+ declare function readFileUtf8(filepath: PathLike | FileHandle, options?: ReadFileOptions): Promise<string>;
21
+ declare function safeReadFile(...args: Parameters<typeof fs.readFile>): ReturnType<typeof fs.readFile> | undefined;
22
+ declare function safeReadFileSync(...args: Parameters<typeof fsReadFileSync>): ReturnType<typeof fsReadFileSync> | undefined;
23
+ declare class ColorOrMarkdown {
24
+ useMarkdown: boolean;
25
+ constructor(useMarkdown: boolean);
26
+ bold(text: string): string;
27
+ header(text: string, level?: number): string;
28
+ hyperlink(text: string, url: string | undefined, { fallback, fallbackToUrl }?: {
29
+ fallback?: boolean;
30
+ fallbackToUrl?: boolean;
31
+ }): string;
32
+ indent(...args: Parameters<typeof indentString>): ReturnType<typeof indentString>;
33
+ italic(text: string): string;
34
+ json(value: any): string;
35
+ list(items: string[]): string;
36
+ get logSymbols(): typeof logSymbols;
37
+ }
38
+ declare function getSocketDevAlertUrl(alertType: string): string;
39
+ declare function getSocketDevPackageOverviewUrl(eco: string, name: string, version?: string): string;
40
+ export { getDefaultToken, getPublicToken, setupSdk, findUp, ReadFileOptions, readFileBinary, readFileUtf8, safeReadFile, safeReadFileSync, ColorOrMarkdown, getSocketDevAlertUrl, getSocketDevPackageOverviewUrl };
@@ -0,0 +1,301 @@
1
+ 'use strict';
2
+
3
+ function _socketInterop(e) {
4
+ let c = 0
5
+ for (const k in e ?? {}) {
6
+ c = c === 0 && k === 'default' ? 1 : 0
7
+ if (!c && k !== '__esModule') break
8
+ }
9
+ return c ? e.default : e
10
+ }
11
+
12
+ var terminalLink = _socketInterop(require('terminal-link'));
13
+ var colors = _socketInterop(require('yoctocolors-cjs'));
14
+ var indentString = require('@socketregistry/indent-string/index.cjs');
15
+ var pathResolve = require('./path-resolve.js');
16
+ var process = require('node:process');
17
+ var hpagent = _socketInterop(require('hpagent'));
18
+ var isInteractive = require('@socketregistry/is-interactive/index.cjs');
19
+ var registryConstants = require('@socketsecurity/registry/lib/constants');
20
+ var prompts = require('@socketsecurity/registry/lib/prompts');
21
+ var strings = require('@socketsecurity/registry/lib/strings');
22
+ var sdk = require('@socketsecurity/sdk');
23
+ var fs = require('node:fs');
24
+ var os = require('node:os');
25
+ var path = require('node:path');
26
+ var config = require('@socketsecurity/config');
27
+ var constants = require('./constants.js');
28
+
29
+ class AuthError extends Error {}
30
+ class InputError extends Error {
31
+ constructor(message, body) {
32
+ super(message);
33
+ this.body = body;
34
+ }
35
+ }
36
+ function isErrnoException(value) {
37
+ if (!(value instanceof Error)) {
38
+ return false;
39
+ }
40
+ return value.code !== undefined;
41
+ }
42
+
43
+ const markdownLogSymbols = {
44
+ __proto__: null,
45
+ info: ':information_source:',
46
+ error: ':stop_sign:',
47
+ success: ':white_check_mark:',
48
+ warning: ':warning:'
49
+ };
50
+ class ColorOrMarkdown {
51
+ constructor(useMarkdown) {
52
+ this.useMarkdown = !!useMarkdown;
53
+ }
54
+ bold(text) {
55
+ return this.useMarkdown ? `**${text}**` : colors.bold(`${text}`);
56
+ }
57
+ header(text, level = 1) {
58
+ return this.useMarkdown ? `\n${''.padStart(level, '#')} ${text}\n` : colors.underline(`\n${level === 1 ? colors.bold(text) : text}\n`);
59
+ }
60
+ hyperlink(text, url, {
61
+ fallback = true,
62
+ fallbackToUrl
63
+ } = {}) {
64
+ if (url) {
65
+ return this.useMarkdown ? `[${text}](${url})` : terminalLink(text, url, {
66
+ fallback: fallbackToUrl ? (_text, url) => url : fallback
67
+ });
68
+ }
69
+ return text;
70
+ }
71
+ indent(...args) {
72
+ return indentString(...args);
73
+ }
74
+ italic(text) {
75
+ return this.useMarkdown ? `_${text}_` : colors.italic(`${text}`);
76
+ }
77
+ json(value) {
78
+ return this.useMarkdown ? '```json\n' + JSON.stringify(value) + '\n```' : JSON.stringify(value);
79
+ }
80
+ list(items) {
81
+ const indentedContent = items.map(item => this.indent(item).trimStart());
82
+ return this.useMarkdown ? `* ${indentedContent.join('\n* ')}\n` : `${indentedContent.join('\n')}\n`;
83
+ }
84
+ get logSymbols() {
85
+ return this.useMarkdown ? markdownLogSymbols : pathResolve.logSymbols;
86
+ }
87
+ }
88
+
89
+ async function findUp(name, {
90
+ cwd = process.cwd()
91
+ }) {
92
+ let dir = path.resolve(cwd);
93
+ const {
94
+ root
95
+ } = path.parse(dir);
96
+ const names = [name].flat();
97
+ while (dir && dir !== root) {
98
+ for (const name of names) {
99
+ const filePath = path.join(dir, name);
100
+ try {
101
+ // eslint-disable-next-line no-await-in-loop
102
+ const stats = await fs.promises.stat(filePath);
103
+ if (stats.isFile()) {
104
+ return filePath;
105
+ }
106
+ } catch {}
107
+ }
108
+ dir = path.dirname(dir);
109
+ }
110
+ return undefined;
111
+ }
112
+ async function readFileBinary(filepath, options) {
113
+ return await fs.promises.readFile(filepath, {
114
+ ...options,
115
+ encoding: 'binary'
116
+ });
117
+ }
118
+ async function readFileUtf8(filepath, options) {
119
+ return await fs.promises.readFile(filepath, {
120
+ ...options,
121
+ encoding: 'utf8'
122
+ });
123
+ }
124
+ function safeReadFile(...args) {
125
+ try {
126
+ return fs.promises.readFile(...args);
127
+ } catch {}
128
+ return undefined;
129
+ }
130
+ function safeReadFileSync(...args) {
131
+ try {
132
+ return fs.readFileSync(...args);
133
+ } catch {}
134
+ return undefined;
135
+ }
136
+
137
+ const LOCALAPPDATA = 'LOCALAPPDATA';
138
+ let _settings;
139
+ function getSettings() {
140
+ if (_settings === undefined) {
141
+ _settings = {};
142
+ const settingsPath = getSettingsPath();
143
+ if (settingsPath) {
144
+ const raw = safeReadFileSync(settingsPath, 'utf8');
145
+ if (raw) {
146
+ try {
147
+ Object.assign(_settings, JSON.parse(Buffer.from(raw, 'base64').toString()));
148
+ } catch {
149
+ pathResolve.logger.warn(`Failed to parse settings at ${settingsPath}`);
150
+ }
151
+ } else {
152
+ fs.mkdirSync(path.dirname(settingsPath), {
153
+ recursive: true
154
+ });
155
+ }
156
+ }
157
+ }
158
+ return _settings;
159
+ }
160
+ let _settingsPath;
161
+ let _warnedSettingPathWin32Missing = false;
162
+ function getSettingsPath() {
163
+ if (_settingsPath === undefined) {
164
+ // Lazily access constants.WIN32.
165
+ const {
166
+ WIN32
167
+ } = constants;
168
+ let dataHome = WIN32 ? process.env[LOCALAPPDATA] : process.env['XDG_DATA_HOME'];
169
+ if (!dataHome) {
170
+ if (WIN32) {
171
+ if (!_warnedSettingPathWin32Missing) {
172
+ _warnedSettingPathWin32Missing = true;
173
+ pathResolve.logger.warn(`Missing %${LOCALAPPDATA}%`);
174
+ }
175
+ } else {
176
+ dataHome = path.join(os.homedir(), ...(process.platform === 'darwin' ? ['Library', 'Application Support'] : ['.local', 'share']));
177
+ }
178
+ }
179
+ _settingsPath = dataHome ? path.join(dataHome, 'socket', 'settings') : undefined;
180
+ }
181
+ return _settingsPath;
182
+ }
183
+ function findSocketYmlSync() {
184
+ let prevDir = null;
185
+ let dir = process.cwd();
186
+ while (dir !== prevDir) {
187
+ let ymlPath = path.join(dir, 'socket.yml');
188
+ let yml = safeReadFileSync(ymlPath, 'utf8');
189
+ if (yml === undefined) {
190
+ ymlPath = path.join(dir, 'socket.yaml');
191
+ yml = safeReadFileSync(ymlPath, 'utf8');
192
+ }
193
+ if (typeof yml === 'string') {
194
+ try {
195
+ return {
196
+ path: ymlPath,
197
+ parsed: config.parseSocketConfig(yml)
198
+ };
199
+ } catch {
200
+ throw new Error(`Found file but was unable to parse ${ymlPath}`);
201
+ }
202
+ }
203
+ prevDir = dir;
204
+ dir = path.join(dir, '..');
205
+ }
206
+ return null;
207
+ }
208
+ function getSetting(key) {
209
+ return getSettings()[key];
210
+ }
211
+ let pendingSave = false;
212
+ function updateSetting(key, value) {
213
+ const settings = getSettings();
214
+ settings[key] = value;
215
+ if (!pendingSave) {
216
+ pendingSave = true;
217
+ process.nextTick(() => {
218
+ pendingSave = false;
219
+ const settingsPath = getSettingsPath();
220
+ if (settingsPath) {
221
+ fs.writeFileSync(settingsPath, Buffer.from(JSON.stringify(settings)).toString('base64'));
222
+ }
223
+ });
224
+ }
225
+ }
226
+
227
+ // The API server that should be used for operations.
228
+ function getDefaultApiBaseUrl() {
229
+ const baseUrl = process.env['SOCKET_SECURITY_API_BASE_URL'] || getSetting('apiBaseUrl');
230
+ return strings.isNonEmptyString(baseUrl) ? baseUrl : undefined;
231
+ }
232
+
233
+ // The API server that should be used for operations.
234
+ function getDefaultHttpProxy() {
235
+ const apiProxy = process.env['SOCKET_SECURITY_API_PROXY'] || getSetting('apiProxy');
236
+ return strings.isNonEmptyString(apiProxy) ? apiProxy : undefined;
237
+ }
238
+
239
+ // This API key should be stored globally for the duration of the CLI execution.
240
+ let _defaultToken;
241
+ function getDefaultToken() {
242
+ const key = process.env['SOCKET_SECURITY_API_TOKEN'] ||
243
+ // Keep 'SOCKET_SECURITY_API_KEY' as an alias of 'SOCKET_SECURITY_API_TOKEN'.
244
+ // TODO: Remove 'SOCKET_SECURITY_API_KEY' alias.
245
+ process.env['SOCKET_SECURITY_API_KEY'] ||
246
+ // TODO: Rename the 'apiKey' setting to 'apiToken'.
247
+ getSetting('apiKey') || _defaultToken;
248
+ _defaultToken = strings.isNonEmptyString(key) ? key : undefined;
249
+ return _defaultToken;
250
+ }
251
+ function getPublicToken() {
252
+ return getDefaultToken() ?? registryConstants.SOCKET_PUBLIC_API_TOKEN;
253
+ }
254
+ async function setupSdk(apiToken = getDefaultToken(), apiBaseUrl = getDefaultApiBaseUrl(), proxy = getDefaultHttpProxy()) {
255
+ if (typeof apiToken !== 'string' && isInteractive()) {
256
+ apiToken = await prompts.password({
257
+ message: 'Enter your Socket.dev API key (not saved, use socket login to persist)'
258
+ });
259
+ _defaultToken = apiToken;
260
+ }
261
+ if (!apiToken) {
262
+ throw new AuthError('You need to provide an API key');
263
+ }
264
+ return new sdk.SocketSdk(apiToken, {
265
+ agent: proxy ? {
266
+ http: new hpagent.HttpProxyAgent({
267
+ proxy
268
+ }),
269
+ https: new hpagent.HttpsProxyAgent({
270
+ proxy
271
+ })
272
+ } : undefined,
273
+ baseUrl: apiBaseUrl,
274
+ // Lazily access constants.rootPkgJsonPath.
275
+ userAgent: sdk.createUserAgentFromPkgJson(require(constants.rootPkgJsonPath))
276
+ });
277
+ }
278
+
279
+ function getSocketDevAlertUrl(alertType) {
280
+ return `https://socket.dev/alerts/${alertType}`;
281
+ }
282
+ function getSocketDevPackageOverviewUrl(eco, name, version) {
283
+ return `https://socket.dev/${eco}/package/${name}${version ? `/overview/${version}` : ''}`;
284
+ }
285
+
286
+ exports.AuthError = AuthError;
287
+ exports.ColorOrMarkdown = ColorOrMarkdown;
288
+ exports.InputError = InputError;
289
+ exports.findSocketYmlSync = findSocketYmlSync;
290
+ exports.findUp = findUp;
291
+ exports.getDefaultToken = getDefaultToken;
292
+ exports.getPublicToken = getPublicToken;
293
+ exports.getSetting = getSetting;
294
+ exports.getSocketDevAlertUrl = getSocketDevAlertUrl;
295
+ exports.getSocketDevPackageOverviewUrl = getSocketDevPackageOverviewUrl;
296
+ exports.isErrnoException = isErrnoException;
297
+ exports.readFileBinary = readFileBinary;
298
+ exports.readFileUtf8 = readFileUtf8;
299
+ exports.safeReadFile = safeReadFile;
300
+ exports.setupSdk = setupSdk;
301
+ exports.updateSetting = updateSetting;