@socketsecurity/cli 0.14.6 → 0.14.8

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.
Files changed (2) hide show
  1. package/dist/cli.js +151 -86
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -12,9 +12,9 @@ var sdk = require('./sdk.js');
12
12
  var require$$1$2 = require('@inquirer/prompts');
13
13
  var require$$3$2 = require('@npmcli/package-json');
14
14
  var require$$4 = require('@socketsecurity/registry');
15
+ var require$$3$1 = require('semver');
15
16
  var require$$1$3 = require('@socketregistry/hyrious__bun.lockb');
16
17
  var require$$3 = require('browserslist');
17
- var require$$3$1 = require('semver');
18
18
  var require$$5$1 = require('which');
19
19
  var require$$2 = require('@apideck/better-ajv-errors');
20
20
  var require$$3$3 = require('@socketsecurity/config');
@@ -937,12 +937,13 @@ var _nodePath$3 = require$$1;
937
937
  var _hyrious__bun = require$$1$3;
938
938
  var _promiseSpawn$3 = require$$1$1;
939
939
  var _browserslist = require$$3;
940
- var _semver = require$$3$1;
940
+ var _semver$1 = require$$3$1;
941
941
  var _which = require$$5$1;
942
942
  var _fs = fs;
943
943
  var _json = json;
944
944
  var _objects$1 = objects;
945
945
  var _strings = strings;
946
+ const PNPM_WORKSPACE = 'pnpm-workspace';
946
947
  const AGENTS = packageManagerDetector.AGENTS = ['bun', 'npm', 'pnpm', 'yarn'];
947
948
  const LOCKS = packageManagerDetector.LOCKS = {
948
949
  'bun.lockb': 'bun',
@@ -993,17 +994,16 @@ const readLockFileByAgent = (() => {
993
994
  };
994
995
  })();
