@westbayberry/dg 1.0.33 → 1.0.35
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/README.md +2 -9
- package/dist/index.mjs +1287 -568
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -38,6 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
39
39
|
mod
|
|
40
40
|
));
|
|
41
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
41
42
|
|
|
42
43
|
// src/auth.ts
|
|
43
44
|
var auth_exports = {};
|
|
@@ -53,7 +54,7 @@ __export(auth_exports, {
|
|
|
53
54
|
import { readFileSync, writeFileSync, chmodSync, unlinkSync, existsSync } from "node:fs";
|
|
54
55
|
import { join } from "node:path";
|
|
55
56
|
import { homedir } from "node:os";
|
|
56
|
-
import {
|
|
57
|
+
import { spawn } from "node:child_process";
|
|
57
58
|
import { randomUUID } from "node:crypto";
|
|
58
59
|
async function createAuthSession() {
|
|
59
60
|
let res;
|
|
@@ -154,24 +155,35 @@ function getOrCreateDeviceId() {
|
|
|
154
155
|
return deviceId;
|
|
155
156
|
}
|
|
156
157
|
function openBrowser(url) {
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
try {
|
|
159
|
+
const parsed = new URL(url);
|
|
160
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return;
|
|
161
|
+
} catch {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
159
164
|
let cmd;
|
|
165
|
+
let args;
|
|
160
166
|
switch (process.platform) {
|
|
161
167
|
case "darwin":
|
|
162
|
-
cmd =
|
|
168
|
+
cmd = "open";
|
|
169
|
+
args = [url];
|
|
163
170
|
break;
|
|
164
171
|
case "linux":
|
|
165
|
-
cmd =
|
|
172
|
+
cmd = "xdg-open";
|
|
173
|
+
args = [url];
|
|
166
174
|
break;
|
|
167
175
|
case "win32":
|
|
168
|
-
cmd =
|
|
176
|
+
cmd = "cmd.exe";
|
|
177
|
+
args = ["/c", "start", "", url];
|
|
169
178
|
break;
|
|
170
179
|
default:
|
|
171
180
|
return;
|
|
172
181
|
}
|
|
173
|
-
|
|
174
|
-
|
|
182
|
+
try {
|
|
183
|
+
const child = spawn(cmd, args, { stdio: "ignore", detached: true });
|
|
184
|
+
child.unref();
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
175
187
|
}
|
|
176
188
|
var WEB_BASE, CONFIG_FILE;
|
|
177
189
|
var init_auth = __esm({
|
|
@@ -211,6 +223,22 @@ function loadDgrc() {
|
|
|
211
223
|
}
|
|
212
224
|
return {};
|
|
213
225
|
}
|
|
226
|
+
function validateApiUrl(url) {
|
|
227
|
+
try {
|
|
228
|
+
const parsed = new URL(url);
|
|
229
|
+
const isLocal = parsed.hostname === "localhost" || parsed.hostname.startsWith("127.");
|
|
230
|
+
if (parsed.protocol !== "https:" && !isLocal) {
|
|
231
|
+
process.stderr.write(`Error: API URL must use HTTPS (got ${parsed.protocol}). Use localhost for local testing.
|
|
232
|
+
`);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
return url;
|
|
236
|
+
} catch {
|
|
237
|
+
process.stderr.write(`Error: Invalid API URL: ${url}
|
|
238
|
+
`);
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
214
242
|
function getVersion() {
|
|
215
243
|
try {
|
|
216
244
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -222,28 +250,46 @@ function getVersion() {
|
|
|
222
250
|
return "1.0.0";
|
|
223
251
|
}
|
|
224
252
|
}
|
|
225
|
-
function parseConfig(argv) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
253
|
+
function parseConfig(argv, strictFlags = true) {
|
|
254
|
+
let values;
|
|
255
|
+
let positionals;
|
|
256
|
+
try {
|
|
257
|
+
const parsed = parseArgs({
|
|
258
|
+
args: argv.slice(2),
|
|
259
|
+
options: {
|
|
260
|
+
"api-url": { type: "string" },
|
|
261
|
+
mode: { type: "string" },
|
|
262
|
+
"max-packages": { type: "string" },
|
|
263
|
+
json: { type: "boolean", default: false },
|
|
264
|
+
"scan-all": { type: "boolean", default: false },
|
|
265
|
+
"base-lockfile": { type: "string" },
|
|
266
|
+
workspace: { type: "string", short: "w" },
|
|
267
|
+
debug: { type: "boolean", default: false },
|
|
268
|
+
help: { type: "boolean", default: false },
|
|
269
|
+
version: { type: "boolean", default: false },
|
|
270
|
+
// Recognized but handled server-side via policy dashboard
|
|
271
|
+
"no-config": { type: "boolean", default: false },
|
|
272
|
+
allowlist: { type: "string" },
|
|
273
|
+
"block-threshold": { type: "string" },
|
|
274
|
+
"warn-threshold": { type: "string" }
|
|
275
|
+
},
|
|
276
|
+
allowPositionals: true,
|
|
277
|
+
strict: strictFlags
|
|
278
|
+
});
|
|
279
|
+
values = parsed.values;
|
|
280
|
+
positionals = parsed.positionals;
|
|
281
|
+
} catch (err) {
|
|
282
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
283
|
+
const match = raw.match(/Unknown option '([^']+)'/);
|
|
284
|
+
const msg = match ? `Unknown option '${match[1]}'.` : raw;
|
|
285
|
+
process.stderr.write(`
|
|
286
|
+
Error: ${msg}
|
|
287
|
+
`);
|
|
288
|
+
process.stderr.write(` Run 'dg --help' for available options.
|
|
289
|
+
|
|
290
|
+
`);
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
247
293
|
if (values.help) {
|
|
248
294
|
process.stdout.write(USAGE);
|
|
249
295
|
process.exit(0);
|
|
@@ -254,8 +300,7 @@ function parseConfig(argv) {
|
|
|
254
300
|
process.exit(0);
|
|
255
301
|
}
|
|
256
302
|
const command = positionals[0] ?? "scan";
|
|
257
|
-
const
|
|
258
|
-
const dgrc = noConfig ? {} : loadDgrc();
|
|
303
|
+
const dgrc = loadDgrc();
|
|
259
304
|
const apiKey = dgrc.apiKey && typeof dgrc.apiKey === "string" && dgrc.apiKey.startsWith("dg_live_") ? dgrc.apiKey : null;
|
|
260
305
|
const deviceId = getOrCreateDeviceId();
|
|
261
306
|
const modeRaw = values.mode ?? process.env.DG_MODE ?? dgrc.mode ?? "warn";
|
|
@@ -266,19 +311,8 @@ function parseConfig(argv) {
|
|
|
266
311
|
);
|
|
267
312
|
process.exit(1);
|
|
268
313
|
}
|
|
269
|
-
const allowlistRaw = values.allowlist ?? process.env.DG_ALLOWLIST ?? "";
|
|
270
|
-
const blockThreshold = Number(values["block-threshold"] ?? dgrc.blockThreshold ?? "70");
|
|
271
|
-
const warnThreshold = Number(values["warn-threshold"] ?? dgrc.warnThreshold ?? "60");
|
|
272
314
|
const maxPackages = Number(values["max-packages"] ?? dgrc.maxPackages ?? "200");
|
|
273
315
|
const debug = values.debug || process.env.DG_DEBUG === "1";
|
|
274
|
-
if (isNaN(blockThreshold) || blockThreshold < 0 || blockThreshold > 100) {
|
|
275
|
-
process.stderr.write("Error: --block-threshold must be a number between 0 and 100\n");
|
|
276
|
-
process.exit(1);
|
|
277
|
-
}
|
|
278
|
-
if (isNaN(warnThreshold) || warnThreshold < 0 || warnThreshold > 100) {
|
|
279
|
-
process.stderr.write("Error: --warn-threshold must be a number between 0 and 100\n");
|
|
280
|
-
process.exit(1);
|
|
281
|
-
}
|
|
282
316
|
if (isNaN(maxPackages) || maxPackages < 1 || maxPackages > 1e4) {
|
|
283
317
|
process.stderr.write("Error: --max-packages must be a number between 1 and 10000\n");
|
|
284
318
|
process.exit(1);
|
|
@@ -286,12 +320,11 @@ function parseConfig(argv) {
|
|
|
286
320
|
return {
|
|
287
321
|
apiKey,
|
|
288
322
|
deviceId,
|
|
289
|
-
apiUrl:
|
|
323
|
+
apiUrl: validateApiUrl(
|
|
324
|
+
values["api-url"] ?? process.env.DG_API_URL ?? dgrc.apiUrl ?? "https://api.westbayberry.com"
|
|
325
|
+
),
|
|
290
326
|
mode: modeRaw,
|
|
291
|
-
blockThreshold,
|
|
292
|
-
warnThreshold,
|
|
293
327
|
maxPackages,
|
|
294
|
-
allowlist: allowlistRaw ? allowlistRaw.split(",").map((s) => s.trim()).filter(Boolean) : dgrc.allowlist ?? [],
|
|
295
328
|
json: values.json,
|
|
296
329
|
scanAll: values["scan-all"],
|
|
297
330
|
baseLockfile: values["base-lockfile"] ?? null,
|
|
@@ -312,11 +345,13 @@ var init_config = __esm({
|
|
|
312
345
|
dependency-guardian scan [options]
|
|
313
346
|
dg scan [options]
|
|
314
347
|
dg npm install <pkg> [npm-flags]
|
|
348
|
+
dg pip install <pkg> [pip-flags]
|
|
315
349
|
dg wrap
|
|
316
350
|
|
|
317
351
|
Commands:
|
|
318
352
|
scan Scan dependencies (auto-discovers npm + Python projects)
|
|
319
353
|
npm Wrap npm commands \u2014 scans packages before installing
|
|
354
|
+
pip Wrap pip commands \u2014 scans packages before installing
|
|
320
355
|
hook install Install git pre-commit hook to scan lockfile changes
|
|
321
356
|
hook uninstall Remove the pre-commit hook
|
|
322
357
|
update Check for and install the latest version
|
|
@@ -327,16 +362,12 @@ var init_config = __esm({
|
|
|
327
362
|
Options:
|
|
328
363
|
--api-url <url> API base URL (default: https://api.westbayberry.com)
|
|
329
364
|
--mode <mode> block | warn | off (default: warn)
|
|
330
|
-
--block-threshold <n> Score threshold for blocking (default: 70)
|
|
331
|
-
--warn-threshold <n> Score threshold for warnings (default: 60)
|
|
332
365
|
--max-packages <n> Max packages per scan (default: 200)
|
|
333
|
-
--allowlist <pkgs> Comma-separated package names to skip
|
|
334
366
|
--json Output JSON for CI parsing
|
|
335
367
|
--scan-all Scan all packages, not just changed
|
|
336
368
|
--base-lockfile <path> Path to base lockfile for explicit diff
|
|
337
369
|
--workspace <dir> Scan a specific workspace subdirectory
|
|
338
370
|
--debug Show diagnostic output (discovery, batches, timing)
|
|
339
|
-
--no-config Skip loading .dgrc.json config file
|
|
340
371
|
--help Show this help message
|
|
341
372
|
--version Show version number
|
|
342
373
|
|
|
@@ -347,7 +378,6 @@ var init_config = __esm({
|
|
|
347
378
|
Environment Variables:
|
|
348
379
|
DG_API_URL API base URL
|
|
349
380
|
DG_MODE Mode (block/warn/off)
|
|
350
|
-
DG_ALLOWLIST Comma-separated allowlist
|
|
351
381
|
DG_DEBUG Enable debug output (set to 1)
|
|
352
382
|
DG_WORKSPACE Workspace subdirectory to scan
|
|
353
383
|
|
|
@@ -370,7 +400,7 @@ var init_config = __esm({
|
|
|
370
400
|
});
|
|
371
401
|
|
|
372
402
|
// src/npm-wrapper.ts
|
|
373
|
-
import { spawn } from "node:child_process";
|
|
403
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
374
404
|
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "node:fs";
|
|
375
405
|
import { join as join3 } from "node:path";
|
|
376
406
|
function parseNpmArgs(args) {
|
|
@@ -451,7 +481,7 @@ function parsePackageSpec(spec) {
|
|
|
451
481
|
}
|
|
452
482
|
async function resolveVersion(spec) {
|
|
453
483
|
return new Promise((resolve) => {
|
|
454
|
-
const child =
|
|
484
|
+
const child = spawn2("npm", ["view", spec, "version"], {
|
|
455
485
|
stdio: ["pipe", "pipe", "pipe"]
|
|
456
486
|
});
|
|
457
487
|
let stdout = "";
|
|
@@ -509,7 +539,7 @@ async function resolvePackages(specs) {
|
|
|
509
539
|
}
|
|
510
540
|
function runNpm(args) {
|
|
511
541
|
return new Promise((resolve) => {
|
|
512
|
-
const child =
|
|
542
|
+
const child = spawn2("npm", args, {
|
|
513
543
|
stdio: "inherit",
|
|
514
544
|
shell: false
|
|
515
545
|
});
|
|
@@ -3440,15 +3470,15 @@ var require_react_development = __commonJS({
|
|
|
3440
3470
|
var dispatcher = resolveDispatcher();
|
|
3441
3471
|
return dispatcher.useState(initialState);
|
|
3442
3472
|
}
|
|
3443
|
-
function
|
|
3473
|
+
function useReducer6(reducer5, initialArg, init) {
|
|
3444
3474
|
var dispatcher = resolveDispatcher();
|
|
3445
|
-
return dispatcher.useReducer(
|
|
3475
|
+
return dispatcher.useReducer(reducer5, initialArg, init);
|
|
3446
3476
|
}
|
|
3447
|
-
function
|
|
3477
|
+
function useRef9(initialValue) {
|
|
3448
3478
|
var dispatcher = resolveDispatcher();
|
|
3449
3479
|
return dispatcher.useRef(initialValue);
|
|
3450
3480
|
}
|
|
3451
|
-
function
|
|
3481
|
+
function useEffect16(create2, deps) {
|
|
3452
3482
|
var dispatcher = resolveDispatcher();
|
|
3453
3483
|
return dispatcher.useEffect(create2, deps);
|
|
3454
3484
|
}
|
|
@@ -3460,7 +3490,7 @@ var require_react_development = __commonJS({
|
|
|
3460
3490
|
var dispatcher = resolveDispatcher();
|
|
3461
3491
|
return dispatcher.useLayoutEffect(create2, deps);
|
|
3462
3492
|
}
|
|
3463
|
-
function
|
|
3493
|
+
function useCallback6(callback, deps) {
|
|
3464
3494
|
var dispatcher = resolveDispatcher();
|
|
3465
3495
|
return dispatcher.useCallback(callback, deps);
|
|
3466
3496
|
}
|
|
@@ -4227,18 +4257,18 @@ var require_react_development = __commonJS({
|
|
|
4227
4257
|
exports.memo = memo;
|
|
4228
4258
|
exports.startTransition = startTransition;
|
|
4229
4259
|
exports.unstable_act = act;
|
|
4230
|
-
exports.useCallback =
|
|
4260
|
+
exports.useCallback = useCallback6;
|
|
4231
4261
|
exports.useContext = useContext7;
|
|
4232
4262
|
exports.useDebugValue = useDebugValue;
|
|
4233
4263
|
exports.useDeferredValue = useDeferredValue;
|
|
4234
|
-
exports.useEffect =
|
|
4264
|
+
exports.useEffect = useEffect16;
|
|
4235
4265
|
exports.useId = useId;
|
|
4236
4266
|
exports.useImperativeHandle = useImperativeHandle;
|
|
4237
4267
|
exports.useInsertionEffect = useInsertionEffect;
|
|
4238
4268
|
exports.useLayoutEffect = useLayoutEffect2;
|
|
4239
4269
|
exports.useMemo = useMemo4;
|
|
4240
|
-
exports.useReducer =
|
|
4241
|
-
exports.useRef =
|
|
4270
|
+
exports.useReducer = useReducer6;
|
|
4271
|
+
exports.useRef = useRef9;
|
|
4242
4272
|
exports.useState = useState9;
|
|
4243
4273
|
exports.useSyncExternalStore = useSyncExternalStore;
|
|
4244
4274
|
exports.useTransition = useTransition;
|
|
@@ -11949,9 +11979,9 @@ var require_react_reconciler_development = __commonJS({
|
|
|
11949
11979
|
module.exports = function $$$reconciler($$$hostConfig) {
|
|
11950
11980
|
var exports2 = {};
|
|
11951
11981
|
"use strict";
|
|
11952
|
-
var
|
|
11982
|
+
var React18 = require_react();
|
|
11953
11983
|
var Scheduler = require_scheduler();
|
|
11954
|
-
var ReactSharedInternals =
|
|
11984
|
+
var ReactSharedInternals = React18.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
11955
11985
|
var suppressWarning = false;
|
|
11956
11986
|
function setSuppressWarning(newSuppressWarning) {
|
|
11957
11987
|
{
|
|
@@ -12015,7 +12045,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
12015
12045
|
var HostPortal = 4;
|
|
12016
12046
|
var HostComponent = 5;
|
|
12017
12047
|
var HostText = 6;
|
|
12018
|
-
var
|
|
12048
|
+
var Fragment7 = 7;
|
|
12019
12049
|
var Mode = 8;
|
|
12020
12050
|
var ContextConsumer = 9;
|
|
12021
12051
|
var ContextProvider = 10;
|
|
@@ -12155,7 +12185,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
12155
12185
|
return "DehydratedFragment";
|
|
12156
12186
|
case ForwardRef:
|
|
12157
12187
|
return getWrappedName$1(type, type.render, "ForwardRef");
|
|
12158
|
-
case
|
|
12188
|
+
case Fragment7:
|
|
12159
12189
|
return "Fragment";
|
|
12160
12190
|
case HostComponent:
|
|
12161
12191
|
return type;
|
|
@@ -15289,7 +15319,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
15289
15319
|
}
|
|
15290
15320
|
}
|
|
15291
15321
|
function updateFragment2(returnFiber, current2, fragment, lanes, key) {
|
|
15292
|
-
if (current2 === null || current2.tag !==
|
|
15322
|
+
if (current2 === null || current2.tag !== Fragment7) {
|
|
15293
15323
|
var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
|
|
15294
15324
|
created.return = returnFiber;
|
|
15295
15325
|
return created;
|
|
@@ -15692,7 +15722,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
15692
15722
|
if (child.key === key) {
|
|
15693
15723
|
var elementType = element.type;
|
|
15694
15724
|
if (elementType === REACT_FRAGMENT_TYPE) {
|
|
15695
|
-
if (child.tag ===
|
|
15725
|
+
if (child.tag === Fragment7) {
|
|
15696
15726
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
15697
15727
|
var existing = useFiber(child, element.props.children);
|
|
15698
15728
|
existing.return = returnFiber;
|
|
@@ -16940,7 +16970,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
16940
16970
|
function basicStateReducer(state, action) {
|
|
16941
16971
|
return typeof action === "function" ? action(state) : action;
|
|
16942
16972
|
}
|
|
16943
|
-
function mountReducer(
|
|
16973
|
+
function mountReducer(reducer5, initialArg, init) {
|
|
16944
16974
|
var hook = mountWorkInProgressHook();
|
|
16945
16975
|
var initialState;
|
|
16946
16976
|
if (init !== void 0) {
|
|
@@ -16954,20 +16984,20 @@ var require_react_reconciler_development = __commonJS({
|
|
|
16954
16984
|
interleaved: null,
|
|
16955
16985
|
lanes: NoLanes,
|
|
16956
16986
|
dispatch: null,
|
|
16957
|
-
lastRenderedReducer:
|
|
16987
|
+
lastRenderedReducer: reducer5,
|
|
16958
16988
|
lastRenderedState: initialState
|
|
16959
16989
|
};
|
|
16960
16990
|
hook.queue = queue;
|
|
16961
16991
|
var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
|
|
16962
16992
|
return [hook.memoizedState, dispatch];
|
|
16963
16993
|
}
|
|
16964
|
-
function updateReducer(
|
|
16994
|
+
function updateReducer(reducer5, initialArg, init) {
|
|
16965
16995
|
var hook = updateWorkInProgressHook();
|
|
16966
16996
|
var queue = hook.queue;
|
|
16967
16997
|
if (queue === null) {
|
|
16968
16998
|
throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
|
|
16969
16999
|
}
|
|
16970
|
-
queue.lastRenderedReducer =
|
|
17000
|
+
queue.lastRenderedReducer = reducer5;
|
|
16971
17001
|
var current2 = currentHook;
|
|
16972
17002
|
var baseQueue = current2.baseQueue;
|
|
16973
17003
|
var pendingQueue = queue.pending;
|
|
@@ -17029,7 +17059,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17029
17059
|
newState = update.eagerState;
|
|
17030
17060
|
} else {
|
|
17031
17061
|
var action = update.action;
|
|
17032
|
-
newState =
|
|
17062
|
+
newState = reducer5(newState, action);
|
|
17033
17063
|
}
|
|
17034
17064
|
}
|
|
17035
17065
|
update = update.next;
|
|
@@ -17062,13 +17092,13 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17062
17092
|
var dispatch = queue.dispatch;
|
|
17063
17093
|
return [hook.memoizedState, dispatch];
|
|
17064
17094
|
}
|
|
17065
|
-
function rerenderReducer(
|
|
17095
|
+
function rerenderReducer(reducer5, initialArg, init) {
|
|
17066
17096
|
var hook = updateWorkInProgressHook();
|
|
17067
17097
|
var queue = hook.queue;
|
|
17068
17098
|
if (queue === null) {
|
|
17069
17099
|
throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
|
|
17070
17100
|
}
|
|
17071
|
-
queue.lastRenderedReducer =
|
|
17101
|
+
queue.lastRenderedReducer = reducer5;
|
|
17072
17102
|
var dispatch = queue.dispatch;
|
|
17073
17103
|
var lastRenderPhaseUpdate = queue.pending;
|
|
17074
17104
|
var newState = hook.memoizedState;
|
|
@@ -17078,7 +17108,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17078
17108
|
var update = firstRenderPhaseUpdate;
|
|
17079
17109
|
do {
|
|
17080
17110
|
var action = update.action;
|
|
17081
|
-
newState =
|
|
17111
|
+
newState = reducer5(newState, action);
|
|
17082
17112
|
update = update.next;
|
|
17083
17113
|
} while (update !== firstRenderPhaseUpdate);
|
|
17084
17114
|
if (!objectIs(newState, hook.memoizedState)) {
|
|
@@ -17758,13 +17788,13 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17758
17788
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17759
17789
|
}
|
|
17760
17790
|
},
|
|
17761
|
-
useReducer: function(
|
|
17791
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
17762
17792
|
currentHookNameInDev = "useReducer";
|
|
17763
17793
|
mountHookTypesDev();
|
|
17764
17794
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
17765
17795
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
17766
17796
|
try {
|
|
17767
|
-
return mountReducer(
|
|
17797
|
+
return mountReducer(reducer5, initialArg, init);
|
|
17768
17798
|
} finally {
|
|
17769
17799
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17770
17800
|
}
|
|
@@ -17862,13 +17892,13 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17862
17892
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17863
17893
|
}
|
|
17864
17894
|
},
|
|
17865
|
-
useReducer: function(
|
|
17895
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
17866
17896
|
currentHookNameInDev = "useReducer";
|
|
17867
17897
|
updateHookTypesDev();
|
|
17868
17898
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
17869
17899
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
17870
17900
|
try {
|
|
17871
|
-
return mountReducer(
|
|
17901
|
+
return mountReducer(reducer5, initialArg, init);
|
|
17872
17902
|
} finally {
|
|
17873
17903
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17874
17904
|
}
|
|
@@ -17966,13 +17996,13 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17966
17996
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17967
17997
|
}
|
|
17968
17998
|
},
|
|
17969
|
-
useReducer: function(
|
|
17999
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
17970
18000
|
currentHookNameInDev = "useReducer";
|
|
17971
18001
|
updateHookTypesDev();
|
|
17972
18002
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
17973
18003
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
17974
18004
|
try {
|
|
17975
|
-
return updateReducer(
|
|
18005
|
+
return updateReducer(reducer5, initialArg, init);
|
|
17976
18006
|
} finally {
|
|
17977
18007
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
17978
18008
|
}
|
|
@@ -18070,13 +18100,13 @@ var require_react_reconciler_development = __commonJS({
|
|
|
18070
18100
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18071
18101
|
}
|
|
18072
18102
|
},
|
|
18073
|
-
useReducer: function(
|
|
18103
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
18074
18104
|
currentHookNameInDev = "useReducer";
|
|
18075
18105
|
updateHookTypesDev();
|
|
18076
18106
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
18077
18107
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
|
|
18078
18108
|
try {
|
|
18079
|
-
return rerenderReducer(
|
|
18109
|
+
return rerenderReducer(reducer5, initialArg, init);
|
|
18080
18110
|
} finally {
|
|
18081
18111
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18082
18112
|
}
|
|
@@ -18182,14 +18212,14 @@ var require_react_reconciler_development = __commonJS({
|
|
|
18182
18212
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18183
18213
|
}
|
|
18184
18214
|
},
|
|
18185
|
-
useReducer: function(
|
|
18215
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
18186
18216
|
currentHookNameInDev = "useReducer";
|
|
18187
18217
|
warnInvalidHookAccess();
|
|
18188
18218
|
mountHookTypesDev();
|
|
18189
18219
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
18190
18220
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
|
|
18191
18221
|
try {
|
|
18192
|
-
return mountReducer(
|
|
18222
|
+
return mountReducer(reducer5, initialArg, init);
|
|
18193
18223
|
} finally {
|
|
18194
18224
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18195
18225
|
}
|
|
@@ -18303,14 +18333,14 @@ var require_react_reconciler_development = __commonJS({
|
|
|
18303
18333
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18304
18334
|
}
|
|
18305
18335
|
},
|
|
18306
|
-
useReducer: function(
|
|
18336
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
18307
18337
|
currentHookNameInDev = "useReducer";
|
|
18308
18338
|
warnInvalidHookAccess();
|
|
18309
18339
|
updateHookTypesDev();
|
|
18310
18340
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
18311
18341
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
18312
18342
|
try {
|
|
18313
|
-
return updateReducer(
|
|
18343
|
+
return updateReducer(reducer5, initialArg, init);
|
|
18314
18344
|
} finally {
|
|
18315
18345
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18316
18346
|
}
|
|
@@ -18424,14 +18454,14 @@ var require_react_reconciler_development = __commonJS({
|
|
|
18424
18454
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18425
18455
|
}
|
|
18426
18456
|
},
|
|
18427
|
-
useReducer: function(
|
|
18457
|
+
useReducer: function(reducer5, initialArg, init) {
|
|
18428
18458
|
currentHookNameInDev = "useReducer";
|
|
18429
18459
|
warnInvalidHookAccess();
|
|
18430
18460
|
updateHookTypesDev();
|
|
18431
18461
|
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
|
18432
18462
|
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
|
18433
18463
|
try {
|
|
18434
|
-
return rerenderReducer(
|
|
18464
|
+
return rerenderReducer(reducer5, initialArg, init);
|
|
18435
18465
|
} finally {
|
|
18436
18466
|
ReactCurrentDispatcher$1.current = prevDispatcher;
|
|
18437
18467
|
}
|
|
@@ -21183,7 +21213,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
21183
21213
|
var _resolvedProps2 = workInProgress2.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
|
|
21184
21214
|
return updateForwardRef(current2, workInProgress2, type, _resolvedProps2, renderLanes2);
|
|
21185
21215
|
}
|
|
21186
|
-
case
|
|
21216
|
+
case Fragment7:
|
|
21187
21217
|
return updateFragment(current2, workInProgress2, renderLanes2);
|
|
21188
21218
|
case Mode:
|
|
21189
21219
|
return updateMode(current2, workInProgress2, renderLanes2);
|
|
@@ -21620,7 +21650,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
21620
21650
|
case SimpleMemoComponent:
|
|
21621
21651
|
case FunctionComponent:
|
|
21622
21652
|
case ForwardRef:
|
|
21623
|
-
case
|
|
21653
|
+
case Fragment7:
|
|
21624
21654
|
case Mode:
|
|
21625
21655
|
case Profiler:
|
|
21626
21656
|
case ContextConsumer:
|
|
@@ -26388,7 +26418,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
26388
26418
|
return fiber;
|
|
26389
26419
|
}
|
|
26390
26420
|
function createFiberFromFragment(elements, mode, lanes, key) {
|
|
26391
|
-
var fiber = createFiber(
|
|
26421
|
+
var fiber = createFiber(Fragment7, elements, key, mode);
|
|
26392
26422
|
fiber.lanes = lanes;
|
|
26393
26423
|
return fiber;
|
|
26394
26424
|
}
|
|
@@ -27588,9 +27618,9 @@ var init_ansi_styles = __esm({
|
|
|
27588
27618
|
|
|
27589
27619
|
// node_modules/wrap-ansi/index.js
|
|
27590
27620
|
function wrapAnsi(string, columns, options) {
|
|
27591
|
-
return String(string).normalize().replaceAll("\r\n", "\n").split("\n").map((line) =>
|
|
27621
|
+
return String(string).normalize().replaceAll("\r\n", "\n").split("\n").map((line) => exec(line, columns, options)).join("\n");
|
|
27592
27622
|
}
|
|
27593
|
-
var ESCAPES, END_CODE, ANSI_ESCAPE_BELL, ANSI_CSI, ANSI_OSC, ANSI_SGR_TERMINATOR, ANSI_ESCAPE_LINK, wrapAnsiCode, wrapAnsiHyperlink, wordLengths, wrapWord, stringVisibleTrimSpacesRight,
|
|
27623
|
+
var ESCAPES, END_CODE, ANSI_ESCAPE_BELL, ANSI_CSI, ANSI_OSC, ANSI_SGR_TERMINATOR, ANSI_ESCAPE_LINK, wrapAnsiCode, wrapAnsiHyperlink, wordLengths, wrapWord, stringVisibleTrimSpacesRight, exec;
|
|
27594
27624
|
var init_wrap_ansi = __esm({
|
|
27595
27625
|
"node_modules/wrap-ansi/index.js"() {
|
|
27596
27626
|
init_string_width();
|
|
@@ -27662,7 +27692,7 @@ var init_wrap_ansi = __esm({
|
|
|
27662
27692
|
}
|
|
27663
27693
|
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
27664
27694
|
};
|
|
27665
|
-
|
|
27695
|
+
exec = (string, columns, options = {}) => {
|
|
27666
27696
|
if (options.trim !== false && string.trim() === "") {
|
|
27667
27697
|
return "";
|
|
27668
27698
|
}
|
|
@@ -30753,7 +30783,7 @@ var require_websocket = __commonJS({
|
|
|
30753
30783
|
var tls = __require("tls");
|
|
30754
30784
|
var { randomBytes, createHash } = __require("crypto");
|
|
30755
30785
|
var { Duplex, Readable } = __require("stream");
|
|
30756
|
-
var { URL } = __require("url");
|
|
30786
|
+
var { URL: URL2 } = __require("url");
|
|
30757
30787
|
var PerMessageDeflate = require_permessage_deflate();
|
|
30758
30788
|
var Receiver2 = require_receiver();
|
|
30759
30789
|
var Sender2 = require_sender();
|
|
@@ -31246,11 +31276,11 @@ var require_websocket = __commonJS({
|
|
|
31246
31276
|
);
|
|
31247
31277
|
}
|
|
31248
31278
|
let parsedUrl;
|
|
31249
|
-
if (address instanceof
|
|
31279
|
+
if (address instanceof URL2) {
|
|
31250
31280
|
parsedUrl = address;
|
|
31251
31281
|
} else {
|
|
31252
31282
|
try {
|
|
31253
|
-
parsedUrl = new
|
|
31283
|
+
parsedUrl = new URL2(address);
|
|
31254
31284
|
} catch (e) {
|
|
31255
31285
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
31256
31286
|
}
|
|
@@ -31387,7 +31417,7 @@ var require_websocket = __commonJS({
|
|
|
31387
31417
|
req.abort();
|
|
31388
31418
|
let addr;
|
|
31389
31419
|
try {
|
|
31390
|
-
addr = new
|
|
31420
|
+
addr = new URL2(location, address);
|
|
31391
31421
|
} catch (e) {
|
|
31392
31422
|
const err = new SyntaxError(`Invalid URL: ${location}`);
|
|
31393
31423
|
emitErrorAndClose(websocket, err);
|
|
@@ -37902,7 +37932,7 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
37902
37932
|
if (process.env.NODE_ENV !== "production") {
|
|
37903
37933
|
(function() {
|
|
37904
37934
|
"use strict";
|
|
37905
|
-
var
|
|
37935
|
+
var React18 = require_react();
|
|
37906
37936
|
var REACT_ELEMENT_TYPE = Symbol.for("react.element");
|
|
37907
37937
|
var REACT_PORTAL_TYPE = Symbol.for("react.portal");
|
|
37908
37938
|
var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
@@ -37928,7 +37958,7 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
37928
37958
|
}
|
|
37929
37959
|
return null;
|
|
37930
37960
|
}
|
|
37931
|
-
var ReactSharedInternals =
|
|
37961
|
+
var ReactSharedInternals = React18.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
37932
37962
|
function error(format) {
|
|
37933
37963
|
{
|
|
37934
37964
|
{
|
|
@@ -38778,11 +38808,11 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
38778
38808
|
return jsxWithValidation(type, props, key, false);
|
|
38779
38809
|
}
|
|
38780
38810
|
}
|
|
38781
|
-
var
|
|
38782
|
-
var
|
|
38811
|
+
var jsx12 = jsxWithValidationDynamic;
|
|
38812
|
+
var jsxs14 = jsxWithValidationStatic;
|
|
38783
38813
|
exports.Fragment = REACT_FRAGMENT_TYPE;
|
|
38784
|
-
exports.jsx =
|
|
38785
|
-
exports.jsxs =
|
|
38814
|
+
exports.jsx = jsx12;
|
|
38815
|
+
exports.jsxs = jsxs14;
|
|
38786
38816
|
})();
|
|
38787
38817
|
}
|
|
38788
38818
|
}
|
|
@@ -38919,6 +38949,38 @@ var init_LoginApp = __esm({
|
|
|
38919
38949
|
}
|
|
38920
38950
|
});
|
|
38921
38951
|
|
|
38952
|
+
// src/sanitize.ts
|
|
38953
|
+
import { stripVTControlCharacters } from "node:util";
|
|
38954
|
+
function sanitize(s) {
|
|
38955
|
+
return stripVTControlCharacters(s);
|
|
38956
|
+
}
|
|
38957
|
+
function sanitizeResponse(response) {
|
|
38958
|
+
return {
|
|
38959
|
+
...response,
|
|
38960
|
+
packages: response.packages.map((pkg) => ({
|
|
38961
|
+
...pkg,
|
|
38962
|
+
name: sanitize(pkg.name),
|
|
38963
|
+
version: sanitize(pkg.version),
|
|
38964
|
+
findings: pkg.findings.map((f) => ({
|
|
38965
|
+
...f,
|
|
38966
|
+
id: sanitize(f.id ?? ""),
|
|
38967
|
+
title: sanitize(f.title),
|
|
38968
|
+
evidence: f.evidence.map(sanitize)
|
|
38969
|
+
})),
|
|
38970
|
+
reasons: (pkg.reasons ?? []).map(sanitize),
|
|
38971
|
+
recommendation: pkg.recommendation ? sanitize(pkg.recommendation) : void 0
|
|
38972
|
+
})),
|
|
38973
|
+
safeVersions: Object.fromEntries(
|
|
38974
|
+
Object.entries(response.safeVersions).map(([k, v]) => [sanitize(k), sanitize(v)])
|
|
38975
|
+
)
|
|
38976
|
+
};
|
|
38977
|
+
}
|
|
38978
|
+
var init_sanitize = __esm({
|
|
38979
|
+
"src/sanitize.ts"() {
|
|
38980
|
+
"use strict";
|
|
38981
|
+
}
|
|
38982
|
+
});
|
|
38983
|
+
|
|
38922
38984
|
// src/api.ts
|
|
38923
38985
|
function buildHeaders(config) {
|
|
38924
38986
|
const headers = {
|
|
@@ -38969,7 +39031,7 @@ async function callAnalyzeAPI(packages, config, onProgress) {
|
|
|
38969
39031
|
results.push(result);
|
|
38970
39032
|
}
|
|
38971
39033
|
if (process.env.DG_PERF) console.error(`[CLI-PERF] total: ${packages.length} packages \u2192 ${Date.now() - tTotal}ms`);
|
|
38972
|
-
return mergeResponses(results
|
|
39034
|
+
return mergeResponses(results);
|
|
38973
39035
|
}
|
|
38974
39036
|
async function callBatchWithRetry(packages, config) {
|
|
38975
39037
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
@@ -38992,10 +39054,10 @@ async function callBatchWithRetry(packages, config) {
|
|
|
38992
39054
|
}
|
|
38993
39055
|
throw new Error("Exhausted retries");
|
|
38994
39056
|
}
|
|
38995
|
-
function mergeResponses(results
|
|
39057
|
+
function mergeResponses(results) {
|
|
38996
39058
|
const allPackages = results.flatMap((r) => r.packages);
|
|
38997
39059
|
const maxScore = Math.max(0, ...allPackages.map((p) => p.score));
|
|
38998
|
-
const action = maxScore >=
|
|
39060
|
+
const action = maxScore >= 70 ? "block" : maxScore >= 60 ? "warn" : "pass";
|
|
38999
39061
|
const safeVersions = {};
|
|
39000
39062
|
for (const r of results) {
|
|
39001
39063
|
Object.assign(safeVersions, r.safeVersions);
|
|
@@ -39016,11 +39078,7 @@ async function callAnalyzeBatch(packages, config) {
|
|
|
39016
39078
|
version: p.version,
|
|
39017
39079
|
previousVersion: p.previousVersion,
|
|
39018
39080
|
isNew: p.isNew
|
|
39019
|
-
}))
|
|
39020
|
-
config: {
|
|
39021
|
-
blockThreshold: config.blockThreshold,
|
|
39022
|
-
warnThreshold: config.warnThreshold
|
|
39023
|
-
}
|
|
39081
|
+
}))
|
|
39024
39082
|
};
|
|
39025
39083
|
const controller = new AbortController();
|
|
39026
39084
|
const timeoutId = setTimeout(() => controller.abort(), 18e4);
|
|
@@ -39065,7 +39123,11 @@ async function callAnalyzeBatch(packages, config) {
|
|
|
39065
39123
|
body
|
|
39066
39124
|
);
|
|
39067
39125
|
}
|
|
39068
|
-
|
|
39126
|
+
const raw = await response.json();
|
|
39127
|
+
if (!raw || typeof raw.score !== "number" || !Array.isArray(raw.packages)) {
|
|
39128
|
+
throw new APIError("Invalid API response format", 0, "");
|
|
39129
|
+
}
|
|
39130
|
+
return sanitizeResponse(raw);
|
|
39069
39131
|
}
|
|
39070
39132
|
async function callPyPIAnalyzeAPI(packages, config, onProgress) {
|
|
39071
39133
|
const batchSize = config.apiKey ? BATCH_SIZE : ANON_BATCH_SIZE;
|
|
@@ -39084,7 +39146,7 @@ async function callPyPIAnalyzeAPI(packages, config, onProgress) {
|
|
|
39084
39146
|
if (onProgress) onProgress(completed, packages.length);
|
|
39085
39147
|
results.push(result);
|
|
39086
39148
|
}
|
|
39087
|
-
return mergeResponses(results
|
|
39149
|
+
return mergeResponses(results);
|
|
39088
39150
|
}
|
|
39089
39151
|
async function callPyPIBatch(packages, config) {
|
|
39090
39152
|
const url = `${config.apiUrl}/v1/pypi/analyze`;
|
|
@@ -39094,11 +39156,7 @@ async function callPyPIBatch(packages, config) {
|
|
|
39094
39156
|
version: p.version,
|
|
39095
39157
|
previousVersion: p.previousVersion ?? null,
|
|
39096
39158
|
isNew: p.isNew ?? true
|
|
39097
|
-
}))
|
|
39098
|
-
config: {
|
|
39099
|
-
blockThreshold: config.blockThreshold,
|
|
39100
|
-
warnThreshold: config.warnThreshold
|
|
39101
|
-
}
|
|
39159
|
+
}))
|
|
39102
39160
|
};
|
|
39103
39161
|
const controller = new AbortController();
|
|
39104
39162
|
const timeoutId = setTimeout(() => controller.abort(), 18e4);
|
|
@@ -39139,12 +39197,17 @@ async function callPyPIBatch(packages, config) {
|
|
|
39139
39197
|
const body = await response.text();
|
|
39140
39198
|
throw new APIError(`API returned ${response.status}: ${body}`, response.status, body);
|
|
39141
39199
|
}
|
|
39142
|
-
|
|
39200
|
+
const raw = await response.json();
|
|
39201
|
+
if (!raw || typeof raw.score !== "number" || !Array.isArray(raw.packages)) {
|
|
39202
|
+
throw new APIError("Invalid API response format", 0, "");
|
|
39203
|
+
}
|
|
39204
|
+
return sanitizeResponse(raw);
|
|
39143
39205
|
}
|
|
39144
39206
|
var APIError, TrialExhaustedError, BATCH_SIZE, ANON_BATCH_SIZE, MAX_RETRIES, RETRY_DELAY_MS;
|
|
39145
39207
|
var init_api = __esm({
|
|
39146
39208
|
"src/api.ts"() {
|
|
39147
39209
|
"use strict";
|
|
39210
|
+
init_sanitize();
|
|
39148
39211
|
APIError = class extends Error {
|
|
39149
39212
|
constructor(message, statusCode, body) {
|
|
39150
39213
|
super(message);
|
|
@@ -39179,11 +39242,15 @@ function parseLockfile(content) {
|
|
|
39179
39242
|
const name = extractPackageName(path);
|
|
39180
39243
|
if (name && !packages.has(name)) {
|
|
39181
39244
|
const e = entry;
|
|
39245
|
+
const deps = e.dependencies;
|
|
39182
39246
|
packages.set(name, {
|
|
39183
39247
|
version: e.version ?? "",
|
|
39184
39248
|
resolved: e.resolved,
|
|
39185
39249
|
integrity: e.integrity,
|
|
39186
|
-
dev: e.dev
|
|
39250
|
+
dev: e.dev,
|
|
39251
|
+
optional: e.optional,
|
|
39252
|
+
hasPlatformRestriction: !!(e.os || e.cpu),
|
|
39253
|
+
dependencies: deps && typeof deps === "object" ? deps : void 0
|
|
39187
39254
|
});
|
|
39188
39255
|
}
|
|
39189
39256
|
}
|
|
@@ -39405,26 +39472,40 @@ var init_parse_package_json = __esm({
|
|
|
39405
39472
|
});
|
|
39406
39473
|
|
|
39407
39474
|
// src/lockfile.ts
|
|
39408
|
-
import { execFileSync } from "node:child_process";
|
|
39409
|
-
import { readFileSync as readFileSync6, existsSync as existsSync5 } from "node:fs";
|
|
39475
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
39476
|
+
import { readFileSync as readFileSync6, existsSync as existsSync5, statSync } from "node:fs";
|
|
39410
39477
|
import { join as join5 } from "node:path";
|
|
39478
|
+
function readFileSafe(path) {
|
|
39479
|
+
const size = statSync(path).size;
|
|
39480
|
+
if (size > MAX_LOCKFILE_BYTES) {
|
|
39481
|
+
throw new Error(`Lockfile too large (${(size / 1024 / 1024).toFixed(0)} MB, max 50 MB): ${path}`);
|
|
39482
|
+
}
|
|
39483
|
+
return readFileSync6(path, "utf-8");
|
|
39484
|
+
}
|
|
39411
39485
|
function discoverChanges(cwd2, config) {
|
|
39412
39486
|
if (config.workspace) {
|
|
39413
39487
|
cwd2 = join5(cwd2, config.workspace);
|
|
39414
39488
|
}
|
|
39415
39489
|
const lockfileInfo = findLockfile(cwd2);
|
|
39416
39490
|
if (!lockfileInfo) {
|
|
39491
|
+
const pythonFiles = ["requirements.txt", "Pipfile.lock", "poetry.lock"];
|
|
39492
|
+
const hasPython = pythonFiles.some((f) => existsSync5(join5(cwd2, f)));
|
|
39493
|
+
if (hasPython) {
|
|
39494
|
+
return { packages: [], method: "fallback", skipped: [] };
|
|
39495
|
+
}
|
|
39417
39496
|
throw new Error(
|
|
39418
|
-
"No lockfile found (package-lock.json, yarn.lock,
|
|
39497
|
+
"No lockfile found (package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Pipfile.lock, or poetry.lock). Run from your project root or use --base-lockfile."
|
|
39419
39498
|
);
|
|
39420
39499
|
}
|
|
39421
|
-
const headContent =
|
|
39500
|
+
const headContent = readFileSafe(lockfileInfo.path);
|
|
39422
39501
|
const headParsed = parseLockfileByType(headContent, lockfileInfo.type);
|
|
39423
39502
|
const directDeps = getDirectDeps(cwd2);
|
|
39424
39503
|
if (config.scanAll) {
|
|
39425
39504
|
const packages2 = [];
|
|
39426
39505
|
for (const [name, entry] of headParsed.packages) {
|
|
39427
39506
|
if (packages2.length >= config.maxPackages) break;
|
|
39507
|
+
if (entry.optional && entry.hasPlatformRestriction) continue;
|
|
39508
|
+
if (name === SELF_PACKAGE) continue;
|
|
39428
39509
|
packages2.push({
|
|
39429
39510
|
name,
|
|
39430
39511
|
version: entry.version,
|
|
@@ -39438,11 +39519,11 @@ function discoverChanges(cwd2, config) {
|
|
|
39438
39519
|
if (!existsSync5(config.baseLockfile)) {
|
|
39439
39520
|
throw new Error(`Base lockfile not found: ${config.baseLockfile}`);
|
|
39440
39521
|
}
|
|
39441
|
-
const baseContent2 =
|
|
39522
|
+
const baseContent2 = readFileSafe(config.baseLockfile);
|
|
39442
39523
|
const baseParsed = parseLockfile(baseContent2);
|
|
39443
39524
|
const diff2 = diffLockfiles(baseParsed, headParsed, config.maxPackages, directDeps);
|
|
39444
39525
|
return {
|
|
39445
|
-
packages: diff2.changes.map(toPackageInput),
|
|
39526
|
+
packages: diff2.changes.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
39446
39527
|
method: "base-lockfile",
|
|
39447
39528
|
skipped: diff2.skipped
|
|
39448
39529
|
};
|
|
@@ -39452,14 +39533,14 @@ function discoverChanges(cwd2, config) {
|
|
|
39452
39533
|
const baseParsed = parseLockfile(baseContent);
|
|
39453
39534
|
const diff2 = diffLockfiles(baseParsed, headParsed, config.maxPackages, directDeps);
|
|
39454
39535
|
return {
|
|
39455
|
-
packages: diff2.changes.map(toPackageInput),
|
|
39536
|
+
packages: diff2.changes.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
39456
39537
|
method: "git-diff",
|
|
39457
39538
|
skipped: diff2.skipped
|
|
39458
39539
|
};
|
|
39459
39540
|
}
|
|
39460
39541
|
const pkgJsonPath = join5(cwd2, "package.json");
|
|
39461
39542
|
if (existsSync5(pkgJsonPath)) {
|
|
39462
|
-
const headPkgJson =
|
|
39543
|
+
const headPkgJson = readFileSafe(pkgJsonPath);
|
|
39463
39544
|
const basePkgJson = getGitBaseFile(cwd2, "package.json");
|
|
39464
39545
|
if (basePkgJson !== null) {
|
|
39465
39546
|
const diff2 = diffPackageJsons(basePkgJson, headPkgJson, config.maxPackages);
|
|
@@ -39471,7 +39552,7 @@ function discoverChanges(cwd2, config) {
|
|
|
39471
39552
|
};
|
|
39472
39553
|
});
|
|
39473
39554
|
return {
|
|
39474
|
-
packages: resolved.map(toPackageInput),
|
|
39555
|
+
packages: resolved.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
39475
39556
|
method: "fallback",
|
|
39476
39557
|
skipped: []
|
|
39477
39558
|
};
|
|
@@ -39480,6 +39561,8 @@ function discoverChanges(cwd2, config) {
|
|
|
39480
39561
|
const packages = [];
|
|
39481
39562
|
for (const [name, entry] of headParsed.packages) {
|
|
39482
39563
|
if (packages.length >= config.maxPackages) break;
|
|
39564
|
+
if (entry.optional && entry.hasPlatformRestriction) continue;
|
|
39565
|
+
if (name === SELF_PACKAGE) continue;
|
|
39483
39566
|
packages.push({
|
|
39484
39567
|
name,
|
|
39485
39568
|
version: entry.version,
|
|
@@ -39514,7 +39597,7 @@ function parseLockfileByType(content, type) {
|
|
|
39514
39597
|
}
|
|
39515
39598
|
function getDirectDeps(cwd2) {
|
|
39516
39599
|
try {
|
|
39517
|
-
const content =
|
|
39600
|
+
const content = readFileSafe(join5(cwd2, "package.json"));
|
|
39518
39601
|
const pkg = JSON.parse(content);
|
|
39519
39602
|
return /* @__PURE__ */ new Set([
|
|
39520
39603
|
...Object.keys(pkg.dependencies ?? {}),
|
|
@@ -39526,7 +39609,7 @@ function getDirectDeps(cwd2) {
|
|
|
39526
39609
|
}
|
|
39527
39610
|
function getGitBaseLockfile(cwd2) {
|
|
39528
39611
|
try {
|
|
39529
|
-
const mergeBase =
|
|
39612
|
+
const mergeBase = execFileSync2("git", ["merge-base", "HEAD", "main"], {
|
|
39530
39613
|
cwd: cwd2,
|
|
39531
39614
|
encoding: "utf-8",
|
|
39532
39615
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -39534,7 +39617,7 @@ function getGitBaseLockfile(cwd2) {
|
|
|
39534
39617
|
if (!mergeBase) return null;
|
|
39535
39618
|
for (const name of ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"]) {
|
|
39536
39619
|
try {
|
|
39537
|
-
return
|
|
39620
|
+
return execFileSync2("git", ["show", `${mergeBase}:${name}`], {
|
|
39538
39621
|
cwd: cwd2,
|
|
39539
39622
|
encoding: "utf-8",
|
|
39540
39623
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -39550,13 +39633,13 @@ function getGitBaseLockfile(cwd2) {
|
|
|
39550
39633
|
}
|
|
39551
39634
|
function getGitBaseFile(cwd2, filename) {
|
|
39552
39635
|
try {
|
|
39553
|
-
const mergeBase =
|
|
39636
|
+
const mergeBase = execFileSync2("git", ["merge-base", "HEAD", "main"], {
|
|
39554
39637
|
cwd: cwd2,
|
|
39555
39638
|
encoding: "utf-8",
|
|
39556
39639
|
stdio: ["pipe", "pipe", "pipe"]
|
|
39557
39640
|
}).trim();
|
|
39558
39641
|
if (!mergeBase) return null;
|
|
39559
|
-
return
|
|
39642
|
+
return execFileSync2("git", ["show", `${mergeBase}:${filename}`], {
|
|
39560
39643
|
cwd: cwd2,
|
|
39561
39644
|
encoding: "utf-8",
|
|
39562
39645
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -39574,7 +39657,7 @@ function toPackageInput(change) {
|
|
|
39574
39657
|
};
|
|
39575
39658
|
}
|
|
39576
39659
|
function parsePythonDepFile(projectDir, depFile) {
|
|
39577
|
-
const content =
|
|
39660
|
+
const content = readFileSafe(join5(projectDir, depFile));
|
|
39578
39661
|
if (depFile === "Pipfile.lock") {
|
|
39579
39662
|
try {
|
|
39580
39663
|
const parsed = JSON.parse(content);
|
|
@@ -39622,6 +39705,7 @@ function parsePythonDepFile(projectDir, depFile) {
|
|
|
39622
39705
|
}
|
|
39623
39706
|
return packages;
|
|
39624
39707
|
}
|
|
39708
|
+
var MAX_LOCKFILE_BYTES, SELF_PACKAGE;
|
|
39625
39709
|
var init_lockfile = __esm({
|
|
39626
39710
|
"src/lockfile.ts"() {
|
|
39627
39711
|
"use strict";
|
|
@@ -39630,6 +39714,208 @@ var init_lockfile = __esm({
|
|
|
39630
39714
|
init_parse_pnpm_lock();
|
|
39631
39715
|
init_diff2();
|
|
39632
39716
|
init_parse_package_json();
|
|
39717
|
+
MAX_LOCKFILE_BYTES = 50 * 1024 * 1024;
|
|
39718
|
+
SELF_PACKAGE = "@westbayberry/dg";
|
|
39719
|
+
}
|
|
39720
|
+
});
|
|
39721
|
+
|
|
39722
|
+
// src/pip-wrapper.ts
|
|
39723
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
39724
|
+
import { readFileSync as readFileSync7, existsSync as existsSync6 } from "node:fs";
|
|
39725
|
+
function parsePipArgs(args) {
|
|
39726
|
+
let dgForce = false;
|
|
39727
|
+
const filtered = [];
|
|
39728
|
+
for (const arg of args) {
|
|
39729
|
+
if (arg === "--dg-force") {
|
|
39730
|
+
dgForce = true;
|
|
39731
|
+
} else {
|
|
39732
|
+
filtered.push(arg);
|
|
39733
|
+
}
|
|
39734
|
+
}
|
|
39735
|
+
const command = filtered[0] ?? "";
|
|
39736
|
+
const shouldScan = INSTALL_COMMANDS2.has(command);
|
|
39737
|
+
const packages = [];
|
|
39738
|
+
let requirementsFile;
|
|
39739
|
+
if (shouldScan) {
|
|
39740
|
+
for (let i = 1; i < filtered.length; i++) {
|
|
39741
|
+
const arg = filtered[i];
|
|
39742
|
+
if (arg === "-r" || arg === "--requirement") {
|
|
39743
|
+
if (i + 1 < filtered.length) {
|
|
39744
|
+
requirementsFile = filtered[i + 1];
|
|
39745
|
+
i++;
|
|
39746
|
+
}
|
|
39747
|
+
continue;
|
|
39748
|
+
}
|
|
39749
|
+
if (arg.startsWith("-")) {
|
|
39750
|
+
if (pipFlagTakesValue(arg)) i++;
|
|
39751
|
+
continue;
|
|
39752
|
+
}
|
|
39753
|
+
packages.push(arg);
|
|
39754
|
+
}
|
|
39755
|
+
}
|
|
39756
|
+
return {
|
|
39757
|
+
command,
|
|
39758
|
+
packages,
|
|
39759
|
+
rawArgs: filtered,
|
|
39760
|
+
dgForce,
|
|
39761
|
+
shouldScan,
|
|
39762
|
+
requirementsFile
|
|
39763
|
+
};
|
|
39764
|
+
}
|
|
39765
|
+
function pipFlagTakesValue(flag) {
|
|
39766
|
+
const valueFlags = [
|
|
39767
|
+
"--index-url",
|
|
39768
|
+
"-i",
|
|
39769
|
+
"--extra-index-url",
|
|
39770
|
+
"--constraint",
|
|
39771
|
+
"-c",
|
|
39772
|
+
"--requirement",
|
|
39773
|
+
"-r",
|
|
39774
|
+
"--target",
|
|
39775
|
+
"-t",
|
|
39776
|
+
"--prefix",
|
|
39777
|
+
"--src",
|
|
39778
|
+
"--root",
|
|
39779
|
+
"--config-settings"
|
|
39780
|
+
];
|
|
39781
|
+
for (const f of valueFlags) {
|
|
39782
|
+
if (flag === f) return true;
|
|
39783
|
+
}
|
|
39784
|
+
return false;
|
|
39785
|
+
}
|
|
39786
|
+
function parseRequirementsFile(filePath) {
|
|
39787
|
+
if (!existsSync6(filePath)) return [];
|
|
39788
|
+
try {
|
|
39789
|
+
const content = readFileSync7(filePath, "utf-8");
|
|
39790
|
+
const specs = [];
|
|
39791
|
+
for (const rawLine of content.split("\n")) {
|
|
39792
|
+
let line = rawLine.trim();
|
|
39793
|
+
if (!line) continue;
|
|
39794
|
+
if (line.startsWith("#")) continue;
|
|
39795
|
+
if (line.startsWith("-e") || line.startsWith("--editable")) continue;
|
|
39796
|
+
if (/^(git|svn|hg|bzr)\+/.test(line)) continue;
|
|
39797
|
+
if (line.startsWith("-r") || line.startsWith("--requirement")) continue;
|
|
39798
|
+
if (line.startsWith("--")) continue;
|
|
39799
|
+
const commentIdx = line.indexOf(" #");
|
|
39800
|
+
if (commentIdx !== -1) line = line.slice(0, commentIdx).trim();
|
|
39801
|
+
const markerIdx = line.indexOf(";");
|
|
39802
|
+
if (markerIdx !== -1) line = line.slice(0, markerIdx).trim();
|
|
39803
|
+
if (line) specs.push(line);
|
|
39804
|
+
}
|
|
39805
|
+
return specs;
|
|
39806
|
+
} catch {
|
|
39807
|
+
return [];
|
|
39808
|
+
}
|
|
39809
|
+
}
|
|
39810
|
+
function parsePipSpec(spec) {
|
|
39811
|
+
const match = spec.match(/^([a-zA-Z0-9][-a-zA-Z0-9._]*)(([><=!~]=?).+)?$/);
|
|
39812
|
+
if (!match) return { name: spec, versionSpec: null };
|
|
39813
|
+
return {
|
|
39814
|
+
name: match[1],
|
|
39815
|
+
versionSpec: match[2] ?? null
|
|
39816
|
+
};
|
|
39817
|
+
}
|
|
39818
|
+
async function resolvePipVersion(spec) {
|
|
39819
|
+
const { name, versionSpec } = parsePipSpec(spec);
|
|
39820
|
+
if (versionSpec?.startsWith("==")) {
|
|
39821
|
+
const version = versionSpec.slice(2);
|
|
39822
|
+
try {
|
|
39823
|
+
const controller = new AbortController();
|
|
39824
|
+
const timer = setTimeout(() => controller.abort(), 15e3);
|
|
39825
|
+
const resp = await fetch(`https://pypi.org/pypi/${name}/${version}/json`, {
|
|
39826
|
+
signal: controller.signal
|
|
39827
|
+
});
|
|
39828
|
+
clearTimeout(timer);
|
|
39829
|
+
if (resp.ok) return version;
|
|
39830
|
+
return null;
|
|
39831
|
+
} catch {
|
|
39832
|
+
return null;
|
|
39833
|
+
}
|
|
39834
|
+
}
|
|
39835
|
+
try {
|
|
39836
|
+
const controller = new AbortController();
|
|
39837
|
+
const timer = setTimeout(() => controller.abort(), 15e3);
|
|
39838
|
+
const resp = await fetch(`https://pypi.org/pypi/${name}/json`, {
|
|
39839
|
+
signal: controller.signal
|
|
39840
|
+
});
|
|
39841
|
+
clearTimeout(timer);
|
|
39842
|
+
if (!resp.ok) return null;
|
|
39843
|
+
const data = await resp.json();
|
|
39844
|
+
return data.info?.version ?? null;
|
|
39845
|
+
} catch {
|
|
39846
|
+
return null;
|
|
39847
|
+
}
|
|
39848
|
+
}
|
|
39849
|
+
async function resolvePackages2(specs) {
|
|
39850
|
+
const results = await Promise.allSettled(
|
|
39851
|
+
specs.map(async (spec) => {
|
|
39852
|
+
const { name } = parsePipSpec(spec);
|
|
39853
|
+
const version = await resolvePipVersion(spec);
|
|
39854
|
+
return { spec, name, version };
|
|
39855
|
+
})
|
|
39856
|
+
);
|
|
39857
|
+
const resolved = [];
|
|
39858
|
+
const failed = [];
|
|
39859
|
+
for (const result of results) {
|
|
39860
|
+
if (result.status === "rejected") {
|
|
39861
|
+
failed.push("unknown");
|
|
39862
|
+
continue;
|
|
39863
|
+
}
|
|
39864
|
+
const { spec, name, version } = result.value;
|
|
39865
|
+
if (version) {
|
|
39866
|
+
resolved.push({
|
|
39867
|
+
name,
|
|
39868
|
+
version,
|
|
39869
|
+
previousVersion: null,
|
|
39870
|
+
isNew: true
|
|
39871
|
+
});
|
|
39872
|
+
} else {
|
|
39873
|
+
failed.push(spec);
|
|
39874
|
+
}
|
|
39875
|
+
}
|
|
39876
|
+
return { resolved, failed };
|
|
39877
|
+
}
|
|
39878
|
+
async function detectPipBinary() {
|
|
39879
|
+
if (cachedPipBinary) return cachedPipBinary;
|
|
39880
|
+
const candidates = ["python3 -m pip", "python -m pip", "pip3", "pip"];
|
|
39881
|
+
for (const cmd of candidates) {
|
|
39882
|
+
try {
|
|
39883
|
+
const parts = cmd.split(" ");
|
|
39884
|
+
const code = await new Promise((resolve) => {
|
|
39885
|
+
const child = spawn4(parts[0], [...parts.slice(1), "--version"], {
|
|
39886
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
39887
|
+
timeout: 5e3
|
|
39888
|
+
});
|
|
39889
|
+
child.on("close", (c) => resolve(c ?? 1));
|
|
39890
|
+
child.on("error", () => resolve(1));
|
|
39891
|
+
});
|
|
39892
|
+
if (code === 0) {
|
|
39893
|
+
cachedPipBinary = cmd;
|
|
39894
|
+
return cmd;
|
|
39895
|
+
}
|
|
39896
|
+
} catch {
|
|
39897
|
+
}
|
|
39898
|
+
}
|
|
39899
|
+
throw new Error("pip not found. Install pip or ensure 'python -m pip' is available.");
|
|
39900
|
+
}
|
|
39901
|
+
async function runPip(args) {
|
|
39902
|
+
const pipCmd = await detectPipBinary();
|
|
39903
|
+
const parts = pipCmd.split(" ");
|
|
39904
|
+
return new Promise((resolve) => {
|
|
39905
|
+
const child = spawn4(parts[0], [...parts.slice(1), ...args], {
|
|
39906
|
+
stdio: "inherit",
|
|
39907
|
+
shell: false
|
|
39908
|
+
});
|
|
39909
|
+
child.on("close", (code) => resolve(code ?? 1));
|
|
39910
|
+
child.on("error", () => resolve(1));
|
|
39911
|
+
});
|
|
39912
|
+
}
|
|
39913
|
+
var INSTALL_COMMANDS2, cachedPipBinary;
|
|
39914
|
+
var init_pip_wrapper = __esm({
|
|
39915
|
+
"src/pip-wrapper.ts"() {
|
|
39916
|
+
"use strict";
|
|
39917
|
+
INSTALL_COMMANDS2 = /* @__PURE__ */ new Set(["install", "update"]);
|
|
39918
|
+
cachedPipBinary = null;
|
|
39633
39919
|
}
|
|
39634
39920
|
});
|
|
39635
39921
|
|
|
@@ -39638,7 +39924,7 @@ var discover_exports = {};
|
|
|
39638
39924
|
__export(discover_exports, {
|
|
39639
39925
|
discoverProjects: () => discoverProjects
|
|
39640
39926
|
});
|
|
39641
|
-
import { existsSync as
|
|
39927
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8, readdirSync, lstatSync } from "node:fs";
|
|
39642
39928
|
import { join as join6, relative, basename } from "node:path";
|
|
39643
39929
|
function discoverProjects(root) {
|
|
39644
39930
|
const projects = [];
|
|
@@ -39649,7 +39935,7 @@ function walk(dir, root, depth, out) {
|
|
|
39649
39935
|
if (depth > MAX_DEPTH) return;
|
|
39650
39936
|
for (const lockfile of NPM_LOCKFILES) {
|
|
39651
39937
|
const lockPath = join6(dir, lockfile);
|
|
39652
|
-
if (
|
|
39938
|
+
if (existsSync7(lockPath)) {
|
|
39653
39939
|
const count = countNpmPackages(lockPath);
|
|
39654
39940
|
if (count > 0) {
|
|
39655
39941
|
out.push({
|
|
@@ -39665,7 +39951,7 @@ function walk(dir, root, depth, out) {
|
|
|
39665
39951
|
}
|
|
39666
39952
|
for (const depFile of PYTHON_DEPFILES) {
|
|
39667
39953
|
const depPath = join6(dir, depFile);
|
|
39668
|
-
if (
|
|
39954
|
+
if (existsSync7(depPath)) {
|
|
39669
39955
|
const count = countPythonPackages(depPath, depFile);
|
|
39670
39956
|
if (count > 0) {
|
|
39671
39957
|
out.push({
|
|
@@ -39689,7 +39975,8 @@ function walk(dir, root, depth, out) {
|
|
|
39689
39975
|
if (SKIP_DIRS.has(entry) || entry.startsWith(".")) continue;
|
|
39690
39976
|
const full = join6(dir, entry);
|
|
39691
39977
|
try {
|
|
39692
|
-
|
|
39978
|
+
const st = lstatSync(full);
|
|
39979
|
+
if (st.isDirectory() && !st.isSymbolicLink()) {
|
|
39693
39980
|
walk(full, root, depth + 1, out);
|
|
39694
39981
|
}
|
|
39695
39982
|
} catch {
|
|
@@ -39699,7 +39986,7 @@ function walk(dir, root, depth, out) {
|
|
|
39699
39986
|
function countNpmPackages(lockPath) {
|
|
39700
39987
|
try {
|
|
39701
39988
|
const name = basename(lockPath);
|
|
39702
|
-
const content =
|
|
39989
|
+
const content = readFileSync8(lockPath, "utf-8");
|
|
39703
39990
|
if (name === "yarn.lock") {
|
|
39704
39991
|
return (content.match(/^\S.*:$/gm) || []).length;
|
|
39705
39992
|
}
|
|
@@ -39720,7 +40007,7 @@ function countNpmPackages(lockPath) {
|
|
|
39720
40007
|
}
|
|
39721
40008
|
function countPythonPackages(depPath, depFile) {
|
|
39722
40009
|
try {
|
|
39723
|
-
const content =
|
|
40010
|
+
const content = readFileSync8(depPath, "utf-8");
|
|
39724
40011
|
if (depFile === "Pipfile.lock") {
|
|
39725
40012
|
const parsed = JSON.parse(content);
|
|
39726
40013
|
const defaultCount = Object.keys(parsed.default || {}).length;
|
|
@@ -39777,40 +40064,50 @@ __export(static_output_exports, {
|
|
|
39777
40064
|
renderResultStatic: () => renderResultStatic,
|
|
39778
40065
|
runStatic: () => runStatic,
|
|
39779
40066
|
runStaticLogin: () => runStaticLogin,
|
|
39780
|
-
runStaticNpm: () => runStaticNpm
|
|
40067
|
+
runStaticNpm: () => runStaticNpm,
|
|
40068
|
+
runStaticPip: () => runStaticPip
|
|
39781
40069
|
});
|
|
39782
40070
|
function printTrialBanner(result) {
|
|
39783
40071
|
if (result.trialScansRemaining === void 0) return;
|
|
39784
|
-
|
|
39785
|
-
|
|
39786
|
-
process.stderr.write(
|
|
39787
|
-
import_chalk4.default.dim(` ${remaining} free scan${remaining !== 1 ? "s" : ""} remaining. `) + import_chalk4.default.dim(`Run \`dg login\` for unlimited scans.
|
|
39788
|
-
`)
|
|
39789
|
-
);
|
|
39790
|
-
} else {
|
|
39791
|
-
process.stderr.write(
|
|
39792
|
-
import_chalk4.default.yellow(` No free scans remaining. `) + import_chalk4.default.yellow(`Run \`dg login\` to continue scanning.
|
|
40072
|
+
process.stderr.write(
|
|
40073
|
+
import_chalk4.default.dim(` Free tier \xB7 Run \`dg login\` for finding details and higher rate limits.
|
|
39793
40074
|
`)
|
|
39794
|
-
|
|
39795
|
-
}
|
|
40075
|
+
);
|
|
39796
40076
|
}
|
|
39797
|
-
function handleTrialExhausted2(error) {
|
|
40077
|
+
function handleTrialExhausted2(error, jsonMode = false) {
|
|
39798
40078
|
if (error instanceof TrialExhaustedError) {
|
|
39799
|
-
|
|
39800
|
-
|
|
39801
|
-
|
|
40079
|
+
let hasKey = false;
|
|
40080
|
+
try {
|
|
40081
|
+
const { getStoredApiKey: getStoredApiKey2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
40082
|
+
hasKey = !!getStoredApiKey2();
|
|
40083
|
+
} catch {
|
|
40084
|
+
}
|
|
40085
|
+
const message = hasKey ? "Your API key may be invalid or expired. Run `dg logout` then `dg login` to re-authenticate." : "Free trial scans used up. Run `dg login` to create a free account and continue scanning.";
|
|
40086
|
+
if (jsonMode) {
|
|
40087
|
+
process.stdout.write(JSON.stringify({
|
|
40088
|
+
error: true,
|
|
40089
|
+
code: "trial_exhausted",
|
|
40090
|
+
message,
|
|
40091
|
+
scansUsed: error.scansUsed,
|
|
40092
|
+
maxScans: error.maxScans
|
|
40093
|
+
}, null, 2) + "\n");
|
|
40094
|
+
} else {
|
|
40095
|
+
if (hasKey) {
|
|
40096
|
+
process.stderr.write(import_chalk4.default.yellow(`
|
|
40097
|
+
${message}
|
|
40098
|
+
|
|
40099
|
+
`));
|
|
40100
|
+
} else {
|
|
40101
|
+
process.stderr.write(
|
|
40102
|
+
import_chalk4.default.yellow("\n Free trial scans used up.\n") + import_chalk4.default.white(" Run `dg login` to create a free account and continue scanning.\n\n")
|
|
40103
|
+
);
|
|
40104
|
+
}
|
|
40105
|
+
}
|
|
39802
40106
|
process.exit(1);
|
|
39803
40107
|
return true;
|
|
39804
40108
|
}
|
|
39805
40109
|
return false;
|
|
39806
40110
|
}
|
|
39807
|
-
function severityColor(sev) {
|
|
39808
|
-
if (sev >= 5) return (s) => import_chalk4.default.bold.red(s);
|
|
39809
|
-
if (sev >= 4) return import_chalk4.default.red;
|
|
39810
|
-
if (sev >= 3) return import_chalk4.default.yellow;
|
|
39811
|
-
if (sev >= 2) return import_chalk4.default.cyan;
|
|
39812
|
-
return import_chalk4.default.dim;
|
|
39813
|
-
}
|
|
39814
40111
|
function actionColor(action) {
|
|
39815
40112
|
if (action === "block") return import_chalk4.default.red;
|
|
39816
40113
|
if (action === "warn") return import_chalk4.default.yellow;
|
|
@@ -39833,9 +40130,9 @@ function groupPackages(packages) {
|
|
|
39833
40130
|
}
|
|
39834
40131
|
return [...map.values()].map((pkgs) => ({ packages: pkgs, key: pkgs[0].name })).sort((a, b) => b.packages[0].score - a.packages[0].score);
|
|
39835
40132
|
}
|
|
39836
|
-
function actionBadge(score
|
|
39837
|
-
if (score >=
|
|
39838
|
-
if (score >=
|
|
40133
|
+
function actionBadge(score) {
|
|
40134
|
+
if (score >= 70) return { label: "BLOCK", color: import_chalk4.default.red };
|
|
40135
|
+
if (score >= 60) return { label: "WARN", color: import_chalk4.default.yellow };
|
|
39839
40136
|
return { label: "pass", color: import_chalk4.default.green };
|
|
39840
40137
|
}
|
|
39841
40138
|
function renderResultStatic(result, config) {
|
|
@@ -39865,6 +40162,15 @@ function renderResultStatic(result, config) {
|
|
|
39865
40162
|
` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk4.default.dim("\u2502")} ${import_chalk4.default.green("all clean")}`
|
|
39866
40163
|
);
|
|
39867
40164
|
}
|
|
40165
|
+
const licensedPkgs = result.packages.filter((p) => p.license);
|
|
40166
|
+
const licenseIssues = licensedPkgs.filter(
|
|
40167
|
+
(p) => p.license && p.license.riskCategory !== "permissive"
|
|
40168
|
+
);
|
|
40169
|
+
if (licenseIssues.length > 0) {
|
|
40170
|
+
lines.push(
|
|
40171
|
+
` ${import_chalk4.default.dim("Licenses:")} ${import_chalk4.default.yellow(`${licenseIssues.length} need review`)} \u2502 ${import_chalk4.default.green(`${licensedPkgs.length - licenseIssues.length} permissive`)}`
|
|
40172
|
+
);
|
|
40173
|
+
}
|
|
39868
40174
|
lines.push("");
|
|
39869
40175
|
if (total === 0) {
|
|
39870
40176
|
lines.push(" No packages to scan.");
|
|
@@ -39877,10 +40183,13 @@ function renderResultStatic(result, config) {
|
|
|
39877
40183
|
lines.push(` ${import_chalk4.default.dim("\u2500".repeat(60))}`);
|
|
39878
40184
|
for (const group of groups) {
|
|
39879
40185
|
const rep = group.packages[0];
|
|
39880
|
-
const { label, color } = actionBadge(rep.score
|
|
40186
|
+
const { label, color } = actionBadge(rep.score);
|
|
39881
40187
|
const names = group.packages.length === 1 ? rep.name : group.packages.length <= 3 ? group.packages.map((p) => p.name).join(", ") : `${group.packages[0].name} + ${group.packages.length - 1} similar`;
|
|
40188
|
+
const lcInfo = rep.license;
|
|
40189
|
+
const lcStr = lcInfo ? truncate(lcInfo.spdx ?? lcInfo.raw ?? "", 14) : "";
|
|
40190
|
+
const lcColor = !lcInfo ? import_chalk4.default.dim : lcInfo.riskCategory === "permissive" ? import_chalk4.default.green : lcInfo.riskCategory === "no-license" || lcInfo.riskCategory === "unlicensed" || lcInfo.riskCategory === "network-copyleft" ? import_chalk4.default.red : import_chalk4.default.yellow;
|
|
39882
40191
|
lines.push(
|
|
39883
|
-
` ${color(pad(label, 7))}${import_chalk4.default.bold(pad(truncate(names,
|
|
40192
|
+
` ${color(pad(label, 7))}${import_chalk4.default.bold(pad(truncate(names, 36), 38))}${lcColor(pad(lcStr, 16))}${import_chalk4.default.dim(`score ${rep.score}`)}`
|
|
39884
40193
|
);
|
|
39885
40194
|
}
|
|
39886
40195
|
lines.push("");
|
|
@@ -39891,46 +40200,6 @@ function renderResultStatic(result, config) {
|
|
|
39891
40200
|
);
|
|
39892
40201
|
lines.push("");
|
|
39893
40202
|
}
|
|
39894
|
-
for (const group of groups) {
|
|
39895
|
-
const rep = group.packages[0];
|
|
39896
|
-
const names = group.packages.length === 1 ? `${rep.name}@${rep.version}` : group.packages.length <= 3 ? group.packages.map((p) => `${p.name}@${p.version}`).join(", ") : `${rep.name}@${rep.version} + ${group.packages.length - 1} identical packages`;
|
|
39897
|
-
lines.push(
|
|
39898
|
-
` ${import_chalk4.default.dim("\u2500\u2500")} ${import_chalk4.default.bold(`${names} (score: ${rep.score})`)}`
|
|
39899
|
-
);
|
|
39900
|
-
if (group.packages.length > 3) {
|
|
39901
|
-
lines.push(
|
|
39902
|
-
` ${import_chalk4.default.dim("Affects: " + group.packages.map((p) => p.name).join(", "))}`
|
|
39903
|
-
);
|
|
39904
|
-
}
|
|
39905
|
-
lines.push("");
|
|
39906
|
-
const visibleFindings = rep.findings.filter((f) => f.severity > 1 || f.critical).sort((a, b) => b.severity - a.severity);
|
|
39907
|
-
for (const finding of visibleFindings) {
|
|
39908
|
-
const sevLabel = SEVERITY_LABELS[finding.severity] ?? "INFO";
|
|
39909
|
-
const colorFn = severityColor(finding.severity);
|
|
39910
|
-
lines.push(
|
|
39911
|
-
` ${colorFn(pad(sevLabel, 10))}${finding.id} \u2014 ${finding.title}`
|
|
39912
|
-
);
|
|
39913
|
-
const evidenceLimit = 3;
|
|
39914
|
-
for (let i = 0; i < Math.min(finding.evidence.length, evidenceLimit); i++) {
|
|
39915
|
-
lines.push(
|
|
39916
|
-
` ${" ".repeat(10)}${import_chalk4.default.dim(truncate(finding.evidence[i], 76))}`
|
|
39917
|
-
);
|
|
39918
|
-
}
|
|
39919
|
-
if (finding.evidence.length > evidenceLimit) {
|
|
39920
|
-
lines.push(
|
|
39921
|
-
` ${" ".repeat(10)}${import_chalk4.default.dim(`... and ${finding.evidence.length - evidenceLimit} more`)}`
|
|
39922
|
-
);
|
|
39923
|
-
}
|
|
39924
|
-
lines.push("");
|
|
39925
|
-
}
|
|
39926
|
-
const safeVersion = result.safeVersions[rep.name];
|
|
39927
|
-
if (safeVersion) {
|
|
39928
|
-
lines.push(
|
|
39929
|
-
` ${import_chalk4.default.green(`Safe version: ${rep.name}@${safeVersion}`)}`
|
|
39930
|
-
);
|
|
39931
|
-
lines.push("");
|
|
39932
|
-
}
|
|
39933
|
-
}
|
|
39934
40203
|
if (result.durationMs) {
|
|
39935
40204
|
lines.push(
|
|
39936
40205
|
` ${import_chalk4.default.dim(`Completed in ${(result.durationMs / 1e3).toFixed(1)}s`)}`
|
|
@@ -39952,7 +40221,7 @@ async function runStatic(config) {
|
|
|
39952
40221
|
process.exit(0);
|
|
39953
40222
|
}
|
|
39954
40223
|
dbg(
|
|
39955
|
-
`mode=${config.mode}
|
|
40224
|
+
`mode=${config.mode} max=${config.maxPackages}`
|
|
39956
40225
|
);
|
|
39957
40226
|
dbg(`api=${config.apiUrl}`);
|
|
39958
40227
|
process.stderr.write(import_chalk4.default.dim(" Discovering package changes...\n"));
|
|
@@ -39979,15 +40248,7 @@ async function runStatic(config) {
|
|
|
39979
40248
|
}
|
|
39980
40249
|
process.exit(0);
|
|
39981
40250
|
}
|
|
39982
|
-
const packages = discovery.packages
|
|
39983
|
-
(p) => !config.allowlist.includes(p.name)
|
|
39984
|
-
);
|
|
39985
|
-
if (packages.length === 0) {
|
|
39986
|
-
process.stderr.write(
|
|
39987
|
-
import_chalk4.default.dim(" All changed packages are allowlisted.\n")
|
|
39988
|
-
);
|
|
39989
|
-
process.exit(0);
|
|
39990
|
-
}
|
|
40251
|
+
const packages = discovery.packages;
|
|
39991
40252
|
process.stderr.write(
|
|
39992
40253
|
import_chalk4.default.dim(
|
|
39993
40254
|
` Scanning ${packages.length} package${packages.length !== 1 ? "s" : ""} (${discovery.method})...
|
|
@@ -40016,7 +40277,7 @@ async function runStatic(config) {
|
|
|
40016
40277
|
`API responded in ${Date.now() - startMs}ms, action=${result.action}, score=${result.score}`
|
|
40017
40278
|
);
|
|
40018
40279
|
} catch (error) {
|
|
40019
|
-
if (handleTrialExhausted2(error)) return;
|
|
40280
|
+
if (handleTrialExhausted2(error, config.json)) return;
|
|
40020
40281
|
throw error;
|
|
40021
40282
|
}
|
|
40022
40283
|
const output = renderResultStatic(result, config);
|
|
@@ -40088,24 +40349,16 @@ async function runStaticNpm(npmArgs, config) {
|
|
|
40088
40349
|
return scanAndInstallStatic(resolved, parsed, config);
|
|
40089
40350
|
}
|
|
40090
40351
|
async function scanAndInstallStatic(resolved, parsed, config) {
|
|
40091
|
-
const toScan = resolved.filter((p) => !config.allowlist.includes(p.name));
|
|
40092
|
-
if (toScan.length === 0) {
|
|
40093
|
-
process.stderr.write(
|
|
40094
|
-
import_chalk4.default.dim(" All packages are allowlisted. Passing through to npm.\n")
|
|
40095
|
-
);
|
|
40096
|
-
const code = await runNpm(parsed.rawArgs);
|
|
40097
|
-
process.exit(code);
|
|
40098
|
-
}
|
|
40099
40352
|
process.stderr.write(
|
|
40100
40353
|
import_chalk4.default.dim(
|
|
40101
|
-
` Scanning ${
|
|
40354
|
+
` Scanning ${resolved.length} package${resolved.length !== 1 ? "s" : ""}...
|
|
40102
40355
|
`
|
|
40103
40356
|
)
|
|
40104
40357
|
);
|
|
40105
40358
|
let result;
|
|
40106
40359
|
try {
|
|
40107
40360
|
const startMs = Date.now();
|
|
40108
|
-
result = await callAnalyzeAPI(
|
|
40361
|
+
result = await callAnalyzeAPI(resolved, config);
|
|
40109
40362
|
const elapsed = Date.now() - startMs;
|
|
40110
40363
|
if (config.debug) {
|
|
40111
40364
|
process.stderr.write(
|
|
@@ -40116,7 +40369,7 @@ async function scanAndInstallStatic(resolved, parsed, config) {
|
|
|
40116
40369
|
);
|
|
40117
40370
|
}
|
|
40118
40371
|
} catch (error) {
|
|
40119
|
-
if (handleTrialExhausted2(error)) return;
|
|
40372
|
+
if (handleTrialExhausted2(error, config.json)) return;
|
|
40120
40373
|
const msg = error instanceof Error ? error.message : String(error);
|
|
40121
40374
|
process.stderr.write(
|
|
40122
40375
|
import_chalk4.default.yellow(
|
|
@@ -40131,7 +40384,7 @@ async function scanAndInstallStatic(resolved, parsed, config) {
|
|
|
40131
40384
|
if (result.action === "pass") {
|
|
40132
40385
|
process.stderr.write(
|
|
40133
40386
|
import_chalk4.default.green(
|
|
40134
|
-
` ${import_chalk4.default.bold("\u2713")} ${
|
|
40387
|
+
` ${import_chalk4.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
|
|
40135
40388
|
`
|
|
40136
40389
|
)
|
|
40137
40390
|
);
|
|
@@ -40171,6 +40424,102 @@ async function scanAndInstallStatic(resolved, parsed, config) {
|
|
|
40171
40424
|
process.exit(2);
|
|
40172
40425
|
}
|
|
40173
40426
|
}
|
|
40427
|
+
async function runStaticPip(pipArgs, config) {
|
|
40428
|
+
const parsed = parsePipArgs(pipArgs);
|
|
40429
|
+
if (!parsed.shouldScan) {
|
|
40430
|
+
const code = await runPip(parsed.rawArgs);
|
|
40431
|
+
process.exit(code);
|
|
40432
|
+
}
|
|
40433
|
+
let specs = parsed.packages;
|
|
40434
|
+
if (specs.length === 0 && parsed.requirementsFile) {
|
|
40435
|
+
specs = parseRequirementsFile(parsed.requirementsFile);
|
|
40436
|
+
}
|
|
40437
|
+
if (specs.length === 0) {
|
|
40438
|
+
process.stderr.write(
|
|
40439
|
+
import_chalk4.default.dim(" Dependency Guardian: no packages to scan, passing through to pip.\n")
|
|
40440
|
+
);
|
|
40441
|
+
const code = await runPip(parsed.rawArgs);
|
|
40442
|
+
process.exit(code);
|
|
40443
|
+
}
|
|
40444
|
+
process.stderr.write(
|
|
40445
|
+
import_chalk4.default.dim(
|
|
40446
|
+
` Resolving ${specs.length} package${specs.length !== 1 ? "s" : ""} from PyPI...
|
|
40447
|
+
`
|
|
40448
|
+
)
|
|
40449
|
+
);
|
|
40450
|
+
const { resolved, failed } = await resolvePackages2(specs);
|
|
40451
|
+
if (failed.length > 0) {
|
|
40452
|
+
process.stderr.write(
|
|
40453
|
+
import_chalk4.default.yellow(` Warning: Could not resolve versions for: ${failed.join(", ")}
|
|
40454
|
+
`)
|
|
40455
|
+
);
|
|
40456
|
+
}
|
|
40457
|
+
if (resolved.length === 0) {
|
|
40458
|
+
process.stderr.write(
|
|
40459
|
+
import_chalk4.default.dim(" No packages to scan. Passing through to pip.\n")
|
|
40460
|
+
);
|
|
40461
|
+
const code = await runPip(parsed.rawArgs);
|
|
40462
|
+
process.exit(code);
|
|
40463
|
+
}
|
|
40464
|
+
process.stderr.write(
|
|
40465
|
+
import_chalk4.default.dim(
|
|
40466
|
+
` Scanning ${resolved.length} Python package${resolved.length !== 1 ? "s" : ""}...
|
|
40467
|
+
`
|
|
40468
|
+
)
|
|
40469
|
+
);
|
|
40470
|
+
let result;
|
|
40471
|
+
try {
|
|
40472
|
+
result = await callPyPIAnalyzeAPI(resolved, config);
|
|
40473
|
+
} catch (error) {
|
|
40474
|
+
if (handleTrialExhausted2(error, config.json)) return;
|
|
40475
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
40476
|
+
process.stderr.write(
|
|
40477
|
+
import_chalk4.default.yellow(` Warning: Scan failed (${msg}). Proceeding with install.
|
|
40478
|
+
`)
|
|
40479
|
+
);
|
|
40480
|
+
const code = await runPip(parsed.rawArgs);
|
|
40481
|
+
process.exit(code);
|
|
40482
|
+
return;
|
|
40483
|
+
}
|
|
40484
|
+
if (result.action === "pass") {
|
|
40485
|
+
process.stderr.write(
|
|
40486
|
+
import_chalk4.default.green(
|
|
40487
|
+
` ${import_chalk4.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
|
|
40488
|
+
`
|
|
40489
|
+
)
|
|
40490
|
+
);
|
|
40491
|
+
printTrialBanner(result);
|
|
40492
|
+
process.stderr.write("\n");
|
|
40493
|
+
const code = await runPip(parsed.rawArgs);
|
|
40494
|
+
process.exit(code);
|
|
40495
|
+
}
|
|
40496
|
+
const output = renderResultStatic(result, config);
|
|
40497
|
+
process.stdout.write(output + "\n");
|
|
40498
|
+
printTrialBanner(result);
|
|
40499
|
+
if (result.action === "warn") {
|
|
40500
|
+
process.stderr.write(
|
|
40501
|
+
import_chalk4.default.yellow(" Warnings detected. Proceeding with install.\n\n")
|
|
40502
|
+
);
|
|
40503
|
+
const code = await runPip(parsed.rawArgs);
|
|
40504
|
+
process.exit(code);
|
|
40505
|
+
}
|
|
40506
|
+
if (result.action === "block") {
|
|
40507
|
+
if (parsed.dgForce) {
|
|
40508
|
+
process.stderr.write(
|
|
40509
|
+
import_chalk4.default.yellow(import_chalk4.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n"))
|
|
40510
|
+
);
|
|
40511
|
+
const code = await runPip(parsed.rawArgs);
|
|
40512
|
+
process.exit(code);
|
|
40513
|
+
}
|
|
40514
|
+
process.stderr.write(
|
|
40515
|
+
import_chalk4.default.red(import_chalk4.default.bold(" BLOCKED: ")) + import_chalk4.default.red("High-risk packages detected. Install aborted.\n")
|
|
40516
|
+
);
|
|
40517
|
+
process.stderr.write(
|
|
40518
|
+
import_chalk4.default.dim(" Use --dg-force to bypass this check.\n\n")
|
|
40519
|
+
);
|
|
40520
|
+
process.exit(2);
|
|
40521
|
+
}
|
|
40522
|
+
}
|
|
40174
40523
|
async function runStaticLogin() {
|
|
40175
40524
|
const {
|
|
40176
40525
|
createAuthSession: createAuthSession2,
|
|
@@ -40248,7 +40597,7 @@ async function runStaticLogin() {
|
|
|
40248
40597
|
);
|
|
40249
40598
|
process.exit(1);
|
|
40250
40599
|
}
|
|
40251
|
-
var import_chalk4
|
|
40600
|
+
var import_chalk4;
|
|
40252
40601
|
var init_static_output = __esm({
|
|
40253
40602
|
"src/static-output.ts"() {
|
|
40254
40603
|
"use strict";
|
|
@@ -40256,13 +40605,7 @@ var init_static_output = __esm({
|
|
|
40256
40605
|
init_api();
|
|
40257
40606
|
init_lockfile();
|
|
40258
40607
|
init_npm_wrapper();
|
|
40259
|
-
|
|
40260
|
-
5: "CRITICAL",
|
|
40261
|
-
4: "HIGH",
|
|
40262
|
-
3: "MEDIUM",
|
|
40263
|
-
2: "LOW",
|
|
40264
|
-
1: "INFO"
|
|
40265
|
-
};
|
|
40608
|
+
init_pip_wrapper();
|
|
40266
40609
|
}
|
|
40267
40610
|
});
|
|
40268
40611
|
|
|
@@ -40271,10 +40614,10 @@ var hook_exports = {};
|
|
|
40271
40614
|
__export(hook_exports, {
|
|
40272
40615
|
handleHookCommand: () => handleHookCommand
|
|
40273
40616
|
});
|
|
40274
|
-
import { execFileSync as
|
|
40617
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
40275
40618
|
import {
|
|
40276
|
-
existsSync as
|
|
40277
|
-
readFileSync as
|
|
40619
|
+
existsSync as existsSync8,
|
|
40620
|
+
readFileSync as readFileSync9,
|
|
40278
40621
|
writeFileSync as writeFileSync3,
|
|
40279
40622
|
mkdirSync,
|
|
40280
40623
|
chmodSync as chmodSync2,
|
|
@@ -40283,7 +40626,7 @@ import {
|
|
|
40283
40626
|
import { join as join7 } from "node:path";
|
|
40284
40627
|
function findGitDir() {
|
|
40285
40628
|
try {
|
|
40286
|
-
return
|
|
40629
|
+
return execFileSync3("git", ["rev-parse", "--git-dir"], {
|
|
40287
40630
|
encoding: "utf-8",
|
|
40288
40631
|
stdio: ["pipe", "pipe", "pipe"]
|
|
40289
40632
|
}).trim();
|
|
@@ -40296,8 +40639,8 @@ function installHook() {
|
|
|
40296
40639
|
const hooksDir = join7(gitDir, "hooks");
|
|
40297
40640
|
const hookPath = join7(hooksDir, "pre-commit");
|
|
40298
40641
|
mkdirSync(hooksDir, { recursive: true });
|
|
40299
|
-
if (
|
|
40300
|
-
const existing =
|
|
40642
|
+
if (existsSync8(hookPath)) {
|
|
40643
|
+
const existing = readFileSync9(hookPath, "utf-8");
|
|
40301
40644
|
if (existing.includes(HOOK_MARKER)) {
|
|
40302
40645
|
process.stderr.write(" Hook already installed.\n");
|
|
40303
40646
|
return;
|
|
@@ -40318,11 +40661,11 @@ function installHook() {
|
|
|
40318
40661
|
function uninstallHook() {
|
|
40319
40662
|
const gitDir = findGitDir();
|
|
40320
40663
|
const hookPath = join7(gitDir, "hooks", "pre-commit");
|
|
40321
|
-
if (!
|
|
40664
|
+
if (!existsSync8(hookPath)) {
|
|
40322
40665
|
process.stderr.write(" No hook to remove.\n");
|
|
40323
40666
|
return;
|
|
40324
40667
|
}
|
|
40325
|
-
const content =
|
|
40668
|
+
const content = readFileSync9(hookPath, "utf-8");
|
|
40326
40669
|
if (!content.includes(HOOK_MARKER)) {
|
|
40327
40670
|
process.stderr.write(
|
|
40328
40671
|
" No Dependency Guardian hook found in pre-commit.\n"
|
|
@@ -40517,19 +40860,10 @@ function useNpmWrapper(npmArgs, config) {
|
|
|
40517
40860
|
dispatch({ type: "DONE", exitCode: code });
|
|
40518
40861
|
return;
|
|
40519
40862
|
}
|
|
40520
|
-
|
|
40521
|
-
|
|
40522
|
-
);
|
|
40523
|
-
if (toScan.length === 0) {
|
|
40524
|
-
dispatch({ type: "INSTALLING" });
|
|
40525
|
-
const code = await runNpm(parsed.rawArgs);
|
|
40526
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
40527
|
-
return;
|
|
40528
|
-
}
|
|
40529
|
-
dispatch({ type: "SCANNING", count: toScan.length });
|
|
40530
|
-
const result = await callAnalyzeAPI(toScan, config);
|
|
40863
|
+
dispatch({ type: "SCANNING", count: resolved.length });
|
|
40864
|
+
const result = await callAnalyzeAPI(resolved, config);
|
|
40531
40865
|
if (result.action === "pass") {
|
|
40532
|
-
dispatch({ type: "PASS", count:
|
|
40866
|
+
dispatch({ type: "PASS", count: resolved.length });
|
|
40533
40867
|
dispatch({ type: "INSTALLING" });
|
|
40534
40868
|
const code = await runNpm(parsed.rawArgs);
|
|
40535
40869
|
dispatch({ type: "DONE", exitCode: code });
|
|
@@ -40728,6 +41062,7 @@ var init_ScoreHeader = __esm({
|
|
|
40728
41062
|
severityCounts
|
|
40729
41063
|
}) => {
|
|
40730
41064
|
const logo = renderLogo(action);
|
|
41065
|
+
const showLogo = (process.stdout.columns ?? 80) >= 60;
|
|
40731
41066
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
40732
41067
|
Box_default,
|
|
40733
41068
|
{
|
|
@@ -40767,7 +41102,7 @@ var init_ScoreHeader = __esm({
|
|
|
40767
41102
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: `\x1B]8;;https://westbayberry.com\x07westbayberry.com\x1B]8;;\x07` })
|
|
40768
41103
|
] })
|
|
40769
41104
|
] }),
|
|
40770
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "column", marginLeft: 2, children: logo.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: line }, i)) })
|
|
41105
|
+
showLogo && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "column", marginLeft: 2, children: logo.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: line }, i)) })
|
|
40771
41106
|
] })
|
|
40772
41107
|
}
|
|
40773
41108
|
);
|
|
@@ -40801,16 +41136,16 @@ function groupPackages2(packages) {
|
|
|
40801
41136
|
}
|
|
40802
41137
|
return [...map.values()].map((pkgs) => ({ packages: pkgs, key: pkgs[0].name })).sort((a, b) => b.packages[0].score - a.packages[0].score);
|
|
40803
41138
|
}
|
|
40804
|
-
function
|
|
41139
|
+
function severityColor(sev) {
|
|
40805
41140
|
if (sev >= 5) return (s) => import_chalk6.default.bold.red(s);
|
|
40806
41141
|
if (sev >= 4) return import_chalk6.default.magenta;
|
|
40807
41142
|
if (sev >= 3) return import_chalk6.default.yellow;
|
|
40808
41143
|
if (sev >= 2) return import_chalk6.default.dim;
|
|
40809
41144
|
return import_chalk6.default.dim;
|
|
40810
41145
|
}
|
|
40811
|
-
function actionBadge2(score
|
|
40812
|
-
if (score >=
|
|
40813
|
-
if (score >=
|
|
41146
|
+
function actionBadge2(score) {
|
|
41147
|
+
if (score >= 70) return { label: "BLOCK", color: import_chalk6.default.red };
|
|
41148
|
+
if (score >= 60) return { label: "WARN", color: import_chalk6.default.yellow };
|
|
40814
41149
|
return { label: "PASS", color: import_chalk6.default.green };
|
|
40815
41150
|
}
|
|
40816
41151
|
function truncate2(s, max) {
|
|
@@ -40819,7 +41154,7 @@ function truncate2(s, max) {
|
|
|
40819
41154
|
function pad2(s, len) {
|
|
40820
41155
|
return s + " ".repeat(Math.max(0, len - s.length));
|
|
40821
41156
|
}
|
|
40822
|
-
var import_chalk6, import_jsx_runtime5,
|
|
41157
|
+
var import_chalk6, import_jsx_runtime5, SEVERITY_LABELS, EVIDENCE_LIMIT, ResultsView;
|
|
40823
41158
|
var init_ResultsView = __esm({
|
|
40824
41159
|
async "src/ui/components/ResultsView.tsx"() {
|
|
40825
41160
|
"use strict";
|
|
@@ -40828,7 +41163,7 @@ var init_ResultsView = __esm({
|
|
|
40828
41163
|
await init_ScoreHeader();
|
|
40829
41164
|
await init_DurationLine();
|
|
40830
41165
|
import_jsx_runtime5 = __toESM(require_jsx_runtime());
|
|
40831
|
-
|
|
41166
|
+
SEVERITY_LABELS = {
|
|
40832
41167
|
5: "CRITICAL",
|
|
40833
41168
|
4: "HIGH",
|
|
40834
41169
|
3: "MEDIUM",
|
|
@@ -40867,7 +41202,7 @@ var init_ResultsView = __esm({
|
|
|
40867
41202
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "\u2500".repeat(60) }),
|
|
40868
41203
|
groups.map((group) => {
|
|
40869
41204
|
const rep = group.packages[0];
|
|
40870
|
-
const { label, color } = actionBadge2(rep.score
|
|
41205
|
+
const { label, color } = actionBadge2(rep.score);
|
|
40871
41206
|
const names = group.packages.length === 1 ? rep.name : group.packages.length <= 3 ? group.packages.map((p) => p.name).join(", ") : `${group.packages[0].name} + ${group.packages.length - 1} similar`;
|
|
40872
41207
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
|
|
40873
41208
|
" ",
|
|
@@ -40903,8 +41238,8 @@ var init_ResultsView = __esm({
|
|
|
40903
41238
|
] }),
|
|
40904
41239
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
40905
41240
|
visibleFindings.map((finding, idx) => {
|
|
40906
|
-
const sevLabel =
|
|
40907
|
-
const colorFn =
|
|
41241
|
+
const sevLabel = SEVERITY_LABELS[finding.severity] ?? "INFO";
|
|
41242
|
+
const colorFn = severityColor(finding.severity);
|
|
40908
41243
|
const evidenceSlice = finding.evidence.slice(0, EVIDENCE_LIMIT);
|
|
40909
41244
|
const overflow = finding.evidence.length - EVIDENCE_LIMIT;
|
|
40910
41245
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
@@ -41002,6 +41337,7 @@ var init_ErrorView = __esm({
|
|
|
41002
41337
|
"use strict";
|
|
41003
41338
|
await init_build2();
|
|
41004
41339
|
import_chalk8 = __toESM(require_source());
|
|
41340
|
+
init_sanitize();
|
|
41005
41341
|
import_jsx_runtime7 = __toESM(require_jsx_runtime());
|
|
41006
41342
|
ErrorView = ({ error }) => {
|
|
41007
41343
|
const hint = getHint(error);
|
|
@@ -41015,7 +41351,7 @@ var init_ErrorView = __esm({
|
|
|
41015
41351
|
paddingRight: 1,
|
|
41016
41352
|
children: [
|
|
41017
41353
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: import_chalk8.default.red.bold("\u2718 Error") }),
|
|
41018
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: error.message }),
|
|
41354
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: sanitize(error.message) }),
|
|
41019
41355
|
hint && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
|
|
41020
41356
|
import_chalk8.default.yellow("\u2192"),
|
|
41021
41357
|
" ",
|
|
@@ -41161,22 +41497,349 @@ var init_NpmWrapperApp = __esm({
|
|
|
41161
41497
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorView, { error: new Error(state.message) });
|
|
41162
41498
|
case "passthrough":
|
|
41163
41499
|
return null;
|
|
41164
|
-
case "trial_exhausted":
|
|
41165
|
-
|
|
41500
|
+
case "trial_exhausted": {
|
|
41501
|
+
let hasKey = false;
|
|
41502
|
+
try {
|
|
41503
|
+
const { getStoredApiKey: getStoredApiKey2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
41504
|
+
hasKey = !!getStoredApiKey2();
|
|
41505
|
+
} catch {
|
|
41506
|
+
}
|
|
41507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, children: hasKey ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
41508
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "yellow", bold: true, children: "Your API key may be invalid or expired." }),
|
|
41509
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
|
|
41510
|
+
"Run ",
|
|
41511
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "cyan", bold: true, children: "dg logout" }),
|
|
41512
|
+
" then ",
|
|
41513
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
41514
|
+
" to re-authenticate."
|
|
41515
|
+
] })
|
|
41516
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
41166
41517
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "yellow", bold: true, children: "Free trial scans used up." }),
|
|
41167
41518
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
|
|
41168
41519
|
"Run ",
|
|
41169
41520
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
41170
41521
|
" to create a free account and continue scanning."
|
|
41171
41522
|
] })
|
|
41523
|
+
] }) });
|
|
41524
|
+
}
|
|
41525
|
+
}
|
|
41526
|
+
};
|
|
41527
|
+
}
|
|
41528
|
+
});
|
|
41529
|
+
|
|
41530
|
+
// src/ui/hooks/usePipWrapper.ts
|
|
41531
|
+
function reducer3(_state, action) {
|
|
41532
|
+
switch (action.type) {
|
|
41533
|
+
case "PASSTHROUGH":
|
|
41534
|
+
return { phase: "passthrough" };
|
|
41535
|
+
case "RESOLVING":
|
|
41536
|
+
return { phase: "resolving", count: action.count };
|
|
41537
|
+
case "SCANNING":
|
|
41538
|
+
return { phase: "scanning", count: action.count };
|
|
41539
|
+
case "PASS":
|
|
41540
|
+
return { phase: "pass", count: action.count };
|
|
41541
|
+
case "WARN":
|
|
41542
|
+
return { phase: "warn", result: action.result };
|
|
41543
|
+
case "BLOCKED":
|
|
41544
|
+
return { phase: "blocked", result: action.result, dgForce: action.dgForce };
|
|
41545
|
+
case "INSTALLING":
|
|
41546
|
+
return { phase: "installing" };
|
|
41547
|
+
case "DONE":
|
|
41548
|
+
return { phase: "done", exitCode: action.exitCode };
|
|
41549
|
+
case "ERROR":
|
|
41550
|
+
return { phase: "error", message: action.message, proceed: action.proceed };
|
|
41551
|
+
case "TRIAL_EXHAUSTED":
|
|
41552
|
+
return { phase: "trial_exhausted" };
|
|
41553
|
+
}
|
|
41554
|
+
}
|
|
41555
|
+
function usePipWrapper(pipArgs, config) {
|
|
41556
|
+
const [state, dispatch] = (0, import_react27.useReducer)(reducer3, { phase: "resolving", count: 0 });
|
|
41557
|
+
const started = (0, import_react27.useRef)(false);
|
|
41558
|
+
const parsedRef = (0, import_react27.useRef)(parsePipArgs(pipArgs));
|
|
41559
|
+
const pendingInstall = (0, import_react27.useRef)(null);
|
|
41560
|
+
const rejectRef = (0, import_react27.useRef)(null);
|
|
41561
|
+
const confirmInstall = () => {
|
|
41562
|
+
if (pendingInstall.current) {
|
|
41563
|
+
pendingInstall.current();
|
|
41564
|
+
pendingInstall.current = null;
|
|
41565
|
+
rejectRef.current = null;
|
|
41566
|
+
}
|
|
41567
|
+
};
|
|
41568
|
+
const rejectInstall = () => {
|
|
41569
|
+
if (rejectRef.current) {
|
|
41570
|
+
rejectRef.current();
|
|
41571
|
+
pendingInstall.current = null;
|
|
41572
|
+
rejectRef.current = null;
|
|
41573
|
+
}
|
|
41574
|
+
};
|
|
41575
|
+
(0, import_react27.useEffect)(() => {
|
|
41576
|
+
if (started.current) return;
|
|
41577
|
+
started.current = true;
|
|
41578
|
+
const parsed = parsedRef.current;
|
|
41579
|
+
(async () => {
|
|
41580
|
+
try {
|
|
41581
|
+
if (!parsed.shouldScan) {
|
|
41582
|
+
dispatch({ type: "PASSTHROUGH" });
|
|
41583
|
+
const code = await runPip(parsed.rawArgs);
|
|
41584
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41585
|
+
return;
|
|
41586
|
+
}
|
|
41587
|
+
let specs;
|
|
41588
|
+
if (parsed.packages.length === 0 && parsed.requirementsFile) {
|
|
41589
|
+
specs = parseRequirementsFile(parsed.requirementsFile);
|
|
41590
|
+
if (specs.length === 0) {
|
|
41591
|
+
dispatch({ type: "PASSTHROUGH" });
|
|
41592
|
+
const code = await runPip(parsed.rawArgs);
|
|
41593
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41594
|
+
return;
|
|
41595
|
+
}
|
|
41596
|
+
} else if (parsed.packages.length === 0) {
|
|
41597
|
+
dispatch({ type: "PASSTHROUGH" });
|
|
41598
|
+
const code = await runPip(parsed.rawArgs);
|
|
41599
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41600
|
+
return;
|
|
41601
|
+
} else {
|
|
41602
|
+
specs = parsed.packages;
|
|
41603
|
+
}
|
|
41604
|
+
dispatch({ type: "RESOLVING", count: specs.length });
|
|
41605
|
+
const { resolved, failed } = await resolvePackages2(specs);
|
|
41606
|
+
if (resolved.length === 0) {
|
|
41607
|
+
dispatch({ type: "PASSTHROUGH" });
|
|
41608
|
+
const code = await runPip(parsed.rawArgs);
|
|
41609
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41610
|
+
return;
|
|
41611
|
+
}
|
|
41612
|
+
dispatch({ type: "SCANNING", count: resolved.length });
|
|
41613
|
+
const result = await callPyPIAnalyzeAPI(resolved, config);
|
|
41614
|
+
if (result.action === "pass") {
|
|
41615
|
+
dispatch({ type: "PASS", count: resolved.length });
|
|
41616
|
+
dispatch({ type: "INSTALLING" });
|
|
41617
|
+
const code = await runPip(parsed.rawArgs);
|
|
41618
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41619
|
+
return;
|
|
41620
|
+
}
|
|
41621
|
+
if (result.action === "warn") {
|
|
41622
|
+
dispatch({ type: "WARN", result });
|
|
41623
|
+
process.stdout.write(renderResultStatic(result, config) + "\n");
|
|
41624
|
+
dispatch({ type: "INSTALLING" });
|
|
41625
|
+
const code = await runPip(parsed.rawArgs);
|
|
41626
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41627
|
+
return;
|
|
41628
|
+
}
|
|
41629
|
+
if (result.action === "block") {
|
|
41630
|
+
process.stdout.write(renderResultStatic(result, config) + "\n");
|
|
41631
|
+
if (parsed.dgForce) {
|
|
41632
|
+
dispatch({ type: "BLOCKED", result, dgForce: true });
|
|
41633
|
+
dispatch({ type: "INSTALLING" });
|
|
41634
|
+
const code = await runPip(parsed.rawArgs);
|
|
41635
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41636
|
+
return;
|
|
41637
|
+
}
|
|
41638
|
+
dispatch({ type: "BLOCKED", result, dgForce: false });
|
|
41639
|
+
const shouldProceed = await new Promise((resolve) => {
|
|
41640
|
+
pendingInstall.current = () => resolve(true);
|
|
41641
|
+
rejectRef.current = () => resolve(false);
|
|
41642
|
+
});
|
|
41643
|
+
if (shouldProceed) {
|
|
41644
|
+
dispatch({ type: "INSTALLING" });
|
|
41645
|
+
const code = await runPip(parsed.rawArgs);
|
|
41646
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41647
|
+
} else {
|
|
41648
|
+
dispatch({ type: "DONE", exitCode: 2 });
|
|
41649
|
+
}
|
|
41650
|
+
return;
|
|
41651
|
+
}
|
|
41652
|
+
} catch (error) {
|
|
41653
|
+
if (error instanceof TrialExhaustedError) {
|
|
41654
|
+
dispatch({ type: "TRIAL_EXHAUSTED" });
|
|
41655
|
+
return;
|
|
41656
|
+
}
|
|
41657
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41658
|
+
dispatch({ type: "ERROR", message, proceed: true });
|
|
41659
|
+
dispatch({ type: "INSTALLING" });
|
|
41660
|
+
const code = await runPip(parsedRef.current.rawArgs);
|
|
41661
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
41662
|
+
}
|
|
41663
|
+
})();
|
|
41664
|
+
}, [pipArgs, config]);
|
|
41665
|
+
return { state, confirmInstall, rejectInstall };
|
|
41666
|
+
}
|
|
41667
|
+
var import_react27;
|
|
41668
|
+
var init_usePipWrapper = __esm({
|
|
41669
|
+
"src/ui/hooks/usePipWrapper.ts"() {
|
|
41670
|
+
"use strict";
|
|
41671
|
+
import_react27 = __toESM(require_react());
|
|
41672
|
+
init_pip_wrapper();
|
|
41673
|
+
init_api();
|
|
41674
|
+
init_static_output();
|
|
41675
|
+
}
|
|
41676
|
+
});
|
|
41677
|
+
|
|
41678
|
+
// src/ui/PipWrapperApp.tsx
|
|
41679
|
+
var PipWrapperApp_exports = {};
|
|
41680
|
+
__export(PipWrapperApp_exports, {
|
|
41681
|
+
PipWrapperApp: () => PipWrapperApp
|
|
41682
|
+
});
|
|
41683
|
+
var import_react28, import_jsx_runtime9, PipWrapperApp;
|
|
41684
|
+
var init_PipWrapperApp = __esm({
|
|
41685
|
+
async "src/ui/PipWrapperApp.tsx"() {
|
|
41686
|
+
"use strict";
|
|
41687
|
+
import_react28 = __toESM(require_react());
|
|
41688
|
+
await init_build2();
|
|
41689
|
+
init_usePipWrapper();
|
|
41690
|
+
await init_Spinner();
|
|
41691
|
+
await init_ResultsView();
|
|
41692
|
+
await init_ConfirmPrompt();
|
|
41693
|
+
await init_ErrorView();
|
|
41694
|
+
import_jsx_runtime9 = __toESM(require_jsx_runtime());
|
|
41695
|
+
PipWrapperApp = ({
|
|
41696
|
+
pipArgs,
|
|
41697
|
+
config
|
|
41698
|
+
}) => {
|
|
41699
|
+
const { state, confirmInstall, rejectInstall } = usePipWrapper(pipArgs, config);
|
|
41700
|
+
const { exit } = use_app_default();
|
|
41701
|
+
(0, import_react28.useEffect)(() => {
|
|
41702
|
+
if (state.phase === "done") {
|
|
41703
|
+
process.exitCode = state.exitCode;
|
|
41704
|
+
const timer = setTimeout(() => exit(), 0);
|
|
41705
|
+
return () => clearTimeout(timer);
|
|
41706
|
+
}
|
|
41707
|
+
if (state.phase === "trial_exhausted") {
|
|
41708
|
+
process.exitCode = 1;
|
|
41709
|
+
const timer = setTimeout(() => exit(), 0);
|
|
41710
|
+
return () => clearTimeout(timer);
|
|
41711
|
+
}
|
|
41712
|
+
if (state.phase === "passthrough") {
|
|
41713
|
+
}
|
|
41714
|
+
}, [state, exit]);
|
|
41715
|
+
const handleConfirm = (0, import_react28.useCallback)(() => {
|
|
41716
|
+
confirmInstall();
|
|
41717
|
+
}, [confirmInstall]);
|
|
41718
|
+
const handleReject = (0, import_react28.useCallback)(() => {
|
|
41719
|
+
rejectInstall();
|
|
41720
|
+
}, [rejectInstall]);
|
|
41721
|
+
switch (state.phase) {
|
|
41722
|
+
case "resolving":
|
|
41723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41724
|
+
Spinner2,
|
|
41725
|
+
{
|
|
41726
|
+
label: `Resolving ${state.count} package${state.count !== 1 ? "s" : ""} from PyPI...`
|
|
41727
|
+
}
|
|
41728
|
+
);
|
|
41729
|
+
case "scanning":
|
|
41730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41731
|
+
Spinner2,
|
|
41732
|
+
{
|
|
41733
|
+
label: `Scanning ${state.count} Python package${state.count !== 1 ? "s" : ""}...`
|
|
41734
|
+
}
|
|
41735
|
+
);
|
|
41736
|
+
case "pass":
|
|
41737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: "green", children: [
|
|
41738
|
+
"\u2713",
|
|
41739
|
+
" ",
|
|
41740
|
+
state.count,
|
|
41741
|
+
" package",
|
|
41742
|
+
state.count !== 1 ? "s" : "",
|
|
41743
|
+
" scanned",
|
|
41744
|
+
" \u2014 ",
|
|
41745
|
+
"all clear"
|
|
41746
|
+
] });
|
|
41747
|
+
case "warn":
|
|
41748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
41749
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41750
|
+
ResultsView,
|
|
41751
|
+
{
|
|
41752
|
+
result: state.result,
|
|
41753
|
+
config,
|
|
41754
|
+
durationMs: state.result.durationMs
|
|
41755
|
+
}
|
|
41756
|
+
),
|
|
41757
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "yellow", children: "Warnings detected. Proceeding with install..." })
|
|
41758
|
+
] });
|
|
41759
|
+
case "blocked":
|
|
41760
|
+
if (state.dgForce) {
|
|
41761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
41762
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41763
|
+
ResultsView,
|
|
41764
|
+
{
|
|
41765
|
+
result: state.result,
|
|
41766
|
+
config,
|
|
41767
|
+
durationMs: state.result.durationMs
|
|
41768
|
+
}
|
|
41769
|
+
),
|
|
41770
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "yellow", bold: true, children: "--dg-force: Bypassing block. Install at your own risk." })
|
|
41771
|
+
] });
|
|
41772
|
+
}
|
|
41773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
41774
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41775
|
+
ResultsView,
|
|
41776
|
+
{
|
|
41777
|
+
result: state.result,
|
|
41778
|
+
config,
|
|
41779
|
+
durationMs: state.result.durationMs
|
|
41780
|
+
}
|
|
41781
|
+
),
|
|
41782
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: "red", bold: true, children: [
|
|
41783
|
+
"BLOCKED:",
|
|
41784
|
+
" ",
|
|
41785
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "red", children: "High-risk packages detected." })
|
|
41786
|
+
] }),
|
|
41787
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
41788
|
+
ConfirmPrompt,
|
|
41789
|
+
{
|
|
41790
|
+
message: "Proceed with install anyway?",
|
|
41791
|
+
onConfirm: handleConfirm,
|
|
41792
|
+
onReject: handleReject
|
|
41793
|
+
}
|
|
41794
|
+
)
|
|
41172
41795
|
] });
|
|
41796
|
+
case "installing":
|
|
41797
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner2, { label: "Installing with pip..." });
|
|
41798
|
+
case "done":
|
|
41799
|
+
return null;
|
|
41800
|
+
case "error":
|
|
41801
|
+
if (state.proceed) {
|
|
41802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: "yellow", children: [
|
|
41803
|
+
"Warning: Scan failed (",
|
|
41804
|
+
state.message,
|
|
41805
|
+
"). Proceeding with install."
|
|
41806
|
+
] });
|
|
41807
|
+
}
|
|
41808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ErrorView, { error: new Error(state.message) });
|
|
41809
|
+
case "passthrough":
|
|
41810
|
+
return null;
|
|
41811
|
+
case "trial_exhausted": {
|
|
41812
|
+
let hasKey = false;
|
|
41813
|
+
try {
|
|
41814
|
+
const { getStoredApiKey: getStoredApiKey2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
41815
|
+
hasKey = !!getStoredApiKey2();
|
|
41816
|
+
} catch {
|
|
41817
|
+
}
|
|
41818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, children: hasKey ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
41819
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "yellow", bold: true, children: "Your API key may be invalid or expired." }),
|
|
41820
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
41821
|
+
"Run ",
|
|
41822
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "cyan", bold: true, children: "dg logout" }),
|
|
41823
|
+
" then ",
|
|
41824
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
41825
|
+
" to re-authenticate."
|
|
41826
|
+
] })
|
|
41827
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
41828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "yellow", bold: true, children: "Free trial scans used up." }),
|
|
41829
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
41830
|
+
"Run ",
|
|
41831
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
41832
|
+
" to create a free account and continue scanning."
|
|
41833
|
+
] })
|
|
41834
|
+
] }) });
|
|
41835
|
+
}
|
|
41173
41836
|
}
|
|
41174
41837
|
};
|
|
41175
41838
|
}
|
|
41176
41839
|
});
|
|
41177
41840
|
|
|
41178
41841
|
// src/ui/hooks/useScan.ts
|
|
41179
|
-
function
|
|
41842
|
+
function reducer4(_state, action) {
|
|
41180
41843
|
switch (action.type) {
|
|
41181
41844
|
case "PROJECTS_FOUND":
|
|
41182
41845
|
return { phase: "selecting", projects: action.projects };
|
|
@@ -41197,10 +41860,10 @@ function reducer3(_state, action) {
|
|
|
41197
41860
|
}
|
|
41198
41861
|
}
|
|
41199
41862
|
function useScan(config) {
|
|
41200
|
-
const [state, dispatch] = (0,
|
|
41201
|
-
const started = (0,
|
|
41202
|
-
const [multiProjects, setMultiProjects] = (0,
|
|
41203
|
-
(0,
|
|
41863
|
+
const [state, dispatch] = (0, import_react29.useReducer)(reducer4, { phase: "discovering" });
|
|
41864
|
+
const started = (0, import_react29.useRef)(false);
|
|
41865
|
+
const [multiProjects, setMultiProjects] = (0, import_react29.useState)(null);
|
|
41866
|
+
(0, import_react29.useEffect)(() => {
|
|
41204
41867
|
if (started.current) return;
|
|
41205
41868
|
started.current = true;
|
|
41206
41869
|
const projects = discoverProjects(process.cwd());
|
|
@@ -41211,10 +41874,9 @@ function useScan(config) {
|
|
|
41211
41874
|
}
|
|
41212
41875
|
try {
|
|
41213
41876
|
const discovery = discoverChanges(process.cwd(), config);
|
|
41214
|
-
const packages = discovery.packages
|
|
41877
|
+
const packages = discovery.packages;
|
|
41215
41878
|
if (packages.length === 0) {
|
|
41216
|
-
|
|
41217
|
-
dispatch({ type: "DISCOVERY_EMPTY", message });
|
|
41879
|
+
dispatch({ type: "DISCOVERY_EMPTY", message: "No package changes detected." });
|
|
41218
41880
|
return;
|
|
41219
41881
|
}
|
|
41220
41882
|
dispatch({ type: "DISCOVERY_COMPLETE", packages, skippedCount: discovery.skipped.length });
|
|
@@ -41228,11 +41890,11 @@ function useScan(config) {
|
|
|
41228
41890
|
scanProjects(projects, config, dispatch);
|
|
41229
41891
|
}
|
|
41230
41892
|
}, [config]);
|
|
41231
|
-
const scanSelectedProjects = (0,
|
|
41893
|
+
const scanSelectedProjects = (0, import_react29.useCallback)((projects) => {
|
|
41232
41894
|
dispatch({ type: "DISCOVERY_COMPLETE", packages: [], skippedCount: 0 });
|
|
41233
41895
|
scanProjects(projects, config, dispatch);
|
|
41234
41896
|
}, [config]);
|
|
41235
|
-
const restartSelection = (0,
|
|
41897
|
+
const restartSelection = (0, import_react29.useCallback)(() => {
|
|
41236
41898
|
if (!multiProjects) return;
|
|
41237
41899
|
dispatch({ type: "RESTART_SELECTION", projects: multiProjects });
|
|
41238
41900
|
}, [multiProjects]);
|
|
@@ -41273,7 +41935,7 @@ async function scanProjects(projects, config, dispatch) {
|
|
|
41273
41935
|
const discovery = discoverChanges(proj.path, fullScanConfig);
|
|
41274
41936
|
for (const pkg of discovery.packages) {
|
|
41275
41937
|
const key = `${pkg.name}@${pkg.version}`;
|
|
41276
|
-
if (!
|
|
41938
|
+
if (!seenNpm.has(key)) {
|
|
41277
41939
|
seenNpm.add(key);
|
|
41278
41940
|
npmPackages.push(pkg);
|
|
41279
41941
|
}
|
|
@@ -41286,7 +41948,7 @@ async function scanProjects(projects, config, dispatch) {
|
|
|
41286
41948
|
const packages = parsePythonDepFile(proj.path, proj.depFile);
|
|
41287
41949
|
for (const pkg of packages) {
|
|
41288
41950
|
const key = `${pkg.name}@${pkg.version}`;
|
|
41289
|
-
if (!
|
|
41951
|
+
if (!seenPypi.has(key)) {
|
|
41290
41952
|
seenPypi.add(key);
|
|
41291
41953
|
pypiPackages.push(pkg);
|
|
41292
41954
|
}
|
|
@@ -41335,7 +41997,7 @@ async function scanProjects(projects, config, dispatch) {
|
|
|
41335
41997
|
}
|
|
41336
41998
|
const allPackages = results.flatMap((r) => r.packages);
|
|
41337
41999
|
const maxScore = Math.max(0, ...allPackages.map((p) => p.score));
|
|
41338
|
-
const action = maxScore >=
|
|
42000
|
+
const action = maxScore >= 70 ? "block" : maxScore >= 60 ? "warn" : "pass";
|
|
41339
42001
|
const safeVersions = {};
|
|
41340
42002
|
for (const r of results) Object.assign(safeVersions, r.safeVersions);
|
|
41341
42003
|
const merged = {
|
|
@@ -41354,11 +42016,11 @@ async function scanProjects(projects, config, dispatch) {
|
|
|
41354
42016
|
dispatch({ type: "ERROR", error: error instanceof Error ? error : new Error(String(error)) });
|
|
41355
42017
|
}
|
|
41356
42018
|
}
|
|
41357
|
-
var
|
|
42019
|
+
var import_react29;
|
|
41358
42020
|
var init_useScan = __esm({
|
|
41359
42021
|
"src/ui/hooks/useScan.ts"() {
|
|
41360
42022
|
"use strict";
|
|
41361
|
-
|
|
42023
|
+
import_react29 = __toESM(require_react());
|
|
41362
42024
|
init_lockfile();
|
|
41363
42025
|
init_api();
|
|
41364
42026
|
init_discover();
|
|
@@ -41368,7 +42030,7 @@ var init_useScan = __esm({
|
|
|
41368
42030
|
|
|
41369
42031
|
// src/ui/components/ProgressBar.tsx
|
|
41370
42032
|
function estimateScanSeconds(packageCount) {
|
|
41371
|
-
return Math.ceil(
|
|
42033
|
+
return Math.ceil(Math.max(5, packageCount * 0.35 - 10));
|
|
41372
42034
|
}
|
|
41373
42035
|
function formatTime(seconds) {
|
|
41374
42036
|
if (seconds < 60) return `${seconds}s`;
|
|
@@ -41376,23 +42038,23 @@ function formatTime(seconds) {
|
|
|
41376
42038
|
const s = seconds % 60;
|
|
41377
42039
|
return s > 0 ? `${m}m ${s}s` : `${m}m`;
|
|
41378
42040
|
}
|
|
41379
|
-
var
|
|
42041
|
+
var import_react30, import_chalk9, import_jsx_runtime10, ProgressBar;
|
|
41380
42042
|
var init_ProgressBar = __esm({
|
|
41381
42043
|
async "src/ui/components/ProgressBar.tsx"() {
|
|
41382
42044
|
"use strict";
|
|
41383
|
-
|
|
42045
|
+
import_react30 = __toESM(require_react());
|
|
41384
42046
|
await init_build2();
|
|
41385
42047
|
await init_build3();
|
|
41386
42048
|
import_chalk9 = __toESM(require_source());
|
|
41387
|
-
|
|
42049
|
+
import_jsx_runtime10 = __toESM(require_jsx_runtime());
|
|
41388
42050
|
ProgressBar = ({
|
|
41389
42051
|
value,
|
|
41390
42052
|
total,
|
|
41391
42053
|
label
|
|
41392
42054
|
}) => {
|
|
41393
|
-
const startRef = (0,
|
|
41394
|
-
const [elapsed, setElapsed] = (0,
|
|
41395
|
-
(0,
|
|
42055
|
+
const startRef = (0, import_react30.useRef)(Date.now());
|
|
42056
|
+
const [elapsed, setElapsed] = (0, import_react30.useState)(0);
|
|
42057
|
+
(0, import_react30.useEffect)(() => {
|
|
41396
42058
|
const timer = setInterval(() => {
|
|
41397
42059
|
setElapsed(Math.floor((Date.now() - startRef.current) / 1e3));
|
|
41398
42060
|
}, 1e3);
|
|
@@ -41409,32 +42071,32 @@ var init_ProgressBar = __esm({
|
|
|
41409
42071
|
const empty = barWidth - filled;
|
|
41410
42072
|
const filledBar = "\u2501".repeat(filled);
|
|
41411
42073
|
const emptyBar = "\u2501".repeat(empty);
|
|
41412
|
-
return /* @__PURE__ */ (0,
|
|
41413
|
-
/* @__PURE__ */ (0,
|
|
42074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
|
|
42075
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
41414
42076
|
import_chalk9.default.cyan("\u25C6"),
|
|
41415
42077
|
" ",
|
|
41416
42078
|
import_chalk9.default.bold("Dependency Guardian")
|
|
41417
42079
|
] }),
|
|
41418
|
-
/* @__PURE__ */ (0,
|
|
41419
|
-
/* @__PURE__ */ (0,
|
|
41420
|
-
/* @__PURE__ */ (0,
|
|
41421
|
-
/* @__PURE__ */ (0,
|
|
42080
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: "" }),
|
|
42081
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { children: [
|
|
42082
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(build_default, { type: "dots" }) }),
|
|
42083
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
41422
42084
|
" Scanning ",
|
|
41423
42085
|
total,
|
|
41424
42086
|
" packages... "
|
|
41425
42087
|
] }),
|
|
41426
|
-
/* @__PURE__ */ (0,
|
|
42088
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { dimColor: true, children: timeInfo })
|
|
41427
42089
|
] }),
|
|
41428
|
-
/* @__PURE__ */ (0,
|
|
41429
|
-
/* @__PURE__ */ (0,
|
|
41430
|
-
/* @__PURE__ */ (0,
|
|
41431
|
-
/* @__PURE__ */ (0,
|
|
41432
|
-
/* @__PURE__ */ (0,
|
|
42090
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { children: [
|
|
42091
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: " " }),
|
|
42092
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "green", children: filledBar }),
|
|
42093
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { dimColor: true, children: emptyBar }),
|
|
42094
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
41433
42095
|
" ",
|
|
41434
42096
|
counter
|
|
41435
42097
|
] })
|
|
41436
42098
|
] }),
|
|
41437
|
-
label && /* @__PURE__ */ (0,
|
|
42099
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { dimColor: true, children: [
|
|
41438
42100
|
" ",
|
|
41439
42101
|
import_chalk9.default.dim("\u203A"),
|
|
41440
42102
|
" ",
|
|
@@ -41447,9 +42109,9 @@ var init_ProgressBar = __esm({
|
|
|
41447
42109
|
|
|
41448
42110
|
// src/ui/hooks/useExpandAnimation.ts
|
|
41449
42111
|
function useExpandAnimation(targetHeight, active, durationMs = 180) {
|
|
41450
|
-
const [visibleLines, setVisibleLines] = (0,
|
|
41451
|
-
const timerRef = (0,
|
|
41452
|
-
(0,
|
|
42112
|
+
const [visibleLines, setVisibleLines] = (0, import_react31.useState)(0);
|
|
42113
|
+
const timerRef = (0, import_react31.useRef)(null);
|
|
42114
|
+
(0, import_react31.useEffect)(() => {
|
|
41453
42115
|
if (timerRef.current) {
|
|
41454
42116
|
clearInterval(timerRef.current);
|
|
41455
42117
|
timerRef.current = null;
|
|
@@ -41483,22 +42145,22 @@ function useExpandAnimation(targetHeight, active, durationMs = 180) {
|
|
|
41483
42145
|
isAnimating: active && visibleLines > 0 && visibleLines < targetHeight
|
|
41484
42146
|
};
|
|
41485
42147
|
}
|
|
41486
|
-
var
|
|
42148
|
+
var import_react31;
|
|
41487
42149
|
var init_useExpandAnimation = __esm({
|
|
41488
42150
|
"src/ui/hooks/useExpandAnimation.ts"() {
|
|
41489
42151
|
"use strict";
|
|
41490
|
-
|
|
42152
|
+
import_react31 = __toESM(require_react());
|
|
41491
42153
|
}
|
|
41492
42154
|
});
|
|
41493
42155
|
|
|
41494
42156
|
// src/ui/hooks/useTerminalSize.ts
|
|
41495
42157
|
function useTerminalSize() {
|
|
41496
42158
|
const { stdout } = use_stdout_default();
|
|
41497
|
-
const [size, setSize] = (0,
|
|
42159
|
+
const [size, setSize] = (0, import_react32.useState)({
|
|
41498
42160
|
rows: stdout?.rows ?? process.stdout.rows ?? 24,
|
|
41499
42161
|
cols: stdout?.columns ?? process.stdout.columns ?? 80
|
|
41500
42162
|
});
|
|
41501
|
-
(0,
|
|
42163
|
+
(0, import_react32.useEffect)(() => {
|
|
41502
42164
|
const handle = () => {
|
|
41503
42165
|
const rows = process.stdout.rows ?? 24;
|
|
41504
42166
|
const cols = process.stdout.columns ?? 80;
|
|
@@ -41516,11 +42178,11 @@ function useTerminalSize() {
|
|
|
41516
42178
|
}, []);
|
|
41517
42179
|
return size;
|
|
41518
42180
|
}
|
|
41519
|
-
var
|
|
42181
|
+
var import_react32;
|
|
41520
42182
|
var init_useTerminalSize = __esm({
|
|
41521
42183
|
async "src/ui/hooks/useTerminalSize.ts"() {
|
|
41522
42184
|
"use strict";
|
|
41523
|
-
|
|
42185
|
+
import_react32 = __toESM(require_react());
|
|
41524
42186
|
await init_build2();
|
|
41525
42187
|
}
|
|
41526
42188
|
});
|
|
@@ -41536,10 +42198,10 @@ function groupPackages3(packages) {
|
|
|
41536
42198
|
}
|
|
41537
42199
|
return [...map.entries()].map(([fingerprint, pkgs]) => ({ packages: pkgs, key: fingerprint })).sort((a, b) => b.packages[0].score - a.packages[0].score);
|
|
41538
42200
|
}
|
|
41539
|
-
function actionBadge3(score
|
|
41540
|
-
if (score >=
|
|
42201
|
+
function actionBadge3(score) {
|
|
42202
|
+
if (score >= 70)
|
|
41541
42203
|
return { label: "BLOCK", color: import_chalk10.default.red };
|
|
41542
|
-
if (score >=
|
|
42204
|
+
if (score >= 60)
|
|
41543
42205
|
return { label: "WARN", color: import_chalk10.default.yellow };
|
|
41544
42206
|
return { label: "PASS", color: import_chalk10.default.green };
|
|
41545
42207
|
}
|
|
@@ -41553,6 +42215,7 @@ function findingsSummaryHeight(group) {
|
|
|
41553
42215
|
const rep = group.packages[0];
|
|
41554
42216
|
const visibleFindings = rep.findings.filter((f) => f.severity > 1 || f.critical);
|
|
41555
42217
|
let h = visibleFindings.length;
|
|
42218
|
+
if (rep.license) h += 1;
|
|
41556
42219
|
if (visibleFindings.length === 0 && rep.score > 0) {
|
|
41557
42220
|
h += (rep.reasons ?? []).length;
|
|
41558
42221
|
h += 1;
|
|
@@ -41564,6 +42227,7 @@ function findingsDetailHeight(group, safeVersions) {
|
|
|
41564
42227
|
const rep = group.packages[0];
|
|
41565
42228
|
const visibleFindings = rep.findings.filter((f) => f.severity > 1 || f.critical).sort((a, b) => b.severity - a.severity);
|
|
41566
42229
|
let h = 0;
|
|
42230
|
+
if (rep.license) h += 1;
|
|
41567
42231
|
if (group.packages.length > 3) h += 1;
|
|
41568
42232
|
if (visibleFindings.length === 0 && rep.score > 0) {
|
|
41569
42233
|
h += (rep.reasons ?? []).length;
|
|
@@ -41605,88 +42269,26 @@ function buildDetailLines(group, safeVersion, maxWidth) {
|
|
|
41605
42269
|
const evidenceWidth = Math.max(30, maxWidth - 12);
|
|
41606
42270
|
if (group.packages.length > 3) {
|
|
41607
42271
|
lines.push(
|
|
41608
|
-
/* @__PURE__ */ (0,
|
|
42272
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
41609
42273
|
"Affects: ",
|
|
41610
42274
|
affectsLine(group)
|
|
41611
42275
|
] }, "affects")
|
|
41612
42276
|
);
|
|
41613
|
-
lines.push(/* @__PURE__ */ (0,
|
|
41614
|
-
}
|
|
41615
|
-
if (visibleFindings.length === 0 && rep.score > 0) {
|
|
41616
|
-
const reasons = rep.reasons ?? [];
|
|
41617
|
-
for (let i = 0; i < reasons.length; i++) {
|
|
41618
|
-
lines.push(
|
|
41619
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { dimColor: true, children: truncate3(reasons[i], maxWidth - 4) }, `reason-${i}`)
|
|
41620
|
-
);
|
|
41621
|
-
}
|
|
41622
|
-
lines.push(
|
|
41623
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
41624
|
-
import_chalk10.default.yellow("\u2192"),
|
|
41625
|
-
" ",
|
|
41626
|
-
import_chalk10.default.yellow("Upgrade to Pro"),
|
|
41627
|
-
" ",
|
|
41628
|
-
import_chalk10.default.dim("to see finding details \u2014 dg login")
|
|
41629
|
-
] }, "upgrade")
|
|
41630
|
-
);
|
|
41631
|
-
return lines;
|
|
41632
|
-
}
|
|
41633
|
-
const hasEvidence = visibleFindings.some((f) => f.evidence && f.evidence.length > 0);
|
|
41634
|
-
for (let idx = 0; idx < visibleFindings.length; idx++) {
|
|
41635
|
-
const finding = visibleFindings[idx];
|
|
41636
|
-
const sevLabel = SEVERITY_LABELS3[finding.severity] ?? "INFO";
|
|
41637
|
-
const sevColor = SEVERITY_COLORS[finding.severity] ?? SEVERITY_COLORS[1];
|
|
41638
|
-
const evidence = finding.evidence ?? [];
|
|
41639
|
-
const findingId = finding.id ?? finding.category ?? "";
|
|
41640
|
-
if (idx > 0) lines.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: "" }, `gap-${idx}`));
|
|
41641
|
-
lines.push(
|
|
41642
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
41643
|
-
sevColor(pad3(sevLabel, 5)),
|
|
41644
|
-
" ",
|
|
41645
|
-
findingId
|
|
41646
|
-
] }, `${findingId}-${idx}-badge`)
|
|
41647
|
-
);
|
|
41648
|
-
lines.push(
|
|
41649
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { dimColor: true, children: [
|
|
41650
|
-
" ",
|
|
41651
|
-
finding.title
|
|
41652
|
-
] }, `${findingId}-${idx}-title`)
|
|
41653
|
-
);
|
|
41654
|
-
const evidenceCap = Math.min(evidence.length, DETAIL_EVIDENCE_LIMIT);
|
|
41655
|
-
for (let i = 0; i < evidenceCap; i++) {
|
|
41656
|
-
lines.push(
|
|
41657
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { dimColor: true, children: [
|
|
41658
|
-
" ",
|
|
41659
|
-
import_chalk10.default.dim("\u203A"),
|
|
41660
|
-
" ",
|
|
41661
|
-
truncate3(evidence[i], evidenceWidth)
|
|
41662
|
-
] }, `${findingId}-${idx}-ev-${i}`)
|
|
41663
|
-
);
|
|
41664
|
-
}
|
|
41665
|
-
if (evidence.length > DETAIL_EVIDENCE_LIMIT) {
|
|
41666
|
-
lines.push(
|
|
41667
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { dimColor: true, children: [
|
|
41668
|
-
" ",
|
|
41669
|
-
import_chalk10.default.dim(`+${evidence.length - DETAIL_EVIDENCE_LIMIT} more`)
|
|
41670
|
-
] }, `${findingId}-${idx}-overflow`)
|
|
41671
|
-
);
|
|
41672
|
-
}
|
|
42277
|
+
lines.push(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }, "affects-gap"));
|
|
41673
42278
|
}
|
|
41674
|
-
if (
|
|
41675
|
-
lines.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: "" }, "upgrade-gap"));
|
|
42279
|
+
if (rep.score > 0) {
|
|
41676
42280
|
lines.push(
|
|
41677
|
-
/* @__PURE__ */ (0,
|
|
41678
|
-
|
|
41679
|
-
|
|
41680
|
-
|
|
41681
|
-
|
|
41682
|
-
import_chalk10.default.dim("for evidence and file locations")
|
|
41683
|
-
] }, "upgrade-evidence")
|
|
42281
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42282
|
+
"Score: ",
|
|
42283
|
+
rep.score,
|
|
42284
|
+
"/100"
|
|
42285
|
+
] }, "score-info")
|
|
41684
42286
|
);
|
|
41685
42287
|
}
|
|
41686
42288
|
if (rep.recommendation) {
|
|
41687
|
-
lines.push(/* @__PURE__ */ (0,
|
|
42289
|
+
lines.push(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }, "rec-gap"));
|
|
41688
42290
|
lines.push(
|
|
41689
|
-
/* @__PURE__ */ (0,
|
|
42291
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
41690
42292
|
import_chalk10.default.dim("Rec:"),
|
|
41691
42293
|
" ",
|
|
41692
42294
|
import_chalk10.default.cyan(truncate3(rep.recommendation, maxWidth - 8))
|
|
@@ -41695,7 +42297,7 @@ function buildDetailLines(group, safeVersion, maxWidth) {
|
|
|
41695
42297
|
}
|
|
41696
42298
|
if (safeVersion) {
|
|
41697
42299
|
lines.push(
|
|
41698
|
-
/* @__PURE__ */ (0,
|
|
42300
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: import_chalk10.default.green(`Safe: ${rep.name}@${safeVersion}`) }, "safe")
|
|
41699
42301
|
);
|
|
41700
42302
|
}
|
|
41701
42303
|
return lines;
|
|
@@ -41710,18 +42312,34 @@ function viewReducer(_state, action) {
|
|
|
41710
42312
|
return { cursor: action.cursor, expandedIndex: action.expandedIndex, expandLevel: action.expandLevel, viewport: action.viewport };
|
|
41711
42313
|
}
|
|
41712
42314
|
}
|
|
41713
|
-
|
|
42315
|
+
function licenseLine(rep) {
|
|
42316
|
+
const lc = rep.license;
|
|
42317
|
+
if (!lc) return null;
|
|
42318
|
+
const spdx = lc.spdx ?? lc.raw ?? "";
|
|
42319
|
+
const desc = LICENSE_DESCRIPTIONS[lc.riskCategory] ?? "";
|
|
42320
|
+
const lcColor = lc.riskCategory === "permissive" ? import_chalk10.default.green : lc.riskCategory === "no-license" || lc.riskCategory === "unlicensed" || lc.riskCategory === "network-copyleft" ? import_chalk10.default.red : import_chalk10.default.yellow;
|
|
42321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42322
|
+
T.branch,
|
|
42323
|
+
" ",
|
|
42324
|
+
lcColor(spdx),
|
|
42325
|
+
" ",
|
|
42326
|
+
import_chalk10.default.dim("\u2014"),
|
|
42327
|
+
" ",
|
|
42328
|
+
import_chalk10.default.dim(desc)
|
|
42329
|
+
] }, "license-info");
|
|
42330
|
+
}
|
|
42331
|
+
var import_react33, import_chalk10, import_jsx_runtime11, SEVERITY_LABELS2, SEVERITY_COLORS, EVIDENCE_LIMIT2, FIXED_CHROME, DETAIL_PANE_CHROME, InteractiveResultsView, T, LICENSE_DESCRIPTIONS, FindingsSummary;
|
|
41714
42332
|
var init_InteractiveResultsView = __esm({
|
|
41715
42333
|
async "src/ui/components/InteractiveResultsView.tsx"() {
|
|
41716
42334
|
"use strict";
|
|
41717
|
-
|
|
42335
|
+
import_react33 = __toESM(require_react());
|
|
41718
42336
|
await init_build2();
|
|
41719
42337
|
import_chalk10 = __toESM(require_source());
|
|
41720
42338
|
await init_ScoreHeader();
|
|
41721
42339
|
init_useExpandAnimation();
|
|
41722
42340
|
await init_useTerminalSize();
|
|
41723
|
-
|
|
41724
|
-
|
|
42341
|
+
import_jsx_runtime11 = __toESM(require_jsx_runtime());
|
|
42342
|
+
SEVERITY_LABELS2 = {
|
|
41725
42343
|
5: "CRIT",
|
|
41726
42344
|
4: "HIGH",
|
|
41727
42345
|
3: "MED",
|
|
@@ -41738,7 +42356,6 @@ var init_InteractiveResultsView = __esm({
|
|
|
41738
42356
|
EVIDENCE_LIMIT2 = 2;
|
|
41739
42357
|
FIXED_CHROME = 21;
|
|
41740
42358
|
DETAIL_PANE_CHROME = 20;
|
|
41741
|
-
DETAIL_EVIDENCE_LIMIT = 10;
|
|
41742
42359
|
InteractiveResultsView = ({
|
|
41743
42360
|
result,
|
|
41744
42361
|
config,
|
|
@@ -41747,24 +42364,24 @@ var init_InteractiveResultsView = __esm({
|
|
|
41747
42364
|
onBack,
|
|
41748
42365
|
discoveredTotal
|
|
41749
42366
|
}) => {
|
|
41750
|
-
const flagged = (0,
|
|
42367
|
+
const flagged = (0, import_react33.useMemo)(
|
|
41751
42368
|
() => result.packages.filter((p) => p.score > 0),
|
|
41752
42369
|
[result.packages]
|
|
41753
42370
|
);
|
|
41754
|
-
const clean = (0,
|
|
42371
|
+
const clean = (0, import_react33.useMemo)(
|
|
41755
42372
|
() => result.packages.filter((p) => p.score === 0),
|
|
41756
42373
|
[result.packages]
|
|
41757
42374
|
);
|
|
41758
42375
|
const total = result.packages.length;
|
|
41759
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
41760
|
-
const allGroups = (0,
|
|
42376
|
+
const [searchQuery, setSearchQuery] = (0, import_react33.useState)("");
|
|
42377
|
+
const allGroups = (0, import_react33.useMemo)(() => groupPackages3(flagged), [flagged]);
|
|
41761
42378
|
const allGroupCount = allGroups.length;
|
|
41762
|
-
const groups = (0,
|
|
42379
|
+
const groups = (0, import_react33.useMemo)(() => {
|
|
41763
42380
|
if (!searchQuery) return allGroups;
|
|
41764
42381
|
const q = searchQuery.toLowerCase();
|
|
41765
42382
|
return allGroups.filter((g) => g.packages.some((p) => p.name.toLowerCase().includes(q)));
|
|
41766
42383
|
}, [allGroups, searchQuery]);
|
|
41767
|
-
const severityCounts = (0,
|
|
42384
|
+
const severityCounts = (0, import_react33.useMemo)(() => {
|
|
41768
42385
|
const counts = {};
|
|
41769
42386
|
for (const pkg of flagged) {
|
|
41770
42387
|
const maxSev = pkg.findings.reduce((m, f) => Math.max(m, f.severity), 0);
|
|
@@ -41772,28 +42389,28 @@ var init_InteractiveResultsView = __esm({
|
|
|
41772
42389
|
}
|
|
41773
42390
|
return counts;
|
|
41774
42391
|
}, [flagged]);
|
|
41775
|
-
const [view, dispatchView] = (0,
|
|
42392
|
+
const [view, dispatchView] = (0, import_react33.useReducer)(viewReducer, {
|
|
41776
42393
|
cursor: 0,
|
|
41777
42394
|
expandLevel: null,
|
|
41778
42395
|
expandedIndex: null,
|
|
41779
42396
|
viewport: 0
|
|
41780
42397
|
});
|
|
41781
|
-
const viewRef = (0,
|
|
42398
|
+
const viewRef = (0, import_react33.useRef)(view);
|
|
41782
42399
|
viewRef.current = view;
|
|
41783
|
-
const [detailPane, setDetailPane] = (0,
|
|
41784
|
-
const detailPaneRef = (0,
|
|
42400
|
+
const [detailPane, setDetailPane] = (0, import_react33.useState)(null);
|
|
42401
|
+
const detailPaneRef = (0, import_react33.useRef)(detailPane);
|
|
41785
42402
|
detailPaneRef.current = detailPane;
|
|
41786
|
-
const [showHelp, setShowHelp] = (0,
|
|
41787
|
-
const showHelpRef = (0,
|
|
42403
|
+
const [showHelp, setShowHelp] = (0, import_react33.useState)(false);
|
|
42404
|
+
const showHelpRef = (0, import_react33.useRef)(showHelp);
|
|
41788
42405
|
showHelpRef.current = showHelp;
|
|
41789
|
-
const [searchMode, setSearchMode] = (0,
|
|
41790
|
-
const searchModeRef = (0,
|
|
42406
|
+
const [searchMode, setSearchMode] = (0, import_react33.useState)(false);
|
|
42407
|
+
const searchModeRef = (0, import_react33.useRef)(searchMode);
|
|
41791
42408
|
searchModeRef.current = searchMode;
|
|
41792
42409
|
const { rows: termRows, cols: termCols } = useTerminalSize();
|
|
41793
42410
|
const availableRows = Math.max(5, termRows - FIXED_CHROME);
|
|
41794
42411
|
const innerWidth = Math.max(40, termCols - 6);
|
|
41795
42412
|
const detailGroupIdx = detailPane?.groupIndex ?? -1;
|
|
41796
|
-
const detailLines = (0,
|
|
42413
|
+
const detailLines = (0, import_react33.useMemo)(() => {
|
|
41797
42414
|
if (detailGroupIdx < 0) return [];
|
|
41798
42415
|
const group = groups[detailGroupIdx];
|
|
41799
42416
|
if (!group) return [];
|
|
@@ -41803,7 +42420,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
41803
42420
|
const getLevel = (idx) => {
|
|
41804
42421
|
return view.expandedIndex === idx ? view.expandLevel : null;
|
|
41805
42422
|
};
|
|
41806
|
-
const expandTargetHeight = (0,
|
|
42423
|
+
const expandTargetHeight = (0, import_react33.useMemo)(() => {
|
|
41807
42424
|
if (view.expandedIndex === null || view.expandLevel === null) return 0;
|
|
41808
42425
|
const group = groups[view.expandedIndex];
|
|
41809
42426
|
if (!group) return 0;
|
|
@@ -41819,7 +42436,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
41819
42436
|
if (idx === view.expandedIndex) return 1 + animVisibleLines;
|
|
41820
42437
|
return groupRowHeight(group, level, result.safeVersions);
|
|
41821
42438
|
};
|
|
41822
|
-
const visibleEnd = (0,
|
|
42439
|
+
const visibleEnd = (0, import_react33.useMemo)(() => {
|
|
41823
42440
|
let consumed = 0;
|
|
41824
42441
|
let end = view.viewport;
|
|
41825
42442
|
while (end < groups.length) {
|
|
@@ -41851,13 +42468,22 @@ var init_InteractiveResultsView = __esm({
|
|
|
41851
42468
|
}
|
|
41852
42469
|
return newStart;
|
|
41853
42470
|
};
|
|
41854
|
-
(0,
|
|
42471
|
+
(0, import_react33.useEffect)(() => {
|
|
41855
42472
|
if (groups.length === 0) return;
|
|
41856
42473
|
const { cursor, expandedIndex, expandLevel, viewport } = viewRef.current;
|
|
41857
42474
|
const clamped = Math.min(viewport, Math.max(0, groups.length - 1));
|
|
41858
42475
|
const newVp = adjustViewport(cursor, expandedIndex, expandLevel, clamped);
|
|
41859
42476
|
dispatchView({ type: "MOVE", cursor, viewport: newVp });
|
|
41860
42477
|
}, [availableRows]);
|
|
42478
|
+
(0, import_react33.useEffect)(() => {
|
|
42479
|
+
const dp = detailPaneRef.current;
|
|
42480
|
+
if (dp && detailLines.length > 0) {
|
|
42481
|
+
const maxScroll = Math.max(0, detailLines.length - detailContentRows);
|
|
42482
|
+
if (dp.scroll > maxScroll) {
|
|
42483
|
+
setDetailPane({ groupIndex: dp.groupIndex, scroll: maxScroll });
|
|
42484
|
+
}
|
|
42485
|
+
}
|
|
42486
|
+
}, [detailContentRows, detailLines.length]);
|
|
41861
42487
|
use_input_default((input, key) => {
|
|
41862
42488
|
if (groups.length === 0) {
|
|
41863
42489
|
if (input === "q" || key.return) onExit();
|
|
@@ -41899,13 +42525,18 @@ var init_InteractiveResultsView = __esm({
|
|
|
41899
42525
|
setDetailPane({ groupIndex: dp.groupIndex, scroll: 0 });
|
|
41900
42526
|
} else if (input === "G") {
|
|
41901
42527
|
setDetailPane({ groupIndex: dp.groupIndex, scroll: maxScroll });
|
|
41902
|
-
} else if (input === "e" || input === "b" || key.escape) {
|
|
42528
|
+
} else if (input === " " || input === "e" || input === "b" || key.escape) {
|
|
41903
42529
|
setDetailPane(null);
|
|
41904
42530
|
} else if (input === "q") {
|
|
41905
42531
|
onExit();
|
|
41906
42532
|
}
|
|
41907
42533
|
return;
|
|
41908
42534
|
}
|
|
42535
|
+
if (groups.length === 0) {
|
|
42536
|
+
if (input === "q") onExit();
|
|
42537
|
+
else if (input === "/") setSearchMode(true);
|
|
42538
|
+
return;
|
|
42539
|
+
}
|
|
41909
42540
|
const { cursor, expandLevel: expLvl, expandedIndex: expIdx, viewport: vpStart } = viewRef.current;
|
|
41910
42541
|
if (key.upArrow || input === "k") {
|
|
41911
42542
|
const next = Math.max(0, cursor - 1);
|
|
@@ -41942,7 +42573,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
41942
42573
|
}
|
|
41943
42574
|
const newVp = adjustViewport(cursor, newExpIdx, newExpLvl, vpStart);
|
|
41944
42575
|
dispatchView({ type: "EXPAND", expandedIndex: newExpIdx, expandLevel: newExpLvl, viewport: newVp });
|
|
41945
|
-
} else if (input === "e") {
|
|
42576
|
+
} else if (input === " " || input === "e") {
|
|
41946
42577
|
setDetailPane({ groupIndex: view.cursor, scroll: 0 });
|
|
41947
42578
|
} else if (input === "/") {
|
|
41948
42579
|
setSearchMode(true);
|
|
@@ -41955,11 +42586,13 @@ var init_InteractiveResultsView = __esm({
|
|
|
41955
42586
|
const visibleGroups = groups.slice(view.viewport, visibleEnd);
|
|
41956
42587
|
const aboveCount = view.viewport;
|
|
41957
42588
|
const belowCount = groups.length - visibleEnd;
|
|
41958
|
-
const
|
|
42589
|
+
const lcCol = 16;
|
|
42590
|
+
const nameCol = Math.max(20, innerWidth - 22 - lcCol);
|
|
42591
|
+
const clampedCursor = groups.length > 0 ? Math.min(view.cursor, groups.length - 1) : 0;
|
|
41959
42592
|
if (showHelp) {
|
|
41960
42593
|
const isDetail = detailPane !== null;
|
|
41961
|
-
return /* @__PURE__ */ (0,
|
|
41962
|
-
/* @__PURE__ */ (0,
|
|
42594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
42595
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
41963
42596
|
ScoreHeader,
|
|
41964
42597
|
{
|
|
41965
42598
|
score: result.score,
|
|
@@ -41970,7 +42603,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
41970
42603
|
severityCounts
|
|
41971
42604
|
}
|
|
41972
42605
|
),
|
|
41973
|
-
/* @__PURE__ */ (0,
|
|
42606
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
41974
42607
|
Box_default,
|
|
41975
42608
|
{
|
|
41976
42609
|
flexDirection: "column",
|
|
@@ -41980,82 +42613,82 @@ var init_InteractiveResultsView = __esm({
|
|
|
41980
42613
|
paddingRight: 2,
|
|
41981
42614
|
width: "100%",
|
|
41982
42615
|
children: [
|
|
41983
|
-
/* @__PURE__ */ (0,
|
|
42616
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
41984
42617
|
import_chalk10.default.cyan("\u25C6"),
|
|
41985
42618
|
" Keyboard Shortcuts"
|
|
41986
42619
|
] }),
|
|
41987
|
-
/* @__PURE__ */ (0,
|
|
41988
|
-
/* @__PURE__ */ (0,
|
|
41989
|
-
/* @__PURE__ */ (0,
|
|
42620
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
42621
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: " Navigation" }),
|
|
42622
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
41990
42623
|
" ",
|
|
41991
42624
|
import_chalk10.default.cyan("\u2191 k"),
|
|
41992
42625
|
" ",
|
|
41993
42626
|
import_chalk10.default.dim("Move up")
|
|
41994
42627
|
] }),
|
|
41995
|
-
/* @__PURE__ */ (0,
|
|
42628
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
41996
42629
|
" ",
|
|
41997
42630
|
import_chalk10.default.cyan("\u2193 j"),
|
|
41998
42631
|
" ",
|
|
41999
42632
|
import_chalk10.default.dim("Move down")
|
|
42000
42633
|
] }),
|
|
42001
|
-
/* @__PURE__ */ (0,
|
|
42634
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42002
42635
|
" ",
|
|
42003
42636
|
import_chalk10.default.cyan("g"),
|
|
42004
42637
|
" ",
|
|
42005
42638
|
import_chalk10.default.dim("Jump to top")
|
|
42006
42639
|
] }),
|
|
42007
|
-
/* @__PURE__ */ (0,
|
|
42640
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42008
42641
|
" ",
|
|
42009
42642
|
import_chalk10.default.cyan("G"),
|
|
42010
42643
|
" ",
|
|
42011
42644
|
import_chalk10.default.dim("Jump to bottom")
|
|
42012
42645
|
] }),
|
|
42013
|
-
!isDetail && /* @__PURE__ */ (0,
|
|
42646
|
+
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42014
42647
|
" ",
|
|
42015
42648
|
import_chalk10.default.cyan("PgUp"),
|
|
42016
42649
|
" ",
|
|
42017
42650
|
import_chalk10.default.dim("Page up")
|
|
42018
42651
|
] }),
|
|
42019
|
-
!isDetail && /* @__PURE__ */ (0,
|
|
42652
|
+
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42020
42653
|
" ",
|
|
42021
42654
|
import_chalk10.default.cyan("PgDn"),
|
|
42022
42655
|
" ",
|
|
42023
42656
|
import_chalk10.default.dim("Page down")
|
|
42024
42657
|
] }),
|
|
42025
|
-
/* @__PURE__ */ (0,
|
|
42026
|
-
/* @__PURE__ */ (0,
|
|
42027
|
-
!isDetail && /* @__PURE__ */ (0,
|
|
42658
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
42659
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: " Actions" }),
|
|
42660
|
+
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42028
42661
|
" ",
|
|
42029
42662
|
import_chalk10.default.cyan("\u23CE"),
|
|
42030
42663
|
" ",
|
|
42031
42664
|
import_chalk10.default.dim("Toggle summary")
|
|
42032
42665
|
] }),
|
|
42033
|
-
/* @__PURE__ */ (0,
|
|
42666
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42667
|
+
" ",
|
|
42668
|
+
import_chalk10.default.cyan("space"),
|
|
42034
42669
|
" ",
|
|
42035
|
-
import_chalk10.default.cyan("e"),
|
|
42036
|
-
" ",
|
|
42037
42670
|
import_chalk10.default.dim(isDetail ? "Back to list" : "Open detail view")
|
|
42038
42671
|
] }),
|
|
42039
|
-
!isDetail && /* @__PURE__ */ (0,
|
|
42672
|
+
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42040
42673
|
" ",
|
|
42041
42674
|
import_chalk10.default.cyan("/"),
|
|
42042
42675
|
" ",
|
|
42043
42676
|
import_chalk10.default.dim("Search packages")
|
|
42044
42677
|
] }),
|
|
42045
|
-
!isDetail && onBack && /* @__PURE__ */ (0,
|
|
42678
|
+
!isDetail && onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42046
42679
|
" ",
|
|
42047
42680
|
import_chalk10.default.cyan("b"),
|
|
42048
42681
|
" ",
|
|
42049
42682
|
import_chalk10.default.dim("Back to project selector")
|
|
42050
42683
|
] }),
|
|
42051
|
-
/* @__PURE__ */ (0,
|
|
42684
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42052
42685
|
" ",
|
|
42053
42686
|
import_chalk10.default.cyan("q"),
|
|
42054
42687
|
" ",
|
|
42055
42688
|
import_chalk10.default.dim("Quit")
|
|
42056
42689
|
] }),
|
|
42057
|
-
/* @__PURE__ */ (0,
|
|
42058
|
-
/* @__PURE__ */ (0,
|
|
42690
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
42691
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42059
42692
|
" Press ",
|
|
42060
42693
|
import_chalk10.default.bold.cyan("?"),
|
|
42061
42694
|
" or ",
|
|
@@ -42073,13 +42706,13 @@ var init_InteractiveResultsView = __esm({
|
|
|
42073
42706
|
setDetailPane(null);
|
|
42074
42707
|
} else {
|
|
42075
42708
|
const dpRep = dpGroup.packages[0];
|
|
42076
|
-
const { color: dpColor } = actionBadge3(dpRep.score
|
|
42709
|
+
const { color: dpColor } = actionBadge3(dpRep.score);
|
|
42077
42710
|
const dpScroll = detailPane.scroll;
|
|
42078
42711
|
const dpAbove = dpScroll;
|
|
42079
42712
|
const dpBelow = Math.max(0, detailLines.length - dpScroll - detailContentRows);
|
|
42080
42713
|
const dpVisible = detailLines.slice(dpScroll, dpScroll + detailContentRows);
|
|
42081
|
-
return /* @__PURE__ */ (0,
|
|
42082
|
-
/* @__PURE__ */ (0,
|
|
42714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
42715
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
42083
42716
|
ScoreHeader,
|
|
42084
42717
|
{
|
|
42085
42718
|
score: result.score,
|
|
@@ -42090,7 +42723,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42090
42723
|
severityCounts
|
|
42091
42724
|
}
|
|
42092
42725
|
),
|
|
42093
|
-
/* @__PURE__ */ (0,
|
|
42726
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
42094
42727
|
Box_default,
|
|
42095
42728
|
{
|
|
42096
42729
|
flexDirection: "column",
|
|
@@ -42100,18 +42733,21 @@ var init_InteractiveResultsView = __esm({
|
|
|
42100
42733
|
paddingRight: 1,
|
|
42101
42734
|
width: "100%",
|
|
42102
42735
|
children: [
|
|
42103
|
-
/* @__PURE__ */ (0,
|
|
42104
|
-
/* @__PURE__ */ (0,
|
|
42105
|
-
|
|
42736
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
42737
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
42738
|
+
groupNames(dpGroup),
|
|
42739
|
+
dpRep.license ? import_chalk10.default.dim(" \xB7 ") + (dpRep.license.riskCategory === "permissive" ? import_chalk10.default.green(dpRep.license.spdx ?? dpRep.license.raw ?? "") : dpRep.license.riskCategory === "no-license" || dpRep.license.riskCategory === "network-copyleft" ? import_chalk10.default.red(dpRep.license.spdx ?? dpRep.license.raw ?? "No license") : import_chalk10.default.yellow(dpRep.license.spdx ?? dpRep.license.raw ?? "")) : ""
|
|
42740
|
+
] }),
|
|
42741
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: dpColor(`score ${dpRep.score}`) })
|
|
42106
42742
|
] }),
|
|
42107
|
-
dpAbove > 0 && /* @__PURE__ */ (0,
|
|
42743
|
+
dpAbove > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42108
42744
|
import_chalk10.default.cyan(" \u2191"),
|
|
42109
42745
|
" ",
|
|
42110
42746
|
dpAbove,
|
|
42111
42747
|
" more above"
|
|
42112
42748
|
] }),
|
|
42113
|
-
/* @__PURE__ */ (0,
|
|
42114
|
-
dpBelow > 0 && /* @__PURE__ */ (0,
|
|
42749
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", marginLeft: 2, children: dpVisible }),
|
|
42750
|
+
dpBelow > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42115
42751
|
import_chalk10.default.cyan(" \u2193"),
|
|
42116
42752
|
" ",
|
|
42117
42753
|
dpBelow,
|
|
@@ -42120,7 +42756,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42120
42756
|
]
|
|
42121
42757
|
}
|
|
42122
42758
|
),
|
|
42123
|
-
/* @__PURE__ */ (0,
|
|
42759
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
42124
42760
|
Box_default,
|
|
42125
42761
|
{
|
|
42126
42762
|
flexDirection: "column",
|
|
@@ -42130,36 +42766,31 @@ var init_InteractiveResultsView = __esm({
|
|
|
42130
42766
|
paddingRight: 1,
|
|
42131
42767
|
width: "100%",
|
|
42132
42768
|
children: [
|
|
42133
|
-
clean.length > 0 && /* @__PURE__ */ (0,
|
|
42769
|
+
clean.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42134
42770
|
import_chalk10.default.green("\u2713"),
|
|
42135
42771
|
" ",
|
|
42136
42772
|
import_chalk10.default.green.bold(String(clean.length)),
|
|
42137
42773
|
" ",
|
|
42138
42774
|
import_chalk10.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`)
|
|
42139
42775
|
] }),
|
|
42140
|
-
/* @__PURE__ */ (0,
|
|
42141
|
-
/* @__PURE__ */ (0,
|
|
42776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
42777
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42142
42778
|
(durationMs / 1e3).toFixed(1),
|
|
42143
42779
|
"s"
|
|
42144
42780
|
] }),
|
|
42145
|
-
result.trialScansRemaining !== void 0 && /* @__PURE__ */ (0,
|
|
42146
|
-
result.trialScansRemaining,
|
|
42147
|
-
" free scan",
|
|
42148
|
-
result.trialScansRemaining !== 1 ? "s" : "",
|
|
42149
|
-
" remaining"
|
|
42150
|
-
] })
|
|
42781
|
+
result.trialScansRemaining !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "Free tier \xB7 dg login for finding details" })
|
|
42151
42782
|
] })
|
|
42152
42783
|
]
|
|
42153
42784
|
}
|
|
42154
42785
|
),
|
|
42155
|
-
/* @__PURE__ */ (0,
|
|
42156
|
-
/* @__PURE__ */ (0,
|
|
42786
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk10.default.dim("\u2500".repeat(Math.min(60, termCols - 4))) }),
|
|
42787
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42157
42788
|
" ",
|
|
42158
42789
|
import_chalk10.default.bold.cyan("\u2191\u2193"),
|
|
42159
42790
|
" ",
|
|
42160
42791
|
import_chalk10.default.dim("scroll"),
|
|
42161
42792
|
" ",
|
|
42162
|
-
import_chalk10.default.bold.cyan("
|
|
42793
|
+
import_chalk10.default.bold.cyan("space"),
|
|
42163
42794
|
" ",
|
|
42164
42795
|
import_chalk10.default.dim("back"),
|
|
42165
42796
|
" ",
|
|
@@ -42170,8 +42801,8 @@ var init_InteractiveResultsView = __esm({
|
|
|
42170
42801
|
] });
|
|
42171
42802
|
}
|
|
42172
42803
|
}
|
|
42173
|
-
return /* @__PURE__ */ (0,
|
|
42174
|
-
/* @__PURE__ */ (0,
|
|
42804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
42805
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
42175
42806
|
ScoreHeader,
|
|
42176
42807
|
{
|
|
42177
42808
|
score: result.score,
|
|
@@ -42182,7 +42813,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42182
42813
|
severityCounts
|
|
42183
42814
|
}
|
|
42184
42815
|
),
|
|
42185
|
-
groups.length > 0 && /* @__PURE__ */ (0,
|
|
42816
|
+
groups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
42186
42817
|
Box_default,
|
|
42187
42818
|
{
|
|
42188
42819
|
flexDirection: "column",
|
|
@@ -42192,11 +42823,11 @@ var init_InteractiveResultsView = __esm({
|
|
|
42192
42823
|
paddingRight: 1,
|
|
42193
42824
|
width: "100%",
|
|
42194
42825
|
children: [
|
|
42195
|
-
/* @__PURE__ */ (0,
|
|
42196
|
-
/* @__PURE__ */ (0,
|
|
42197
|
-
/* @__PURE__ */ (0,
|
|
42826
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
42827
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: "Flagged Packages" }),
|
|
42828
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: searchQuery ? `${groups.length} of ${allGroupCount}` : `${clampedCursor + 1}/${groups.length}` })
|
|
42198
42829
|
] }),
|
|
42199
|
-
aboveCount > 0 && /* @__PURE__ */ (0,
|
|
42830
|
+
aboveCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42200
42831
|
import_chalk10.default.cyan(" \u2191"),
|
|
42201
42832
|
" ",
|
|
42202
42833
|
aboveCount,
|
|
@@ -42204,27 +42835,32 @@ var init_InteractiveResultsView = __esm({
|
|
|
42204
42835
|
] }),
|
|
42205
42836
|
visibleGroups.map((group, visIdx) => {
|
|
42206
42837
|
const globalIdx = view.viewport + visIdx;
|
|
42207
|
-
const isCursor = globalIdx ===
|
|
42838
|
+
const isCursor = globalIdx === clampedCursor;
|
|
42208
42839
|
const level = getLevel(globalIdx);
|
|
42209
42840
|
const rep = group.packages[0];
|
|
42210
|
-
const { label, color } = actionBadge3(rep.score
|
|
42841
|
+
const { label, color } = actionBadge3(rep.score);
|
|
42211
42842
|
const names = groupNames(group);
|
|
42212
42843
|
const chevron = level !== null ? "\u25BE" : "\u25B8";
|
|
42213
42844
|
const scoreStr = String(rep.score);
|
|
42214
|
-
|
|
42215
|
-
|
|
42845
|
+
const lcInfo = rep.license;
|
|
42846
|
+
const lcStr = lcInfo ? truncate3(lcInfo.spdx ?? lcInfo.raw ?? "", lcCol - 2) : "";
|
|
42847
|
+
const lcColor = !lcInfo ? import_chalk10.default.dim : lcInfo.riskCategory === "permissive" ? import_chalk10.default.green : lcInfo.riskCategory === "no-license" || lcInfo.riskCategory === "unlicensed" || lcInfo.riskCategory === "network-copyleft" ? import_chalk10.default.red : import_chalk10.default.yellow;
|
|
42848
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
42849
|
+
isCursor ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42216
42850
|
import_chalk10.default.cyan("\u258C"),
|
|
42217
42851
|
` ${chevron} `,
|
|
42218
42852
|
color(pad3(label, 6)),
|
|
42219
42853
|
import_chalk10.default.bold(pad3(truncate3(names, nameCol - 2), nameCol)),
|
|
42854
|
+
lcColor(pad3(lcStr, lcCol)),
|
|
42220
42855
|
color(scoreStr.padStart(3))
|
|
42221
|
-
] }) : /* @__PURE__ */ (0,
|
|
42856
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42222
42857
|
` ${import_chalk10.default.dim(chevron)} `,
|
|
42223
42858
|
color(pad3(label, 6)),
|
|
42224
42859
|
pad3(truncate3(names, nameCol - 2), nameCol),
|
|
42860
|
+
lcColor(pad3(lcStr, lcCol)),
|
|
42225
42861
|
color(scoreStr.padStart(3))
|
|
42226
42862
|
] }),
|
|
42227
|
-
level === "summary" && /* @__PURE__ */ (0,
|
|
42863
|
+
level === "summary" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
42228
42864
|
FindingsSummary,
|
|
42229
42865
|
{
|
|
42230
42866
|
group,
|
|
@@ -42234,7 +42870,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42234
42870
|
)
|
|
42235
42871
|
] }, group.key);
|
|
42236
42872
|
}),
|
|
42237
|
-
belowCount > 0 && /* @__PURE__ */ (0,
|
|
42873
|
+
belowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42238
42874
|
import_chalk10.default.cyan(" \u2193"),
|
|
42239
42875
|
" ",
|
|
42240
42876
|
belowCount,
|
|
@@ -42243,7 +42879,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42243
42879
|
]
|
|
42244
42880
|
}
|
|
42245
42881
|
),
|
|
42246
|
-
/* @__PURE__ */ (0,
|
|
42882
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
42247
42883
|
Box_default,
|
|
42248
42884
|
{
|
|
42249
42885
|
flexDirection: "column",
|
|
@@ -42253,14 +42889,14 @@ var init_InteractiveResultsView = __esm({
|
|
|
42253
42889
|
paddingRight: 1,
|
|
42254
42890
|
width: "100%",
|
|
42255
42891
|
children: [
|
|
42256
|
-
clean.length > 0 && /* @__PURE__ */ (0,
|
|
42892
|
+
clean.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42257
42893
|
import_chalk10.default.green("\u2713"),
|
|
42258
42894
|
" ",
|
|
42259
42895
|
import_chalk10.default.green.bold(String(clean.length)),
|
|
42260
42896
|
" ",
|
|
42261
42897
|
import_chalk10.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`)
|
|
42262
42898
|
] }),
|
|
42263
|
-
discoveredTotal !== void 0 && discoveredTotal > total && /* @__PURE__ */ (0,
|
|
42899
|
+
discoveredTotal !== void 0 && discoveredTotal > total && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42264
42900
|
"Scanned ",
|
|
42265
42901
|
total,
|
|
42266
42902
|
" of ",
|
|
@@ -42268,23 +42904,18 @@ var init_InteractiveResultsView = __esm({
|
|
|
42268
42904
|
" packages ",
|
|
42269
42905
|
import_chalk10.default.dim("\u2014 dg login for full scans")
|
|
42270
42906
|
] }),
|
|
42271
|
-
/* @__PURE__ */ (0,
|
|
42272
|
-
/* @__PURE__ */ (0,
|
|
42907
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
42908
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42273
42909
|
(durationMs / 1e3).toFixed(1),
|
|
42274
42910
|
"s"
|
|
42275
42911
|
] }),
|
|
42276
|
-
result.trialScansRemaining !== void 0 && /* @__PURE__ */ (0,
|
|
42277
|
-
result.trialScansRemaining,
|
|
42278
|
-
" free scan",
|
|
42279
|
-
result.trialScansRemaining !== 1 ? "s" : "",
|
|
42280
|
-
" remaining"
|
|
42281
|
-
] })
|
|
42912
|
+
result.trialScansRemaining !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "Free tier \xB7 dg login for finding details" })
|
|
42282
42913
|
] })
|
|
42283
42914
|
]
|
|
42284
42915
|
}
|
|
42285
42916
|
),
|
|
42286
|
-
/* @__PURE__ */ (0,
|
|
42287
|
-
searchMode ? /* @__PURE__ */ (0,
|
|
42917
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk10.default.dim("\u2500".repeat(Math.min(60, termCols - 4))) }),
|
|
42918
|
+
searchMode ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42288
42919
|
" ",
|
|
42289
42920
|
import_chalk10.default.bold.cyan("/"),
|
|
42290
42921
|
" ",
|
|
@@ -42292,9 +42923,9 @@ var init_InteractiveResultsView = __esm({
|
|
|
42292
42923
|
import_chalk10.default.cyan("\u2588"),
|
|
42293
42924
|
" ",
|
|
42294
42925
|
import_chalk10.default.dim("Esc clear")
|
|
42295
|
-
] }) : /* @__PURE__ */ (0,
|
|
42926
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42296
42927
|
" ",
|
|
42297
|
-
groups.length > 0 ? /* @__PURE__ */ (0,
|
|
42928
|
+
groups.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
42298
42929
|
import_chalk10.default.bold.cyan("\u2191\u2193"),
|
|
42299
42930
|
" ",
|
|
42300
42931
|
import_chalk10.default.dim("navigate"),
|
|
@@ -42303,7 +42934,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42303
42934
|
" ",
|
|
42304
42935
|
import_chalk10.default.dim("toggle"),
|
|
42305
42936
|
" ",
|
|
42306
|
-
import_chalk10.default.bold.cyan("
|
|
42937
|
+
import_chalk10.default.bold.cyan("space"),
|
|
42307
42938
|
" ",
|
|
42308
42939
|
import_chalk10.default.dim("detail"),
|
|
42309
42940
|
" ",
|
|
@@ -42315,7 +42946,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42315
42946
|
" ",
|
|
42316
42947
|
import_chalk10.default.dim("help"),
|
|
42317
42948
|
" ",
|
|
42318
|
-
onBack && /* @__PURE__ */ (0,
|
|
42949
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
42319
42950
|
import_chalk10.default.bold.cyan("b"),
|
|
42320
42951
|
" ",
|
|
42321
42952
|
import_chalk10.default.dim("back"),
|
|
@@ -42324,7 +42955,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42324
42955
|
import_chalk10.default.bold.cyan("q"),
|
|
42325
42956
|
" ",
|
|
42326
42957
|
import_chalk10.default.dim("quit")
|
|
42327
|
-
] }) : /* @__PURE__ */ (0,
|
|
42958
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
42328
42959
|
"Press ",
|
|
42329
42960
|
import_chalk10.default.bold.cyan("q"),
|
|
42330
42961
|
" or ",
|
|
@@ -42341,16 +42972,28 @@ var init_InteractiveResultsView = __esm({
|
|
|
42341
42972
|
pipe: import_chalk10.default.dim("\u2502"),
|
|
42342
42973
|
blank: " "
|
|
42343
42974
|
};
|
|
42975
|
+
LICENSE_DESCRIPTIONS = {
|
|
42976
|
+
"permissive": "Permissive \u2014 free to use, modify, and distribute. Include the copyright notice.",
|
|
42977
|
+
"weak-copyleft": "Weak copyleft \u2014 changes to this library must be shared, but your code stays private.",
|
|
42978
|
+
"strong-copyleft": "Strong copyleft \u2014 your entire project must be open-sourced under the same license.",
|
|
42979
|
+
"network-copyleft": "Network copyleft \u2014 even SaaS/server use requires releasing your source code.",
|
|
42980
|
+
"no-license": "No license found \u2014 legally all rights reserved. Use may require permission from the author.",
|
|
42981
|
+
"unlicensed": "Explicitly unlicensed \u2014 proprietary software. A commercial agreement is required.",
|
|
42982
|
+
"unknown": "Unrecognized license \u2014 have your legal team review before using.",
|
|
42983
|
+
"deferred": "License declared in a file \u2014 check the LICENSE file in the package."
|
|
42984
|
+
};
|
|
42344
42985
|
FindingsSummary = ({ group, maxWidth, maxLines }) => {
|
|
42345
42986
|
const rep = group.packages[0];
|
|
42346
42987
|
const visibleFindings = rep.findings.filter((f) => f.severity > 1 || f.critical).sort((a, b) => b.severity - a.severity);
|
|
42347
42988
|
const hasAffects = group.packages.length > 3;
|
|
42348
42989
|
const allLines = [];
|
|
42990
|
+
const lcLine = licenseLine(rep);
|
|
42991
|
+
if (lcLine) allLines.push(lcLine);
|
|
42349
42992
|
if (visibleFindings.length === 0 && rep.score > 0) {
|
|
42350
42993
|
const reasons = rep.reasons ?? [];
|
|
42351
42994
|
for (let i = 0; i < reasons.length; i++) {
|
|
42352
42995
|
allLines.push(
|
|
42353
|
-
/* @__PURE__ */ (0,
|
|
42996
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42354
42997
|
i < reasons.length - 1 || hasAffects ? T.branch : T.branch,
|
|
42355
42998
|
" ",
|
|
42356
42999
|
truncate3(reasons[i], maxWidth - 8)
|
|
@@ -42358,7 +43001,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42358
43001
|
);
|
|
42359
43002
|
}
|
|
42360
43003
|
allLines.push(
|
|
42361
|
-
/* @__PURE__ */ (0,
|
|
43004
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42362
43005
|
import_chalk10.default.yellow(" \u2192"),
|
|
42363
43006
|
" ",
|
|
42364
43007
|
import_chalk10.default.yellow("Upgrade to Pro"),
|
|
@@ -42371,10 +43014,10 @@ var init_InteractiveResultsView = __esm({
|
|
|
42371
43014
|
const f = visibleFindings[idx];
|
|
42372
43015
|
const isLast = !hasAffects && idx === visibleFindings.length - 1;
|
|
42373
43016
|
const connector = isLast ? T.last : T.branch;
|
|
42374
|
-
const sevLabel =
|
|
43017
|
+
const sevLabel = SEVERITY_LABELS2[f.severity] ?? "INFO";
|
|
42375
43018
|
const sevColor = SEVERITY_COLORS[f.severity] ?? SEVERITY_COLORS[1];
|
|
42376
43019
|
allLines.push(
|
|
42377
|
-
/* @__PURE__ */ (0,
|
|
43020
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
42378
43021
|
connector,
|
|
42379
43022
|
" ",
|
|
42380
43023
|
sevColor(pad3(sevLabel, 5)),
|
|
@@ -42385,7 +43028,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
42385
43028
|
}
|
|
42386
43029
|
if (hasAffects) {
|
|
42387
43030
|
allLines.push(
|
|
42388
|
-
/* @__PURE__ */ (0,
|
|
43031
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
42389
43032
|
T.last,
|
|
42390
43033
|
" ",
|
|
42391
43034
|
truncate3(affectsLine(group), maxWidth - 8)
|
|
@@ -42393,23 +43036,24 @@ var init_InteractiveResultsView = __esm({
|
|
|
42393
43036
|
);
|
|
42394
43037
|
}
|
|
42395
43038
|
const linesToShow = maxLines !== void 0 ? allLines.slice(0, maxLines) : allLines;
|
|
42396
|
-
return /* @__PURE__ */ (0,
|
|
43039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", marginLeft: 5, children: linesToShow });
|
|
42397
43040
|
};
|
|
42398
43041
|
}
|
|
42399
43042
|
});
|
|
42400
43043
|
|
|
42401
43044
|
// src/ui/components/ProjectSelector.tsx
|
|
42402
|
-
var
|
|
43045
|
+
var import_react34, import_chalk11, import_jsx_runtime12, ProjectSelector;
|
|
42403
43046
|
var init_ProjectSelector = __esm({
|
|
42404
43047
|
async "src/ui/components/ProjectSelector.tsx"() {
|
|
42405
43048
|
"use strict";
|
|
42406
|
-
|
|
43049
|
+
import_react34 = __toESM(require_react());
|
|
42407
43050
|
await init_build2();
|
|
42408
43051
|
import_chalk11 = __toESM(require_source());
|
|
42409
|
-
|
|
43052
|
+
init_sanitize();
|
|
43053
|
+
import_jsx_runtime12 = __toESM(require_jsx_runtime());
|
|
42410
43054
|
ProjectSelector = ({ projects, onConfirm, onCancel }) => {
|
|
42411
|
-
const [cursor, setCursor] = (0,
|
|
42412
|
-
const [selected, setSelected] = (0,
|
|
43055
|
+
const [cursor, setCursor] = (0, import_react34.useState)(0);
|
|
43056
|
+
const [selected, setSelected] = (0, import_react34.useState)(() => new Set(projects.map((_, i) => i)));
|
|
42413
43057
|
use_input_default((input, key) => {
|
|
42414
43058
|
if (key.upArrow) {
|
|
42415
43059
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -42435,30 +43079,30 @@ var init_ProjectSelector = __esm({
|
|
|
42435
43079
|
}
|
|
42436
43080
|
});
|
|
42437
43081
|
const ecosystemLabel = (eco) => eco === "npm" ? import_chalk11.default.magenta("npm") : import_chalk11.default.blue("pip");
|
|
42438
|
-
return /* @__PURE__ */ (0,
|
|
42439
|
-
/* @__PURE__ */ (0,
|
|
43082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
|
|
43083
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
|
|
42440
43084
|
import_chalk11.default.cyan("\u25C6"),
|
|
42441
43085
|
" ",
|
|
42442
43086
|
import_chalk11.default.bold("Dependency Guardian")
|
|
42443
43087
|
] }),
|
|
42444
|
-
/* @__PURE__ */ (0,
|
|
42445
|
-
/* @__PURE__ */ (0,
|
|
43088
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
43089
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, children: [
|
|
42446
43090
|
"Found ",
|
|
42447
43091
|
projects.length,
|
|
42448
43092
|
" project",
|
|
42449
43093
|
projects.length !== 1 ? "s" : ""
|
|
42450
43094
|
] }),
|
|
42451
|
-
/* @__PURE__ */ (0,
|
|
43095
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
42452
43096
|
projects.map((proj, i) => {
|
|
42453
43097
|
const isCursor = i === cursor;
|
|
42454
43098
|
const isSelected = selected.has(i);
|
|
42455
43099
|
const prefix = isCursor ? import_chalk11.default.cyan("\u258C") : " ";
|
|
42456
43100
|
const check = isSelected ? import_chalk11.default.green("\u25C9") : import_chalk11.default.dim("\u25CB");
|
|
42457
|
-
return /* @__PURE__ */ (0,
|
|
43101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
|
|
42458
43102
|
prefix,
|
|
42459
43103
|
check,
|
|
42460
43104
|
" ",
|
|
42461
|
-
proj.relativePath.padEnd(40),
|
|
43105
|
+
sanitize(proj.relativePath).padEnd(40),
|
|
42462
43106
|
" ",
|
|
42463
43107
|
ecosystemLabel(proj.ecosystem).padEnd(5),
|
|
42464
43108
|
" ",
|
|
@@ -42466,10 +43110,10 @@ var init_ProjectSelector = __esm({
|
|
|
42466
43110
|
" packages"
|
|
42467
43111
|
] }, i);
|
|
42468
43112
|
}),
|
|
42469
|
-
/* @__PURE__ */ (0,
|
|
42470
|
-
/* @__PURE__ */ (0,
|
|
42471
|
-
/* @__PURE__ */ (0,
|
|
42472
|
-
/* @__PURE__ */ (0,
|
|
43113
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
43114
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: selected.size === 0 ? import_chalk11.default.yellow("Select at least 1 project to scan") : `${selected.size} of ${projects.length} selected` }),
|
|
43115
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "" }),
|
|
43116
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
|
|
42473
43117
|
import_chalk11.default.bold.cyan("space"),
|
|
42474
43118
|
" ",
|
|
42475
43119
|
import_chalk11.default.dim("toggle"),
|
|
@@ -42478,9 +43122,9 @@ var init_ProjectSelector = __esm({
|
|
|
42478
43122
|
" ",
|
|
42479
43123
|
import_chalk11.default.dim("all"),
|
|
42480
43124
|
" ",
|
|
42481
|
-
import_chalk11.default.bold.
|
|
43125
|
+
import_chalk11.default.bold.hex("#FFD700")("\u23CE"),
|
|
42482
43126
|
" ",
|
|
42483
|
-
import_chalk11.default.
|
|
43127
|
+
import_chalk11.default.bold.hex("#FFD700")("scan"),
|
|
42484
43128
|
" ",
|
|
42485
43129
|
import_chalk11.default.bold.cyan("q"),
|
|
42486
43130
|
" ",
|
|
@@ -42496,11 +43140,11 @@ var App_exports = {};
|
|
|
42496
43140
|
__export(App_exports, {
|
|
42497
43141
|
App: () => App2
|
|
42498
43142
|
});
|
|
42499
|
-
var
|
|
43143
|
+
var import_react35, import_jsx_runtime13, App2;
|
|
42500
43144
|
var init_App2 = __esm({
|
|
42501
43145
|
async "src/ui/App.tsx"() {
|
|
42502
43146
|
"use strict";
|
|
42503
|
-
|
|
43147
|
+
import_react35 = __toESM(require_react());
|
|
42504
43148
|
await init_build2();
|
|
42505
43149
|
init_useScan();
|
|
42506
43150
|
await init_Spinner();
|
|
@@ -42509,17 +43153,19 @@ var init_App2 = __esm({
|
|
|
42509
43153
|
await init_ErrorView();
|
|
42510
43154
|
await init_ProjectSelector();
|
|
42511
43155
|
await init_useTerminalSize();
|
|
42512
|
-
|
|
43156
|
+
import_jsx_runtime13 = __toESM(require_jsx_runtime());
|
|
42513
43157
|
App2 = ({ config }) => {
|
|
42514
43158
|
const { state, scanSelectedProjects, restartSelection } = useScan(config);
|
|
42515
43159
|
const { exit } = use_app_default();
|
|
42516
43160
|
useTerminalSize();
|
|
42517
|
-
const prevPhaseRef = (0,
|
|
42518
|
-
const altScreenActiveRef = (0,
|
|
42519
|
-
(0,
|
|
43161
|
+
const prevPhaseRef = (0, import_react35.useRef)(state.phase);
|
|
43162
|
+
const altScreenActiveRef = (0, import_react35.useRef)(false);
|
|
43163
|
+
(0, import_react35.useEffect)(() => {
|
|
42520
43164
|
if (!process.stdout.isTTY) return;
|
|
42521
43165
|
process.stdout.write("\x1B[?1049h");
|
|
42522
43166
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
43167
|
+
process.stdout.write("\x1B[?1003l");
|
|
43168
|
+
process.stdout.write("\x1B[?1000l");
|
|
42523
43169
|
altScreenActiveRef.current = true;
|
|
42524
43170
|
return () => {
|
|
42525
43171
|
if (altScreenActiveRef.current) {
|
|
@@ -42529,20 +43175,20 @@ var init_App2 = __esm({
|
|
|
42529
43175
|
process.stdout.write("\x1B[?25h");
|
|
42530
43176
|
};
|
|
42531
43177
|
}, []);
|
|
42532
|
-
(0,
|
|
43178
|
+
(0, import_react35.useEffect)(() => {
|
|
42533
43179
|
if (prevPhaseRef.current !== state.phase && process.stdout.isTTY) {
|
|
42534
43180
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
42535
43181
|
}
|
|
42536
43182
|
prevPhaseRef.current = state.phase;
|
|
42537
43183
|
}, [state.phase]);
|
|
42538
|
-
const leaveAltScreen = (0,
|
|
43184
|
+
const leaveAltScreen = (0, import_react35.useCallback)(() => {
|
|
42539
43185
|
if (altScreenActiveRef.current && process.stdout.isTTY) {
|
|
42540
43186
|
process.stdout.write("\x1B[?1049l");
|
|
42541
43187
|
altScreenActiveRef.current = false;
|
|
42542
43188
|
}
|
|
42543
43189
|
process.stdout.write("\x1B[?25h");
|
|
42544
43190
|
}, []);
|
|
42545
|
-
const handleResultsExit = (0,
|
|
43191
|
+
const handleResultsExit = (0, import_react35.useCallback)(() => {
|
|
42546
43192
|
if (state.phase === "results") {
|
|
42547
43193
|
const { result } = state;
|
|
42548
43194
|
if (result.action === "block" && config.mode === "block") {
|
|
@@ -42556,13 +43202,13 @@ var init_App2 = __esm({
|
|
|
42556
43202
|
leaveAltScreen();
|
|
42557
43203
|
exit();
|
|
42558
43204
|
}, [state, config, exit, leaveAltScreen]);
|
|
42559
|
-
const exitWithMessage = (0,
|
|
43205
|
+
const exitWithMessage = (0, import_react35.useCallback)((message, exitCode) => {
|
|
42560
43206
|
process.exitCode = exitCode;
|
|
42561
43207
|
leaveAltScreen();
|
|
42562
43208
|
process.stderr.write(message);
|
|
42563
43209
|
return setTimeout(() => exit(), 0);
|
|
42564
43210
|
}, [exit, leaveAltScreen]);
|
|
42565
|
-
(0,
|
|
43211
|
+
(0, import_react35.useEffect)(() => {
|
|
42566
43212
|
if (state.phase === "empty") {
|
|
42567
43213
|
const timer = exitWithMessage(`${state.message}
|
|
42568
43214
|
`, 0);
|
|
@@ -42574,10 +43220,15 @@ var init_App2 = __esm({
|
|
|
42574
43220
|
return () => clearTimeout(timer);
|
|
42575
43221
|
}
|
|
42576
43222
|
if (state.phase === "trial_exhausted") {
|
|
42577
|
-
|
|
42578
|
-
|
|
42579
|
-
|
|
42580
|
-
|
|
43223
|
+
let msg = "Free trial scans used up. Run `dg login` to create a free account and continue scanning.\n";
|
|
43224
|
+
try {
|
|
43225
|
+
const { getStoredApiKey: getStoredApiKey2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
43226
|
+
if (getStoredApiKey2()) {
|
|
43227
|
+
msg = "Your API key may be invalid or expired. Run `dg logout` then `dg login` to re-authenticate.\n";
|
|
43228
|
+
}
|
|
43229
|
+
} catch {
|
|
43230
|
+
}
|
|
43231
|
+
const timer = exitWithMessage(msg, 1);
|
|
42581
43232
|
return () => clearTimeout(timer);
|
|
42582
43233
|
}
|
|
42583
43234
|
}, [state, exitWithMessage]);
|
|
@@ -42593,9 +43244,9 @@ var init_App2 = __esm({
|
|
|
42593
43244
|
const content = (() => {
|
|
42594
43245
|
switch (state.phase) {
|
|
42595
43246
|
case "discovering":
|
|
42596
|
-
return /* @__PURE__ */ (0,
|
|
43247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Spinner2, { label: `Searching for dependencies in ${process.cwd()} ...` });
|
|
42597
43248
|
case "selecting":
|
|
42598
|
-
return /* @__PURE__ */ (0,
|
|
43249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
42599
43250
|
ProjectSelector,
|
|
42600
43251
|
{
|
|
42601
43252
|
projects: state.projects,
|
|
@@ -42608,7 +43259,7 @@ var init_App2 = __esm({
|
|
|
42608
43259
|
}
|
|
42609
43260
|
);
|
|
42610
43261
|
case "scanning":
|
|
42611
|
-
return /* @__PURE__ */ (0,
|
|
43262
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
42612
43263
|
ProgressBar,
|
|
42613
43264
|
{
|
|
42614
43265
|
value: state.done,
|
|
@@ -42617,7 +43268,7 @@ var init_App2 = __esm({
|
|
|
42617
43268
|
}
|
|
42618
43269
|
);
|
|
42619
43270
|
case "results":
|
|
42620
|
-
return /* @__PURE__ */ (0,
|
|
43271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
42621
43272
|
InteractiveResultsView,
|
|
42622
43273
|
{
|
|
42623
43274
|
result: state.result,
|
|
@@ -42629,21 +43280,37 @@ var init_App2 = __esm({
|
|
|
42629
43280
|
}
|
|
42630
43281
|
);
|
|
42631
43282
|
case "empty":
|
|
42632
|
-
return /* @__PURE__ */ (0,
|
|
43283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: state.message });
|
|
42633
43284
|
case "error":
|
|
42634
|
-
return /* @__PURE__ */ (0,
|
|
42635
|
-
case "trial_exhausted":
|
|
42636
|
-
|
|
42637
|
-
|
|
42638
|
-
|
|
43285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ErrorView, { error: state.error });
|
|
43286
|
+
case "trial_exhausted": {
|
|
43287
|
+
let hasKey = false;
|
|
43288
|
+
try {
|
|
43289
|
+
const { getStoredApiKey: getStoredApiKey2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
43290
|
+
hasKey = !!getStoredApiKey2();
|
|
43291
|
+
} catch {
|
|
43292
|
+
}
|
|
43293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, children: hasKey ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
43294
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "yellow", bold: true, children: "Your API key may be invalid or expired." }),
|
|
43295
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
43296
|
+
"Run ",
|
|
43297
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "cyan", bold: true, children: "dg logout" }),
|
|
43298
|
+
" then ",
|
|
43299
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
43300
|
+
" to re-authenticate."
|
|
43301
|
+
] })
|
|
43302
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
43303
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "yellow", bold: true, children: "Free trial scans used up." }),
|
|
43304
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
42639
43305
|
"Run ",
|
|
42640
|
-
/* @__PURE__ */ (0,
|
|
43306
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "cyan", bold: true, children: "dg login" }),
|
|
42641
43307
|
" to create a free account and continue scanning."
|
|
42642
43308
|
] })
|
|
42643
|
-
] });
|
|
43309
|
+
] }) });
|
|
43310
|
+
}
|
|
42644
43311
|
}
|
|
42645
43312
|
})();
|
|
42646
|
-
return /* @__PURE__ */ (0,
|
|
43313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", children: content });
|
|
42647
43314
|
};
|
|
42648
43315
|
}
|
|
42649
43316
|
});
|
|
@@ -42656,7 +43323,7 @@ init_npm_wrapper();
|
|
|
42656
43323
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
42657
43324
|
import { homedir as homedir3 } from "node:os";
|
|
42658
43325
|
import { join as join4 } from "node:path";
|
|
42659
|
-
import { spawn as
|
|
43326
|
+
import { spawn as spawn3, execFileSync } from "node:child_process";
|
|
42660
43327
|
var PKG_NAME = "@westbayberry/dg";
|
|
42661
43328
|
var CACHE_FILE = join4(homedir3(), ".dg-update-check.json");
|
|
42662
43329
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -42709,7 +43376,7 @@ function isNewer(latest, current) {
|
|
|
42709
43376
|
}
|
|
42710
43377
|
function spawnBackgroundUpdate(version) {
|
|
42711
43378
|
try {
|
|
42712
|
-
const child =
|
|
43379
|
+
const child = spawn3("npm", ["install", "-g", `${PKG_NAME}@${version}`], {
|
|
42713
43380
|
detached: true,
|
|
42714
43381
|
stdio: "ignore"
|
|
42715
43382
|
});
|
|
@@ -42755,7 +43422,7 @@ async function runUpdate(currentVersion) {
|
|
|
42755
43422
|
process.stderr.write(chalk10.dim(` Installing ${PKG_NAME}@${latest}...
|
|
42756
43423
|
`));
|
|
42757
43424
|
try {
|
|
42758
|
-
|
|
43425
|
+
execFileSync("npm", ["install", "-g", `${PKG_NAME}@${latest}`], { stdio: "inherit" });
|
|
42759
43426
|
writeCache({ latest, checkedAt: Date.now() });
|
|
42760
43427
|
process.stderr.write(
|
|
42761
43428
|
chalk10.green(`
|
|
@@ -42774,6 +43441,27 @@ async function runUpdate(currentVersion) {
|
|
|
42774
43441
|
|
|
42775
43442
|
// src/bin.ts
|
|
42776
43443
|
var CLI_VERSION = getVersion();
|
|
43444
|
+
function closestCommand(input, commands) {
|
|
43445
|
+
let best = "", bestDist = Infinity;
|
|
43446
|
+
for (const cmd of commands) {
|
|
43447
|
+
const m = input.length, n = cmd.length;
|
|
43448
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1));
|
|
43449
|
+
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
|
43450
|
+
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
|
43451
|
+
for (let i = 1; i <= m; i++)
|
|
43452
|
+
for (let j = 1; j <= n; j++)
|
|
43453
|
+
dp[i][j] = input[i - 1] === cmd[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
43454
|
+
if (dp[m][n] < bestDist) {
|
|
43455
|
+
bestDist = dp[m][n];
|
|
43456
|
+
best = cmd;
|
|
43457
|
+
}
|
|
43458
|
+
}
|
|
43459
|
+
return bestDist <= 3 ? best : null;
|
|
43460
|
+
}
|
|
43461
|
+
process.on("SIGINT", () => {
|
|
43462
|
+
process.stderr.write("\n");
|
|
43463
|
+
process.exit(130);
|
|
43464
|
+
});
|
|
42777
43465
|
var isInteractive = process.stdout.isTTY === true && !process.env.CI && !process.env.NO_COLOR;
|
|
42778
43466
|
async function main() {
|
|
42779
43467
|
const rawCommand = process.argv[2];
|
|
@@ -42794,9 +43482,9 @@ async function main() {
|
|
|
42794
43482
|
if (rawCommand === "login") {
|
|
42795
43483
|
if (isInteractive) {
|
|
42796
43484
|
const { render: render3 } = await init_build2().then(() => build_exports);
|
|
42797
|
-
const
|
|
43485
|
+
const React19 = await Promise.resolve().then(() => __toESM(require_react()));
|
|
42798
43486
|
const { LoginApp: LoginApp2 } = await init_LoginApp().then(() => LoginApp_exports);
|
|
42799
|
-
const { waitUntilExit } = render3(
|
|
43487
|
+
const { waitUntilExit } = render3(React19.createElement(LoginApp2));
|
|
42800
43488
|
await waitUntilExit();
|
|
42801
43489
|
} else {
|
|
42802
43490
|
const { runStaticLogin: runStaticLogin2 } = await Promise.resolve().then(() => (init_static_output(), static_output_exports));
|
|
@@ -42820,12 +43508,29 @@ async function main() {
|
|
|
42820
43508
|
process.stderr.write(chalk10.green(" Logged out.\n"));
|
|
42821
43509
|
return;
|
|
42822
43510
|
}
|
|
42823
|
-
const
|
|
43511
|
+
const KNOWN_COMMANDS = ["scan", "npm", "pip", "wrap", "login", "hook", "update", "logout"];
|
|
43512
|
+
if (rawCommand && !rawCommand.startsWith("-") && !KNOWN_COMMANDS.includes(rawCommand)) {
|
|
43513
|
+
const chalk10 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
43514
|
+
const best = closestCommand(rawCommand, KNOWN_COMMANDS);
|
|
43515
|
+
const hint = best ? ` Did you mean '${best}'?` : "";
|
|
43516
|
+
process.stderr.write(`
|
|
43517
|
+
${chalk10.bold.red("Error:")} Unknown command '${rawCommand}'.${hint}
|
|
43518
|
+
`);
|
|
43519
|
+
process.stderr.write(chalk10.dim(` Run 'dg --help' for available commands.
|
|
43520
|
+
|
|
43521
|
+
`));
|
|
43522
|
+
process.exit(1);
|
|
43523
|
+
}
|
|
43524
|
+
const strictFlags = rawCommand !== "npm" && rawCommand !== "pip";
|
|
43525
|
+
const config = parseConfig(process.argv, strictFlags);
|
|
42824
43526
|
const updatePromise = checkForUpdate(CLI_VERSION).catch(() => null);
|
|
42825
43527
|
if (config.json || !isInteractive) {
|
|
42826
43528
|
if (rawCommand === "npm") {
|
|
42827
43529
|
const { runStaticNpm: runStaticNpm2 } = await Promise.resolve().then(() => (init_static_output(), static_output_exports));
|
|
42828
43530
|
await runStaticNpm2(process.argv.slice(3), config);
|
|
43531
|
+
} else if (rawCommand === "pip") {
|
|
43532
|
+
const { runStaticPip: runStaticPip2 } = await Promise.resolve().then(() => (init_static_output(), static_output_exports));
|
|
43533
|
+
await runStaticPip2(process.argv.slice(3), config);
|
|
42829
43534
|
} else {
|
|
42830
43535
|
const { runStatic: runStatic2 } = await Promise.resolve().then(() => (init_static_output(), static_output_exports));
|
|
42831
43536
|
await runStatic2(config);
|
|
@@ -42838,11 +43543,17 @@ async function main() {
|
|
|
42838
43543
|
return;
|
|
42839
43544
|
}
|
|
42840
43545
|
const { render: render2 } = await init_build2().then(() => build_exports);
|
|
42841
|
-
const
|
|
43546
|
+
const React18 = await Promise.resolve().then(() => __toESM(require_react()));
|
|
42842
43547
|
if (rawCommand === "npm") {
|
|
42843
43548
|
const { NpmWrapperApp: NpmWrapperApp2 } = await init_NpmWrapperApp().then(() => NpmWrapperApp_exports);
|
|
42844
43549
|
const { waitUntilExit } = render2(
|
|
42845
|
-
|
|
43550
|
+
React18.createElement(NpmWrapperApp2, { config, npmArgs: process.argv.slice(3) })
|
|
43551
|
+
);
|
|
43552
|
+
await waitUntilExit();
|
|
43553
|
+
} else if (rawCommand === "pip") {
|
|
43554
|
+
const { PipWrapperApp: PipWrapperApp2 } = await init_PipWrapperApp().then(() => PipWrapperApp_exports);
|
|
43555
|
+
const { waitUntilExit } = render2(
|
|
43556
|
+
React18.createElement(PipWrapperApp2, { config, pipArgs: process.argv.slice(3) })
|
|
42846
43557
|
);
|
|
42847
43558
|
await waitUntilExit();
|
|
42848
43559
|
} else {
|
|
@@ -42853,7 +43564,7 @@ async function main() {
|
|
|
42853
43564
|
}
|
|
42854
43565
|
const { App: App3 } = await init_App2().then(() => App_exports);
|
|
42855
43566
|
const { waitUntilExit } = render2(
|
|
42856
|
-
|
|
43567
|
+
React18.createElement(App3, { config })
|
|
42857
43568
|
);
|
|
42858
43569
|
await waitUntilExit();
|
|
42859
43570
|
}
|
|
@@ -42864,17 +43575,25 @@ async function main() {
|
|
|
42864
43575
|
}
|
|
42865
43576
|
}
|
|
42866
43577
|
main().catch((err) => {
|
|
42867
|
-
|
|
42868
|
-
|
|
42869
|
-
|
|
43578
|
+
if (process.argv.includes("--json")) {
|
|
43579
|
+
process.stdout.write(JSON.stringify({
|
|
43580
|
+
error: true,
|
|
43581
|
+
code: err.statusCode ? "api_error" : "internal_error",
|
|
43582
|
+
message: err.message
|
|
43583
|
+
}, null, 2) + "\n");
|
|
43584
|
+
} else {
|
|
43585
|
+
try {
|
|
43586
|
+
const chalk10 = require_source();
|
|
43587
|
+
process.stderr.write(`
|
|
42870
43588
|
${chalk10.bold.red("Error:")} ${err.message}
|
|
42871
43589
|
|
|
42872
43590
|
`);
|
|
42873
|
-
|
|
42874
|
-
|
|
43591
|
+
} catch {
|
|
43592
|
+
process.stderr.write(`
|
|
42875
43593
|
Error: ${err.message}
|
|
42876
43594
|
|
|
42877
43595
|
`);
|
|
43596
|
+
}
|
|
42878
43597
|
}
|
|
42879
43598
|
process.exit(3);
|
|
42880
43599
|
});
|