995
996
  async function detect({
996
- cwd,
997
+ cwd = process.cwd(),
997
998
  onUnknown
998
999
  } = {}) {
999
- const lockPath = await (0, _fs.findUp)(Object.keys(LOCKS), {
1000
+ let lockPath = await (0, _fs.findUp)(Object.keys(LOCKS), {
1000
1001
  cwd
1001
1002
  });
1002
1003
  const isHiddenLockFile = lockPath?.endsWith('.package-lock.json') ?? false;
1003
1004
  const pkgJsonPath = lockPath ? _nodePath$3.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await (0, _fs.findUp)('package.json', {
1004
1005
  cwd
1005
1006
  });
1006
-
1007
1007
  // Read Corepack `packageManager` field in package.json:
1008
1008
  // https://nodejs.org/api/packages.html#packagemanager
1009
1009
  const pkgJsonStr = (0, _fs.existsSync)(pkgJsonPath) ? await (0, _fs.readFileUtf8)(pkgJsonPath) : undefined;
@@ -1022,7 +1022,7 @@ async function detect({
1022
1022
  }
1023
1023
  }
1024
1024
  }
1025
- if (agent === undefined && !isHiddenLockFile && typeof lockPath === 'string') {
1025
+ if (agent === undefined && !isHiddenLockFile && typeof pkgJsonPath === 'string' && typeof lockPath === 'string') {
1026
1026
  agent = LOCKS[_nodePath$3.basename(lockPath)];
1027
1027
  }
1028
1028
  if (agent === undefined) {
@@ -1042,7 +1042,7 @@ async function detect({
1042
1042
  if (pkgJson) {
1043
1043
  const pkgPath = _nodePath$3.dirname(pkgJsonPath);
1044
1044
  isPrivate = !!pkgJson['private'];
1045
- isWorkspace = !!pkgJson['workspaces'] || agent === 'pnpm' && (0, _fs.existsSync)(_nodePath$3.join(pkgPath, 'pnpm-workspace.yaml'));
1045
+ isWorkspace = !!pkgJson['workspaces'] || (0, _fs.existsSync)(_nodePath$3.join(pkgPath, `${PNPM_WORKSPACE}.yaml`)) || (0, _fs.existsSync)(_nodePath$3.join(pkgPath, `${PNPM_WORKSPACE}.yml`));
1046
1046
  let browser;
1047
1047
  let node;
1048
1048
  const browserField = (0, _objects$1.getOwn)(pkgJson, 'browser');
@@ -1051,7 +1051,7 @@ async function detect({
1051
1051
  }
1052
1052
  const nodeRange = (0, _objects$1.getOwn)(pkgJson['engines'], 'node');
1053
1053
  if ((0, _strings.isNonEmptyString)(nodeRange)) {
1054
- node = MAINTAINED_NODE_VERSIONS.some(v => _semver.satisfies(v, nodeRange));
1054
+ node = MAINTAINED_NODE_VERSIONS.some(v => _semver$1.satisfies(v, nodeRange));
1055
1055
  }
1056
1056
  const browserslistQuery = (0, _objects$1.getOwn)(pkgJson, 'browserslist');
1057
1057
  if (Array.isArray(browserslistQuery)) {
@@ -1061,7 +1061,7 @@ async function detect({
1061
1061
  browser = browserslistTargets.length !== browserslistNodeTargets.length;
1062
1062
  }
1063
1063
  if (node === undefined && browserslistNodeTargets.length) {
1064
- node = MAINTAINED_NODE_VERSIONS.some(r => browserslistNodeTargets.some(v => _semver.satisfies(v, `^${r}`)));
1064
+ node = MAINTAINED_NODE_VERSIONS.some(r => browserslistNodeTargets.some(v => _semver$1.satisfies(v, `^${r}`)));
1065
1065
  }
1066
1066
  }
1067
1067
  if (browser !== undefined) {
@@ -1071,6 +1071,8 @@ async function detect({
1071
1071
  targets.node = node;
1072
1072
  }
1073
1073
  lockSrc = typeof lockPath === 'string' ? await readLockFileByAgent[agent](lockPath, agentExecPath) : undefined;
1074
+ } else {
1075
+ lockPath = undefined;
1074
1076
  }
1075
1077
  return {
1076
1078
  agent,
@@ -1130,31 +1132,47 @@ var _packageJson = require$$3$2;
1130
1132
  var _registry = require$$4;
1131
1133
  var _meow$m = _interopRequireDefault$n(vendor.build);
1132
1134
  var _ora$i = _interopRequireDefault$n(vendor.ora);
1135
+ var _semver = require$$3$1;
1133
1136
  var _formatting$k = formatting;
1134
1137
  var _objects = objects;
1135
1138
  var _packageManagerDetector = packageManagerDetector;
1136
1139
  var _regexps = regexps;
1137
1140
  var _sorts$1 = sorts;
1138
1141
  const distPath$1 = __dirname;
1142
+ const COMMAND_TITLE = 'Socket Optimize';
1139
1143
  const OVERRIDES_FIELD_NAME = 'overrides';
1140
1144
  const RESOLUTIONS_FIELD_NAME = 'resolutions';
1141
- const SOCKET_REGISTRY_NAME = '@socketregistry';
1142
- const SOCKET_REGISTRY_MAJOR_VERSION = '^1';
1143
- const allPackages = (0, _registry.getManifestData)('npm').filter(({
1144
- 1: d
1145
- }) => d.engines?.node?.startsWith('>=18')).map(({
1145
+ const availableOverrides = (0, _registry.getManifestData)('npm').filter(({
1146
1146
  1: d
1147
- }) => d.package);
1148
- const getManifestOverridesByAgent = {
1147
+ }) => d.engines?.node?.startsWith('>=18'));
1148
+ const getOverridesDataByAgent = {
1149
1149
  // npm overrides documentation:
1150
1150
  // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides
1151
- npm: pkgJson => pkgJson?.overrides ?? undefined,
1151
+ npm: pkgJson => {
1152
+ const overrides = pkgJson?.overrides ?? {};
1153
+ return {
1154
+ type: 'npm',
1155
+ overrides
1156
+ };
1157
+ },
1152
1158
  // pnpm overrides documentation:
1153
1159
  // https://pnpm.io/package_json#pnpmoverrides
1154
- pnpm: pkgJson => pkgJson?.pnpm?.overrides ?? undefined,
1160
+ pnpm: pkgJson => {
1161
+ const overrides = pkgJson?.pnpm?.overrides ?? undefined;
1162
+ return overrides ? {
1163
+ type: 'pnpm',
1164
+ overrides
1165
+ } : undefined;
1166
+ },
1155
1167
  // Yarn resolutions documentation:
1156
1168
  // https://yarnpkg.com/configuration/manifest#resolutions
1157
- yarn: pkgJson => pkgJson?.resolutions ?? undefined
1169
+ yarn: pkgJson => {
1170
+ const overrides = pkgJson?.resolutions ?? {};
1171
+ return {
1172
+ type: 'yarn',
1173
+ overrides
1174
+ };
1175
+ }
1158
1176
  };
1159
1177
  const lockIncludesByAgent = {
1160
1178
  npm: (lockSrc, name) => {
@@ -1186,16 +1204,22 @@ const updateManifestByAgent = {
1186
1204
  __proto__: null,
1187
1205
  npm(editablePkgJson, overrides) {
1188
1206
  editablePkgJson.update({
1207
+ __proto__: null,
1189
1208
  [OVERRIDES_FIELD_NAME]: overrides
1190
1209
  });
1191
1210
  },
1192
1211
  pnpm(editablePkgJson, overrides) {
1193
1212
  editablePkgJson.update({
1194
- [OVERRIDES_FIELD_NAME]: overrides
1213
+ pnpm: {
1214
+ __proto__: null,
1215
+ ...editablePkgJson.content['pnpm'],
1216
+ [OVERRIDES_FIELD_NAME]: overrides
1217
+ }
1195
1218
  });
1196
1219
  },
1197
1220
  yarn(editablePkgJson, overrides) {
1198
1221
  editablePkgJson.update({
1222
+ __proto__: null,
1199
1223
  [RESOLUTIONS_FIELD_NAME]: overrides
1200
1224
  });
1201
1225
  }
@@ -1206,48 +1230,91 @@ async function addOverrides({
1206
1230
  isWorkspace,
1207
1231
  lockSrc,
1208
1232
  lockIncludes,
1209
- pkgJsonPath,
1210
- overrides
1233
+ pkgJsonPath
1211
1234
  }, aoState) {
1212
1235
  const {
1213
1236
  packageNames
1214
1237
  } = aoState;
1215
- let addedCount = 0;
1216
- let clonedOverrides;
1217
- for (const name of allPackages) {
1218
- if (!(0, _objects.hasOwn)(overrides, name) && lockIncludes(lockSrc, name)) {
1219
- if (clonedOverrides === undefined) {
1220
- clonedOverrides = {
1221
- __proto__: null,
1222
- ...overrides
1223
- };
1238
+ const editablePkgJson = await _packageJson.load(_nodePath$2.dirname(pkgJsonPath));
1239
+ const {
1240
+ dependencies,
1241
+ devDependencies,
1242
+ peerDependencies,
1243
+ optionalDependencies
1244
+ } = editablePkgJson.content;
1245
+ const depEntries = [['dependencies', dependencies ? {
1246
+ __proto__: null,
1247
+ ...dependencies
1248
+ } : undefined], ['devDependencies', devDependencies ? {
1249
+ __proto__: null,
1250
+ ...devDependencies
1251
+ } : undefined], ['peerDependencies', peerDependencies ? {
1252
+ __proto__: null,
1253
+ ...peerDependencies
1254
+ } : undefined], ['optionalDependencies', optionalDependencies ? {
1255
+ __proto__: null,
1256
+ ...optionalDependencies
1257
+ } : undefined]].filter(({
1258
+ 1: o
1259
+ }) => o);
1260
+ const overridesDataObjects = [getOverridesDataByAgent['npm'](editablePkgJson.content)];
1261
+ const isApp = isPrivate || isWorkspace;
1262
+ const overridesData = !isApp || agent !== 'npm' ? getOverridesDataByAgent[isApp ? agent : 'yarn'](editablePkgJson.content) : undefined;
1263
+ if (overridesData) {
1264
+ overridesDataObjects.push(overridesData);
1265
+ }
1266
+ const aliasMap = new Map();
1267
+ for (const {
1268
+ 1: data
1269
+ } of availableOverrides) {
1270
+ const {
1271
+ name: regPkgName,
1272
+ package: origPkgName,
1273
+ version
1274
+ } = data;
1275
+ for (const {
1276
+ 1: depObj
1277
+ } of depEntries) {
1278
+ let pkgSpec = depObj[origPkgName];
1279
+ if (pkgSpec) {
1280
+ // Add package aliases for direct dependencies to avoid npm EOVERRIDE errors.
1281
+ // https://docs.npmjs.com/cli/v8/using-npm/package-spec#aliases
1282
+ const overrideSpecPrefix = `npm:${regPkgName}@`;
1283
+ if (!pkgSpec.startsWith(overrideSpecPrefix)) {
1284
+ aliasMap.set(regPkgName, pkgSpec);
1285
+ } else {
1286
+ packageNames.add(regPkgName);
1287
+ pkgSpec = `${overrideSpecPrefix}^${version}`;
1288
+ depObj[origPkgName] = pkgSpec;
1289
+ }
1290
+ aliasMap.set(origPkgName, pkgSpec);
1224
1291
  }
1225
- addedCount += 1;
1226
- packageNames.add(name);
1227
- clonedOverrides[name] = `npm:${SOCKET_REGISTRY_NAME}/${name}@${SOCKET_REGISTRY_MAJOR_VERSION}`;
1228
1292
  }
1229
- }
1230
- if (addedCount) {
1231
- const editablePkgJson = await _packageJson.load(_nodePath$2.dirname(pkgJsonPath));
1232
- const sortedOverrides = (0, _sorts$1.toSortedObject)(clonedOverrides);
1233
- updateManifestByAgent[agent](editablePkgJson, sortedOverrides);
1234
- if (!isPrivate && !isWorkspace) {
1235
- if ((0, _objects.hasOwn)(editablePkgJson.content, 'pnpm') && (0, _objects.isObjectObject)(editablePkgJson.content['pnpm'])) {
1236
- const pnpmKeys = Object.keys(editablePkgJson.content['pnpm']);
1237
- editablePkgJson.update(pnpmKeys.length === 1 && pnpmKeys[0] === 'overrides' ?
1238
- // Properties with undefined values are omitted when saved as JSON.
1239
- {
1240
- pnpm: undefined
1241
- } : {
1242
- pnpm: {
1243
- __proto__: null,
1244
- ...editablePkgJson.content['pnpm'],
1245
- overrides: undefined
1246
- }
1247
- });
1293
+ for (const {
1294
+ type,
1295
+ overrides
1296
+ } of overridesDataObjects) {
1297
+ if (overrides && !(0, _objects.hasOwn)(overrides, origPkgName) && lockIncludes(lockSrc, origPkgName)) {
1298
+ packageNames.add(regPkgName);
1299
+ overrides[origPkgName] =
1300
+ // With npm you may not set an override for a package that you directly
1301
+ // depend on unless both the dependency and the override itself share
1302
+ // the exact same spec. To make this limitation easier to deal with,
1303
+ // overrides may also be defined as a reference to a spec for a direct
1304
+ // dependency by prefixing the name of the package you wish the version
1305
+ // to match with a $.
1306
+ // https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
1307
+ type === 'npm' && aliasMap.has(origPkgName) && `$${origPkgName}` || `npm:${regPkgName}@^${_semver.major(version)}`;
1248
1308
  }
1249
- updateManifestByAgent.npm(editablePkgJson, sortedOverrides);
1250
- updateManifestByAgent.yarn(editablePkgJson, sortedOverrides);
1309
+ }
1310
+ }
1311
+ if (packageNames.size) {
1312
+ editablePkgJson.update(Object.fromEntries(depEntries));
1313
+ for (const {
1314
+ type,
1315
+ overrides
1316
+ } of overridesDataObjects) {
1317
+ updateManifestByAgent[type](editablePkgJson, (0, _sorts$1.toSortedObject)(overrides));
1251
1318
  }
1252
1319
  await editablePkgJson.save();
1253
1320
  }
@@ -1260,6 +1327,7 @@ const optimize = optimize$1.optimize = {
1260
1327
  }) {
1261
1328
  const commandContext = setupCommand$l(`${parentName} dependency optimize`, optimize.description, argv, importMeta);
1262
1329
  if (commandContext) {
1330
+ const cwd = process.cwd();
1263
1331
  const {
1264
1332
  agent,
1265
1333
  agentExecPath,
@@ -1272,49 +1340,44 @@ const optimize = optimize$1.optimize = {
1272
1340
  pkgJson,
1273
1341
  supported
1274
1342
  } = await (0, _packageManagerDetector.detect)({
1275
- cwd: process.cwd(),
1343
+ cwd,
1276
1344
  onUnknown(pkgManager) {
1277
- console.log(`⚠️ Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}: Defaulting to npm`);
1345
+ console.log(`⚠️ ${COMMAND_TITLE}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
1278
1346
  }
1279
1347
  });
1280
1348
  if (!supported) {
1281
- console.log('✘ The engines.node range is not supported.');
1349
+ console.log(`✘ ${COMMAND_TITLE}: Package engines.node range is not supported`);
1350
+ return;
1351
+ }
1352
+ const lockName = lockPath ? _nodePath$2.basename(lockPath) : 'lock file';
1353
+ if (lockSrc === undefined) {
1354
+ console.log(`✘ ${COMMAND_TITLE}: No ${lockName} found`);
1282
1355
  return;
1283
1356
  }
1284
1357
  if (pkgJson === undefined) {
1285
- console.log('✘ No package.json found.');
1358
+ console.log(`✘ ${COMMAND_TITLE}: No package.json found`);
1286
1359
  return;
1287
1360
  }
1361
+ if (lockPath && _nodePath$2.relative(cwd, lockPath).startsWith('.')) {
1362
+ console.log(`⚠️ ${COMMAND_TITLE}: Package ${lockName} found at ${lockPath}`);
1363
+ }
1288
1364
  const aoState = {
1289
1365
  output: pkgJsonStr,
1290
1366
  packageNames: new Set()
1291
1367
  };
1292
1368
  if (lockSrc) {
1293
- const configs = agent === 'bun' ? [{
1294
- agent: 'npm',
1295
- lockIncludes: lockIncludesByAgent.yarn,
1296
- overrides: getManifestOverridesByAgent.npm(pkgJson)
1297
- }, {
1298
- agent: 'yarn',
1299
- lockIncludes: lockIncludesByAgent.yarn,
1300
- overrides: getManifestOverridesByAgent.yarn(pkgJson)
1301
- }] : [{
1302
- agent,
1303
- lockIncludes: lockIncludesByAgent[agent],
1304
- overrides: getManifestOverridesByAgent[agent](pkgJson)
1305
- }];
1306
- for (const config of configs) {
1307
- await addOverrides({
1308
- __proto__: null,
1309
- isPrivate,
1310
- isWorkspace,
1311
- lockSrc,
1312
- pkgJsonPath,
1313
- pkgJsonStr,
1314
- pkgJson,
1315
- ...config
1316
- }, aoState);
1317
- }
1369
+ const lockIncludes = agent === 'bun' ? lockIncludesByAgent.yarn : lockIncludesByAgent[agent];
1370
+ await addOverrides({
1371
+ __proto__: null,
1372
+ agent: agent === 'bun' ? 'yarn' : agent,
1373
+ isPrivate,
1374
+ isWorkspace,
1375
+ lockIncludes,
1376
+ lockSrc,
1377
+ pkgJsonPath,
1378
+ pkgJsonStr,
1379
+ pkgJson
1380
+ }, aoState);
1318
1381
  }
1319
1382
  const {
1320
1383
  size: count
@@ -1324,7 +1387,6 @@ const optimize = optimize$1.optimize = {
1324
1387
  } else {
1325
1388
  console.log('Congratulations! Already Socket.dev optimized 🎉');
1326
1389
  }
1327
- const lockName = lockPath ? _nodePath$2.basename(lockPath) : 'lock file';
1328
1390
  const isNpm = agent === 'npm';
1329
1391
  if (isNpm || count) {
1330
1392
  // Always update package-lock.json until the npm overrides PR lands:
@@ -1347,9 +1409,12 @@ const optimize = optimize$1.optimize = {
1347
1409
  });
1348
1410
  }
1349
1411
  spinner.stop();
1412
+ if (isNpm) {
1413
+ console.log(`💡 Re-run ${COMMAND_TITLE} whenever ${lockName} changes.\n This can be skipped once npm ships https://github.com/npm/cli/pull/7025.`);
1414
+ }
1350
1415
  } catch {
1351
1416
  spinner.stop();
1352
- console.log(`✘ socket ${agent} install: Failed to update ${lockName}`);
1417
+ console.log(`✘ ${COMMAND_TITLE}: ${agent} install failed to update ${lockName}`);
1353
1418
  }
1354
1419
  }
1355
1420
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socketsecurity/cli",
3
- "version": "0.14.6",
3
+ "version": "0.14.8",
4
4
  "description": "CLI tool for Socket.dev",
5
5
  "homepage": "http://github.com/SocketDev/socket-cli-js",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "@npmcli/promise-spawn": "^8.0.1",
48
48
  "@socketregistry/hyrious__bun.lockb": "1.0.0",
49
49
  "@socketsecurity/config": "^2.1.3",
50
- "@socketsecurity/registry": "^1.0.4",
50
+ "@socketsecurity/registry": "^1.0.8",
51
51
  "@socketsecurity/sdk": "^1.3.0",
52
52
  "ansi-align": "^3.0.1",
53
53
  "blessed": "^0.1.81",