@westbayberry/dg 1.1.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +610 -235
- package/dist/postinstall.mjs +38 -13
- package/dist/python-hook/dg_pip_hook.py +15 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -910,15 +910,15 @@ var require_route = __commonJS({
|
|
|
910
910
|
};
|
|
911
911
|
}
|
|
912
912
|
function wrapConversion(toModel, graph) {
|
|
913
|
-
const
|
|
913
|
+
const path = [graph[toModel].parent, toModel];
|
|
914
914
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
915
915
|
let cur = graph[toModel].parent;
|
|
916
916
|
while (graph[cur].parent) {
|
|
917
|
-
|
|
917
|
+
path.unshift(graph[cur].parent);
|
|
918
918
|
fn = link2(conversions[graph[cur].parent][cur], fn);
|
|
919
919
|
cur = graph[cur].parent;
|
|
920
920
|
}
|
|
921
|
-
fn.conversion =
|
|
921
|
+
fn.conversion = path;
|
|
922
922
|
return fn;
|
|
923
923
|
}
|
|
924
924
|
module.exports = function(fromModel) {
|
|
@@ -1590,8 +1590,8 @@ var require_source = __commonJS({
|
|
|
1590
1590
|
// src/telemetry.ts
|
|
1591
1591
|
import { platform, arch } from "node:os";
|
|
1592
1592
|
function telemetryEnabled() {
|
|
1593
|
-
if (process.env.DG_TELEMETRY === "0") return false;
|
|
1594
1593
|
if (process.env.DO_NOT_TRACK === "1") return false;
|
|
1594
|
+
if (process.env.DG_TELEMETRY === "0") return false;
|
|
1595
1595
|
return true;
|
|
1596
1596
|
}
|
|
1597
1597
|
function classifyError(err) {
|
|
@@ -2004,17 +2004,17 @@ function ensureConfigDir() {
|
|
|
2004
2004
|
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
2005
2005
|
}
|
|
2006
2006
|
}
|
|
2007
|
-
function ensureConfigPerms(
|
|
2007
|
+
function ensureConfigPerms(path) {
|
|
2008
2008
|
let st;
|
|
2009
2009
|
try {
|
|
2010
|
-
st = lstatSync(
|
|
2010
|
+
st = lstatSync(path);
|
|
2011
2011
|
} catch {
|
|
2012
2012
|
return;
|
|
2013
2013
|
}
|
|
2014
2014
|
if (!st || typeof st.isSymbolicLink !== "function") return;
|
|
2015
2015
|
if (st.isSymbolicLink()) {
|
|
2016
2016
|
process.stderr.write(
|
|
2017
|
-
`Warning: ${
|
|
2017
|
+
`Warning: ${path} is a symlink; refusing to chmod (would affect the symlink target). Replace with a regular file to enforce 0o600.
|
|
2018
2018
|
`
|
|
2019
2019
|
);
|
|
2020
2020
|
return;
|
|
@@ -2023,12 +2023,12 @@ function ensureConfigPerms(path2) {
|
|
|
2023
2023
|
const mode = (st.mode ?? 384) & 511;
|
|
2024
2024
|
if (mode === 384) return;
|
|
2025
2025
|
process.stderr.write(
|
|
2026
|
-
`Warning: ${
|
|
2026
|
+
`Warning: ${path} has perms 0o${mode.toString(8)} (expected 0o600); re-tightening.
|
|
2027
2027
|
`
|
|
2028
2028
|
);
|
|
2029
2029
|
let fd;
|
|
2030
2030
|
try {
|
|
2031
|
-
fd = openSync(
|
|
2031
|
+
fd = openSync(path, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
2032
2032
|
fchmodSync(fd, 384);
|
|
2033
2033
|
} catch {
|
|
2034
2034
|
} finally {
|
|
@@ -2185,11 +2185,11 @@ async function fetchCliPolicy(opts) {
|
|
|
2185
2185
|
return null;
|
|
2186
2186
|
}
|
|
2187
2187
|
}
|
|
2188
|
-
async function postCliEvent(
|
|
2188
|
+
async function postCliEvent(path, body, apiUrl, apiKey, timeoutMs = 3e3) {
|
|
2189
2189
|
try {
|
|
2190
2190
|
const ctrl = new AbortController();
|
|
2191
2191
|
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
2192
|
-
await globalThis.fetch(`${apiUrl}${
|
|
2192
|
+
await globalThis.fetch(`${apiUrl}${path}`, {
|
|
2193
2193
|
method: "POST",
|
|
2194
2194
|
headers: {
|
|
2195
2195
|
"Content-Type": "application/json",
|
|
@@ -2263,9 +2263,9 @@ function authStatusCachePath() {
|
|
|
2263
2263
|
}
|
|
2264
2264
|
function readCachedAuthStatus() {
|
|
2265
2265
|
try {
|
|
2266
|
-
const
|
|
2267
|
-
if (!existsSync(
|
|
2268
|
-
const raw = readFileSync(
|
|
2266
|
+
const path = authStatusCachePath();
|
|
2267
|
+
if (!existsSync(path)) return null;
|
|
2268
|
+
const raw = readFileSync(path, "utf-8");
|
|
2269
2269
|
const cached = JSON.parse(raw);
|
|
2270
2270
|
if (typeof cached.fetchedAt !== "number") return null;
|
|
2271
2271
|
if (Date.now() - cached.fetchedAt > AUTH_STATUS_TTL_MS) return null;
|
|
@@ -2276,10 +2276,10 @@ function readCachedAuthStatus() {
|
|
|
2276
2276
|
}
|
|
2277
2277
|
function writeCachedAuthStatus(status) {
|
|
2278
2278
|
try {
|
|
2279
|
-
const
|
|
2280
|
-
const dir = dirname(
|
|
2279
|
+
const path = authStatusCachePath();
|
|
2280
|
+
const dir = dirname(path);
|
|
2281
2281
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 448 });
|
|
2282
|
-
writeFileSync(
|
|
2282
|
+
writeFileSync(path, JSON.stringify(status), { mode: 384 });
|
|
2283
2283
|
} catch {
|
|
2284
2284
|
}
|
|
2285
2285
|
}
|
|
@@ -2369,8 +2369,8 @@ async function preflightAuthCheck(apiUrl) {
|
|
|
2369
2369
|
}
|
|
2370
2370
|
function clearAuthStatusCache() {
|
|
2371
2371
|
try {
|
|
2372
|
-
const
|
|
2373
|
-
if (existsSync(
|
|
2372
|
+
const path = authStatusCachePath();
|
|
2373
|
+
if (existsSync(path)) unlinkSync(path);
|
|
2374
2374
|
} catch {
|
|
2375
2375
|
}
|
|
2376
2376
|
}
|
|
@@ -2816,7 +2816,7 @@ var init_config = __esm({
|
|
|
2816
2816
|
DG_DEBUG=1 Enable debug output
|
|
2817
2817
|
DG_QUIET=1 Same as passing --quiet
|
|
2818
2818
|
DG_WORKSPACE Workspace subdirectory to scan
|
|
2819
|
-
DG_TELEMETRY=
|
|
2819
|
+
DG_TELEMETRY=0 Opt out of anonymous crash reports (on by default; DO_NOT_TRACK=1 also opts out)
|
|
2820
2820
|
DG_FORCE_POSTINSTALL=1 Force postinstall to run even outside a TTY
|
|
2821
2821
|
(useful for re-running setup manually)
|
|
2822
2822
|
DG_NO_RC_EDIT=1 Postinstall installs shims but does not edit
|
|
@@ -2865,23 +2865,23 @@ function cacheFile() {
|
|
|
2865
2865
|
return dgCachePath("update-check.json");
|
|
2866
2866
|
}
|
|
2867
2867
|
function readCache() {
|
|
2868
|
-
const
|
|
2868
|
+
const path = cacheFile();
|
|
2869
2869
|
let stat = null;
|
|
2870
2870
|
try {
|
|
2871
|
-
stat = lstatSync2(
|
|
2871
|
+
stat = lstatSync2(path, { throwIfNoEntry: false }) ?? null;
|
|
2872
2872
|
} catch {
|
|
2873
2873
|
return null;
|
|
2874
2874
|
}
|
|
2875
2875
|
if (!stat) return null;
|
|
2876
2876
|
if (!stat.isFile() || stat.size > MAX_CACHE_BYTES) {
|
|
2877
2877
|
try {
|
|
2878
|
-
unlinkSync2(
|
|
2878
|
+
unlinkSync2(path);
|
|
2879
2879
|
} catch {
|
|
2880
2880
|
}
|
|
2881
2881
|
return null;
|
|
2882
2882
|
}
|
|
2883
2883
|
try {
|
|
2884
|
-
const raw = readFileSync3(
|
|
2884
|
+
const raw = readFileSync3(path, "utf-8");
|
|
2885
2885
|
const data = JSON.parse(raw);
|
|
2886
2886
|
if (typeof data.latest === "string" && typeof data.checkedAt === "number") {
|
|
2887
2887
|
return data;
|
|
@@ -2892,14 +2892,14 @@ function readCache() {
|
|
|
2892
2892
|
}
|
|
2893
2893
|
function writeCache(entry) {
|
|
2894
2894
|
try {
|
|
2895
|
-
const
|
|
2896
|
-
const parent = dirname3(
|
|
2895
|
+
const path = cacheFile();
|
|
2896
|
+
const parent = dirname3(path);
|
|
2897
2897
|
if (!existsSync3(parent)) mkdirSync2(parent, { recursive: true, mode: 448 });
|
|
2898
2898
|
const serialized = JSON.stringify(entry);
|
|
2899
2899
|
if (serialized.length > MAX_CACHE_BYTES) return;
|
|
2900
|
-
writeFileSync2(
|
|
2900
|
+
writeFileSync2(path, serialized, { encoding: "utf-8", mode: 384 });
|
|
2901
2901
|
try {
|
|
2902
|
-
chmodSync2(
|
|
2902
|
+
chmodSync2(path, 384);
|
|
2903
2903
|
} catch {
|
|
2904
2904
|
}
|
|
2905
2905
|
} catch {
|
|
@@ -3050,17 +3050,17 @@ function ensureUnderHome(target) {
|
|
|
3050
3050
|
throw new UnsafePathError(`refusing to operate on path outside $HOME: ${target}`, target);
|
|
3051
3051
|
}
|
|
3052
3052
|
}
|
|
3053
|
-
function lstatNoSymlink(
|
|
3053
|
+
function lstatNoSymlink(path) {
|
|
3054
3054
|
let st;
|
|
3055
3055
|
try {
|
|
3056
|
-
st = lstatSync3(
|
|
3056
|
+
st = lstatSync3(path);
|
|
3057
3057
|
} catch (e) {
|
|
3058
3058
|
const code = e.code;
|
|
3059
3059
|
if (code === "ENOENT") return;
|
|
3060
3060
|
throw e;
|
|
3061
3061
|
}
|
|
3062
3062
|
if (st.isSymbolicLink()) {
|
|
3063
|
-
throw new UnsafePathError(`refusing: ${
|
|
3063
|
+
throw new UnsafePathError(`refusing: ${path} is a symlink`, path);
|
|
3064
3064
|
}
|
|
3065
3065
|
}
|
|
3066
3066
|
function safeMkdirRecursive(target, mode = 493) {
|
|
@@ -3090,9 +3090,9 @@ function atomicWriteFile(target, content, mode = 420) {
|
|
|
3090
3090
|
writeFileSync3(tmp, content, { mode });
|
|
3091
3091
|
renameSync(tmp, target);
|
|
3092
3092
|
}
|
|
3093
|
-
function isExecutable(
|
|
3093
|
+
function isExecutable(path) {
|
|
3094
3094
|
try {
|
|
3095
|
-
const st = statSync(
|
|
3095
|
+
const st = statSync(path);
|
|
3096
3096
|
return st.isFile() && (st.mode & 73) !== 0;
|
|
3097
3097
|
} catch {
|
|
3098
3098
|
return false;
|
|
@@ -3117,9 +3117,9 @@ var init_safe_fs = __esm({
|
|
|
3117
3117
|
"src/shims/safe-fs.ts"() {
|
|
3118
3118
|
"use strict";
|
|
3119
3119
|
UnsafePathError = class extends Error {
|
|
3120
|
-
constructor(message,
|
|
3120
|
+
constructor(message, path) {
|
|
3121
3121
|
super(message);
|
|
3122
|
-
this.path =
|
|
3122
|
+
this.path = path;
|
|
3123
3123
|
this.name = "UnsafePathError";
|
|
3124
3124
|
}
|
|
3125
3125
|
};
|
|
@@ -3151,16 +3151,29 @@ var init_templates = __esm({
|
|
|
3151
3151
|
"mamba"
|
|
3152
3152
|
];
|
|
3153
3153
|
UNIX_SHIM_BODY = `#!/bin/sh
|
|
3154
|
+
nonce=$(cat "$HOME/.dg/state/shim-nonce" 2>/dev/null)
|
|
3154
3155
|
if [ -n "\${DG_SHIM_ACTIVE:-}" ]; then
|
|
3155
3156
|
cleaned_path=$(printf '%s' "$PATH" | awk -v RS=':' -v ORS=':' '$0 != ENVIRON["HOME"]"/.dg/shims"' | sed 's/:$//')
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3157
|
+
# Only honor DG_SHIM_ACTIVE as the recursion guard when it equals the
|
|
3158
|
+
# on-disk nonce \u2014 that is the value our own wrapper sets before running the
|
|
3159
|
+
# real installer. A non-matching value was set outside dg (stale or a
|
|
3160
|
+
# bypass attempt) and must NOT skip scanning.
|
|
3161
|
+
if [ -n "$nonce" ] && [ "$DG_SHIM_ACTIVE" = "$nonce" ]; then
|
|
3162
|
+
real_bin=$(PATH="$cleaned_path" command -v __ECOSYSTEM__)
|
|
3163
|
+
if [ -n "$real_bin" ]; then
|
|
3164
|
+
exec "$real_bin" "$@"
|
|
3165
|
+
fi
|
|
3166
|
+
echo "dg: real __ECOSYSTEM__ not found on PATH" >&2
|
|
3167
|
+
exit 127
|
|
3159
3168
|
fi
|
|
3160
|
-
|
|
3161
|
-
|
|
3169
|
+
if [ -z "$nonce" ]; then
|
|
3170
|
+
echo "dg: shim nonce missing (reinstall dg) \u2014 cannot verify; passing through __ECOSYSTEM__ UNSCANNED." >&2
|
|
3171
|
+
real_bin=$(PATH="$cleaned_path" command -v __ECOSYSTEM__)
|
|
3172
|
+
if [ -n "$real_bin" ]; then exec "$real_bin" "$@"; fi
|
|
3173
|
+
exit 127
|
|
3174
|
+
fi
|
|
3175
|
+
echo "dg: ignoring externally-set DG_SHIM_ACTIVE (nonce mismatch); scanning __ECOSYSTEM__." >&2
|
|
3162
3176
|
fi
|
|
3163
|
-
nonce=$(cat "$HOME/.dg/state/shim-nonce" 2>/dev/null)
|
|
3164
3177
|
dg_entry=$(cat "$HOME/.dg/state/dg-entry" 2>/dev/null)
|
|
3165
3178
|
if [ -n "$dg_entry" ] && [ -x "$dg_entry" ]; then
|
|
3166
3179
|
DG_SHIM_ACTIVE="$nonce" DG_SHIM_PARENT_PATH="$PATH" exec "$dg_entry" __wrap __ECOSYSTEM__ "$@"
|
|
@@ -3180,6 +3193,8 @@ exit 127
|
|
|
3180
3193
|
`;
|
|
3181
3194
|
WINDOWS_SHIM_BODY = `@echo off
|
|
3182
3195
|
setlocal enabledelayedexpansion
|
|
3196
|
+
set "DG_SHIM_NONCE="
|
|
3197
|
+
if exist "%USERPROFILE%\\.dg\\state\\shim-nonce" set /p DG_SHIM_NONCE=<"%USERPROFILE%\\.dg\\state\\shim-nonce"
|
|
3183
3198
|
if not "%DG_SHIM_ACTIVE%"=="" (
|
|
3184
3199
|
set "_dg_realpath="
|
|
3185
3200
|
for /f "tokens=*" %%i in ('where __ECOSYSTEM__ 2^>nul') do (
|
|
@@ -3187,15 +3202,25 @@ if not "%DG_SHIM_ACTIVE%"=="" (
|
|
|
3187
3202
|
if not defined _dg_realpath set "_dg_realpath=%%i"
|
|
3188
3203
|
)
|
|
3189
3204
|
)
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3205
|
+
rem Only honor DG_SHIM_ACTIVE as the recursion guard when it equals the nonce.
|
|
3206
|
+
if "%DG_SHIM_ACTIVE%"=="!DG_SHIM_NONCE!" (
|
|
3207
|
+
if defined _dg_realpath (
|
|
3208
|
+
"!_dg_realpath!" %*
|
|
3209
|
+
exit /b !errorlevel!
|
|
3210
|
+
)
|
|
3211
|
+
echo dg: real __ECOSYSTEM__ not found on PATH 1>&2
|
|
3212
|
+
exit /b 127
|
|
3213
|
+
)
|
|
3214
|
+
if "!DG_SHIM_NONCE!"=="" (
|
|
3215
|
+
echo dg: shim nonce missing ^(reinstall dg^) -- passing through __ECOSYSTEM__ UNSCANNED. 1>&2
|
|
3216
|
+
if defined _dg_realpath (
|
|
3217
|
+
"!_dg_realpath!" %*
|
|
3218
|
+
exit /b !errorlevel!
|
|
3219
|
+
)
|
|
3220
|
+
exit /b 127
|
|
3193
3221
|
)
|
|
3194
|
-
echo dg:
|
|
3195
|
-
exit /b 127
|
|
3222
|
+
echo dg: ignoring externally-set DG_SHIM_ACTIVE ^(nonce mismatch^); scanning __ECOSYSTEM__. 1>&2
|
|
3196
3223
|
)
|
|
3197
|
-
set "DG_SHIM_NONCE="
|
|
3198
|
-
if exist "%USERPROFILE%\\.dg\\state\\shim-nonce" set /p DG_SHIM_NONCE=<"%USERPROFILE%\\.dg\\state\\shim-nonce"
|
|
3199
3224
|
set "DG_ENTRY="
|
|
3200
3225
|
if exist "%USERPROFILE%\\.dg\\state\\dg-entry" set /p DG_ENTRY=<"%USERPROFILE%\\.dg\\state\\dg-entry"
|
|
3201
3226
|
set "DG_SHIM_ACTIVE=!DG_SHIM_NONCE!"
|
|
@@ -3237,9 +3262,9 @@ exit /b 127
|
|
|
3237
3262
|
import { homedir as homedir3 } from "node:os";
|
|
3238
3263
|
import { join as join3 } from "node:path";
|
|
3239
3264
|
import { existsSync as existsSync5, readFileSync as readFileSync4, lstatSync as lstatSync4, appendFileSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
3240
|
-
function expandHome(
|
|
3241
|
-
if (
|
|
3242
|
-
return
|
|
3265
|
+
function expandHome(path) {
|
|
3266
|
+
if (path.startsWith("~/")) return join3(homedir3(), path.slice(2));
|
|
3267
|
+
return path;
|
|
3243
3268
|
}
|
|
3244
3269
|
function detectShellKind(envShell) {
|
|
3245
3270
|
const s = (envShell ?? "").toLowerCase();
|
|
@@ -3463,6 +3488,7 @@ var init_resolve = __esm({
|
|
|
3463
3488
|
var install_exports = {};
|
|
3464
3489
|
__export(install_exports, {
|
|
3465
3490
|
bypassLogPath: () => bypassLogPath,
|
|
3491
|
+
childInstallEnv: () => childInstallEnv,
|
|
3466
3492
|
currentDgEntry: () => currentDgEntry,
|
|
3467
3493
|
dgShimDir: () => dgShimDir,
|
|
3468
3494
|
ensureDgEntryRecorded: () => ensureDgEntryRecorded,
|
|
@@ -3509,15 +3535,15 @@ function ensureDgEntryRecorded(targetHome = homedir5()) {
|
|
|
3509
3535
|
try {
|
|
3510
3536
|
const entry = currentDgEntry();
|
|
3511
3537
|
if (!entry) return;
|
|
3512
|
-
const
|
|
3538
|
+
const path = dgEntryStatePath(targetHome);
|
|
3513
3539
|
let existing = null;
|
|
3514
3540
|
try {
|
|
3515
|
-
existing = readFileSync6(
|
|
3541
|
+
existing = readFileSync6(path, "utf-8").trim();
|
|
3516
3542
|
} catch {
|
|
3517
3543
|
}
|
|
3518
3544
|
if (existing === entry) return;
|
|
3519
|
-
safeMkdirRecursive(dirname5(
|
|
3520
|
-
safeWriteFile(
|
|
3545
|
+
safeMkdirRecursive(dirname5(path), 493);
|
|
3546
|
+
safeWriteFile(path, entry + "\n", 420);
|
|
3521
3547
|
} catch {
|
|
3522
3548
|
}
|
|
3523
3549
|
}
|
|
@@ -3529,11 +3555,21 @@ function readNonce() {
|
|
|
3529
3555
|
return null;
|
|
3530
3556
|
}
|
|
3531
3557
|
}
|
|
3532
|
-
function
|
|
3558
|
+
function childInstallEnv() {
|
|
3559
|
+
const env3 = {};
|
|
3560
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
3561
|
+
if (k.startsWith("DG_")) continue;
|
|
3562
|
+
env3[k] = v;
|
|
3563
|
+
}
|
|
3564
|
+
const nonce = readNonce();
|
|
3565
|
+
if (nonce) env3.DG_SHIM_ACTIVE = nonce;
|
|
3566
|
+
return env3;
|
|
3567
|
+
}
|
|
3568
|
+
function chownIfNeeded(path, uid, gid) {
|
|
3533
3569
|
if (uid === void 0 || gid === void 0) return;
|
|
3534
3570
|
if (process.platform === "win32") return;
|
|
3535
3571
|
try {
|
|
3536
|
-
chownSync(
|
|
3572
|
+
chownSync(path, uid, gid);
|
|
3537
3573
|
} catch {
|
|
3538
3574
|
}
|
|
3539
3575
|
}
|
|
@@ -28803,10 +28839,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28803
28839
|
var setErrorHandler = null;
|
|
28804
28840
|
var setSuspenseHandler = null;
|
|
28805
28841
|
{
|
|
28806
|
-
var copyWithDeleteImpl = function(obj,
|
|
28807
|
-
var key =
|
|
28842
|
+
var copyWithDeleteImpl = function(obj, path, index2) {
|
|
28843
|
+
var key = path[index2];
|
|
28808
28844
|
var updated = isArray(obj) ? obj.slice() : assign({}, obj);
|
|
28809
|
-
if (index2 + 1 ===
|
|
28845
|
+
if (index2 + 1 === path.length) {
|
|
28810
28846
|
if (isArray(updated)) {
|
|
28811
28847
|
updated.splice(key, 1);
|
|
28812
28848
|
} else {
|
|
@@ -28814,11 +28850,11 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28814
28850
|
}
|
|
28815
28851
|
return updated;
|
|
28816
28852
|
}
|
|
28817
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
28853
|
+
updated[key] = copyWithDeleteImpl(obj[key], path, index2 + 1);
|
|
28818
28854
|
return updated;
|
|
28819
28855
|
};
|
|
28820
|
-
var copyWithDelete = function(obj,
|
|
28821
|
-
return copyWithDeleteImpl(obj,
|
|
28856
|
+
var copyWithDelete = function(obj, path) {
|
|
28857
|
+
return copyWithDeleteImpl(obj, path, 0);
|
|
28822
28858
|
};
|
|
28823
28859
|
var copyWithRenameImpl = function(obj, oldPath, newPath, index2) {
|
|
28824
28860
|
var oldKey = oldPath[index2];
|
|
@@ -28856,17 +28892,17 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28856
28892
|
}
|
|
28857
28893
|
return copyWithRenameImpl(obj, oldPath, newPath, 0);
|
|
28858
28894
|
};
|
|
28859
|
-
var copyWithSetImpl = function(obj,
|
|
28860
|
-
if (index2 >=
|
|
28895
|
+
var copyWithSetImpl = function(obj, path, index2, value) {
|
|
28896
|
+
if (index2 >= path.length) {
|
|
28861
28897
|
return value;
|
|
28862
28898
|
}
|
|
28863
|
-
var key =
|
|
28899
|
+
var key = path[index2];
|
|
28864
28900
|
var updated = isArray(obj) ? obj.slice() : assign({}, obj);
|
|
28865
|
-
updated[key] = copyWithSetImpl(obj[key],
|
|
28901
|
+
updated[key] = copyWithSetImpl(obj[key], path, index2 + 1, value);
|
|
28866
28902
|
return updated;
|
|
28867
28903
|
};
|
|
28868
|
-
var copyWithSet = function(obj,
|
|
28869
|
-
return copyWithSetImpl(obj,
|
|
28904
|
+
var copyWithSet = function(obj, path, value) {
|
|
28905
|
+
return copyWithSetImpl(obj, path, 0, value);
|
|
28870
28906
|
};
|
|
28871
28907
|
var findHook = function(fiber, id) {
|
|
28872
28908
|
var currentHook2 = fiber.memoizedState;
|
|
@@ -28876,10 +28912,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28876
28912
|
}
|
|
28877
28913
|
return currentHook2;
|
|
28878
28914
|
};
|
|
28879
|
-
overrideHookState = function(fiber, id,
|
|
28915
|
+
overrideHookState = function(fiber, id, path, value) {
|
|
28880
28916
|
var hook = findHook(fiber, id);
|
|
28881
28917
|
if (hook !== null) {
|
|
28882
|
-
var newState = copyWithSet(hook.memoizedState,
|
|
28918
|
+
var newState = copyWithSet(hook.memoizedState, path, value);
|
|
28883
28919
|
hook.memoizedState = newState;
|
|
28884
28920
|
hook.baseState = newState;
|
|
28885
28921
|
fiber.memoizedProps = assign({}, fiber.memoizedProps);
|
|
@@ -28889,10 +28925,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28889
28925
|
}
|
|
28890
28926
|
}
|
|
28891
28927
|
};
|
|
28892
|
-
overrideHookStateDeletePath = function(fiber, id,
|
|
28928
|
+
overrideHookStateDeletePath = function(fiber, id, path) {
|
|
28893
28929
|
var hook = findHook(fiber, id);
|
|
28894
28930
|
if (hook !== null) {
|
|
28895
|
-
var newState = copyWithDelete(hook.memoizedState,
|
|
28931
|
+
var newState = copyWithDelete(hook.memoizedState, path);
|
|
28896
28932
|
hook.memoizedState = newState;
|
|
28897
28933
|
hook.baseState = newState;
|
|
28898
28934
|
fiber.memoizedProps = assign({}, fiber.memoizedProps);
|
|
@@ -28915,8 +28951,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28915
28951
|
}
|
|
28916
28952
|
}
|
|
28917
28953
|
};
|
|
28918
|
-
overrideProps = function(fiber,
|
|
28919
|
-
fiber.pendingProps = copyWithSet(fiber.memoizedProps,
|
|
28954
|
+
overrideProps = function(fiber, path, value) {
|
|
28955
|
+
fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
|
|
28920
28956
|
if (fiber.alternate) {
|
|
28921
28957
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
28922
28958
|
}
|
|
@@ -28925,8 +28961,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28925
28961
|
scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
|
|
28926
28962
|
}
|
|
28927
28963
|
};
|
|
28928
|
-
overridePropsDeletePath = function(fiber,
|
|
28929
|
-
fiber.pendingProps = copyWithDelete(fiber.memoizedProps,
|
|
28964
|
+
overridePropsDeletePath = function(fiber, path) {
|
|
28965
|
+
fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
|
|
28930
28966
|
if (fiber.alternate) {
|
|
28931
28967
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
28932
28968
|
}
|
|
@@ -36994,8 +37030,8 @@ var init_ErrorOverview = __esm({
|
|
|
36994
37030
|
init_dist3();
|
|
36995
37031
|
init_Box();
|
|
36996
37032
|
init_Text();
|
|
36997
|
-
cleanupPath = (
|
|
36998
|
-
return
|
|
37033
|
+
cleanupPath = (path) => {
|
|
37034
|
+
return path?.replace(`file://${cwd()}/`, "");
|
|
36999
37035
|
};
|
|
37000
37036
|
stackUtils = new import_stack_utils.default({
|
|
37001
37037
|
cwd: cwd(),
|
|
@@ -41664,18 +41700,19 @@ async function readNdjsonAnalyzeResponse(response, onPackageProgress) {
|
|
|
41664
41700
|
}
|
|
41665
41701
|
buf += decoder.decode();
|
|
41666
41702
|
if (buf.trim()) processLine(buf);
|
|
41667
|
-
|
|
41703
|
+
const payload = finalPayload;
|
|
41704
|
+
if (!payload) {
|
|
41668
41705
|
throw new APIError(
|
|
41669
41706
|
"Streaming response ended without a result event",
|
|
41670
41707
|
0,
|
|
41671
41708
|
""
|
|
41672
41709
|
);
|
|
41673
41710
|
}
|
|
41674
|
-
if (typeof
|
|
41711
|
+
if (typeof payload.score !== "number" || !Array.isArray(payload.packages)) {
|
|
41675
41712
|
throw new APIError("Invalid streamed result payload", 0, "");
|
|
41676
41713
|
}
|
|
41677
|
-
checkVersionFloor(
|
|
41678
|
-
return sanitizeResponse(
|
|
41714
|
+
checkVersionFloor(payload);
|
|
41715
|
+
return sanitizeResponse(payload);
|
|
41679
41716
|
}
|
|
41680
41717
|
async function callPyPIAnalyzeAPI(packages, config, onProgress) {
|
|
41681
41718
|
const batchSize = config.apiKey ? BATCH_SIZE : ANON_BATCH_SIZE;
|
|
@@ -41992,9 +42029,9 @@ function parseLockfile(content) {
|
|
|
41992
42029
|
const lockfileVersion = json.lockfileVersion ?? 1;
|
|
41993
42030
|
const packages = /* @__PURE__ */ new Map();
|
|
41994
42031
|
if (lockfileVersion >= 2 && json.packages) {
|
|
41995
|
-
for (const [
|
|
41996
|
-
if (
|
|
41997
|
-
const pathName = extractPackageName(
|
|
42032
|
+
for (const [path, entry] of Object.entries(json.packages)) {
|
|
42033
|
+
if (path === "") continue;
|
|
42034
|
+
const pathName = extractPackageName(path);
|
|
41998
42035
|
if (!pathName) continue;
|
|
41999
42036
|
const e = entry;
|
|
42000
42037
|
const entryName = typeof e.name === "string" && e.name.length > 0 ? e.name : void 0;
|
|
@@ -42266,12 +42303,12 @@ var init_parse_package_json = __esm({
|
|
|
42266
42303
|
// src/lockfile/index.ts
|
|
42267
42304
|
import { readFileSync as readFileSync8, existsSync as existsSync11, statSync as statSync3 } from "node:fs";
|
|
42268
42305
|
import { join as join6 } from "node:path";
|
|
42269
|
-
function readFileSafe(
|
|
42270
|
-
const size = statSync3(
|
|
42306
|
+
function readFileSafe(path) {
|
|
42307
|
+
const size = statSync3(path).size;
|
|
42271
42308
|
if (size > MAX_LOCKFILE_BYTES) {
|
|
42272
|
-
throw new Error(`Lockfile too large (${(size / 1024 / 1024).toFixed(0)} MB, max 50 MB): ${
|
|
42309
|
+
throw new Error(`Lockfile too large (${(size / 1024 / 1024).toFixed(0)} MB, max 50 MB): ${path}`);
|
|
42273
42310
|
}
|
|
42274
|
-
return readFileSync8(
|
|
42311
|
+
return readFileSync8(path, "utf-8");
|
|
42275
42312
|
}
|
|
42276
42313
|
function discoverChanges(cwd2, config) {
|
|
42277
42314
|
if (config.workspace) {
|
|
@@ -42537,6 +42574,12 @@ var init_lockfile = __esm({
|
|
|
42537
42574
|
});
|
|
42538
42575
|
|
|
42539
42576
|
// src/commands/wrapper-shared.ts
|
|
42577
|
+
function injectIgnoreScripts(args, opts) {
|
|
42578
|
+
if (!opts.isNpmFamily) return args;
|
|
42579
|
+
if (!(opts.strict || opts.dgNoScripts)) return args;
|
|
42580
|
+
if (args.includes("--ignore-scripts")) return args;
|
|
42581
|
+
return [...args, "--ignore-scripts"];
|
|
42582
|
+
}
|
|
42540
42583
|
function stripDgFlags(args) {
|
|
42541
42584
|
let dgForce = false;
|
|
42542
42585
|
let dgForceReason;
|
|
@@ -42619,9 +42662,7 @@ function realNpmBinary() {
|
|
|
42619
42662
|
return real;
|
|
42620
42663
|
}
|
|
42621
42664
|
function shimSentinelEnv() {
|
|
42622
|
-
|
|
42623
|
-
if (!nonce) return process.env;
|
|
42624
|
-
return { ...process.env, DG_SHIM_ACTIVE: nonce };
|
|
42665
|
+
return childInstallEnv();
|
|
42625
42666
|
}
|
|
42626
42667
|
function parseNpmArgs(args) {
|
|
42627
42668
|
const { filtered, dgForce, dgForceReason, dgNoScripts } = stripDgFlags(args);
|
|
@@ -42889,9 +42930,9 @@ function readLockfilePins(cwd2) {
|
|
|
42889
42930
|
...Object.keys(root.optionalDependencies ?? {}),
|
|
42890
42931
|
...Object.keys(root.peerDependencies ?? {})
|
|
42891
42932
|
]);
|
|
42892
|
-
for (const [
|
|
42893
|
-
if (
|
|
42894
|
-
const m =
|
|
42933
|
+
for (const [path, entry] of Object.entries(lock.packages ?? {})) {
|
|
42934
|
+
if (path === "") continue;
|
|
42935
|
+
const m = path.match(/^node_modules\/((?:@[^/]+\/)?[^/]+)$/);
|
|
42895
42936
|
if (!m) continue;
|
|
42896
42937
|
const name = m[1];
|
|
42897
42938
|
if (!directDeps.has(name)) continue;
|
|
@@ -43067,6 +43108,22 @@ function parsePipSpec(spec) {
|
|
|
43067
43108
|
versionSpec: match[2] ?? null
|
|
43068
43109
|
};
|
|
43069
43110
|
}
|
|
43111
|
+
function pinPipArgs(rawArgs, userSpecs, resolved) {
|
|
43112
|
+
const specNames = new Set(userSpecs.map((s) => parsePipSpec(s).name.toLowerCase()));
|
|
43113
|
+
const pinByName = /* @__PURE__ */ new Map();
|
|
43114
|
+
for (const p of resolved) {
|
|
43115
|
+
const key = p.name.toLowerCase();
|
|
43116
|
+
if (specNames.has(key) && !pinByName.has(key)) {
|
|
43117
|
+
pinByName.set(key, `${p.name}==${p.version}`);
|
|
43118
|
+
}
|
|
43119
|
+
}
|
|
43120
|
+
const specSet = new Set(userSpecs);
|
|
43121
|
+
return rawArgs.map((a) => {
|
|
43122
|
+
if (!specSet.has(a)) return a;
|
|
43123
|
+
const { name } = parsePipSpec(a);
|
|
43124
|
+
return pinByName.get(name.toLowerCase()) ?? a;
|
|
43125
|
+
});
|
|
43126
|
+
}
|
|
43070
43127
|
async function resolvePipVersion(spec) {
|
|
43071
43128
|
const { name, versionSpec } = parsePipSpec(spec);
|
|
43072
43129
|
if (versionSpec?.startsWith("==")) {
|
|
@@ -43128,9 +43185,7 @@ async function resolvePackages2(specs) {
|
|
|
43128
43185
|
return { resolved, failed };
|
|
43129
43186
|
}
|
|
43130
43187
|
function shimSentinelEnv2() {
|
|
43131
|
-
|
|
43132
|
-
if (!nonce) return process.env;
|
|
43133
|
-
return { ...process.env, DG_SHIM_ACTIVE: nonce };
|
|
43188
|
+
return childInstallEnv();
|
|
43134
43189
|
}
|
|
43135
43190
|
async function detectPipBinary() {
|
|
43136
43191
|
const py3 = walkPathExcludingShimDir("python3");
|
|
@@ -43427,16 +43482,16 @@ function collectNpmLockSha512Hashes(packageLock) {
|
|
|
43427
43482
|
const root = packageLock;
|
|
43428
43483
|
const packages = root["packages"];
|
|
43429
43484
|
if (packages && typeof packages === "object") {
|
|
43430
|
-
for (const [
|
|
43431
|
-
if (
|
|
43485
|
+
for (const [path, raw] of Object.entries(packages)) {
|
|
43486
|
+
if (path === "") continue;
|
|
43432
43487
|
if (!raw || typeof raw !== "object") continue;
|
|
43433
43488
|
const entry = raw;
|
|
43434
43489
|
const version = typeof entry.version === "string" ? entry.version : void 0;
|
|
43435
43490
|
const integrity = typeof entry.integrity === "string" ? entry.integrity : void 0;
|
|
43436
43491
|
if (!version || !integrity) continue;
|
|
43437
|
-
const idx =
|
|
43492
|
+
const idx = path.lastIndexOf("node_modules/");
|
|
43438
43493
|
if (idx < 0) continue;
|
|
43439
|
-
const name =
|
|
43494
|
+
const name = path.slice(idx + "node_modules/".length);
|
|
43440
43495
|
if (!name) continue;
|
|
43441
43496
|
const hex = npmIntegrityToSha512Hex(integrity);
|
|
43442
43497
|
if (hex) out.set(`${name}@${version}`, hex);
|
|
@@ -43678,7 +43733,7 @@ var init_FileSavePrompt = __esm({
|
|
|
43678
43733
|
return;
|
|
43679
43734
|
}
|
|
43680
43735
|
if ((key.backspace || key.delete) && !state.filterText) {
|
|
43681
|
-
const parentDir =
|
|
43736
|
+
const parentDir = dirname8(state.directory);
|
|
43682
43737
|
if (parentDir !== state.directory) {
|
|
43683
43738
|
dispatch({ type: "SET_DIRECTORY", directory: parentDir, entries: listDirectory(parentDir) });
|
|
43684
43739
|
}
|
|
@@ -43691,7 +43746,7 @@ var init_FileSavePrompt = __esm({
|
|
|
43691
43746
|
if (key.return) {
|
|
43692
43747
|
const entry = filteredEntries[state.browserCursor];
|
|
43693
43748
|
if (!entry || !entry.isDirectory) return;
|
|
43694
|
-
const newDir = entry.name === ".." ?
|
|
43749
|
+
const newDir = entry.name === ".." ? dirname8(state.directory) : join8(state.directory, entry.name);
|
|
43695
43750
|
dispatch({ type: "SET_DIRECTORY", directory: newDir, entries: listDirectory(newDir) });
|
|
43696
43751
|
return;
|
|
43697
43752
|
}
|
|
@@ -43967,9 +44022,9 @@ async function scanDir(dir, depth, _root) {
|
|
|
43967
44022
|
}
|
|
43968
44023
|
return { subdirs, lockfileHits };
|
|
43969
44024
|
}
|
|
43970
|
-
async function isSafeRegularFile(
|
|
44025
|
+
async function isSafeRegularFile(path) {
|
|
43971
44026
|
try {
|
|
43972
|
-
const st = await lstat(
|
|
44027
|
+
const st = await lstat(path);
|
|
43973
44028
|
return st.isFile() && !st.isSymbolicLink();
|
|
43974
44029
|
} catch {
|
|
43975
44030
|
return false;
|
|
@@ -44104,9 +44159,9 @@ function discoverProjectsConsolidated(projectPaths, config) {
|
|
|
44104
44159
|
const seenPy = /* @__PURE__ */ new Set();
|
|
44105
44160
|
const unparseable = [];
|
|
44106
44161
|
let rawCount = 0;
|
|
44107
|
-
for (const
|
|
44162
|
+
for (const path of projectPaths) {
|
|
44108
44163
|
try {
|
|
44109
|
-
const d = discoverChanges(
|
|
44164
|
+
const d = discoverChanges(path, config);
|
|
44110
44165
|
for (const pkg of d.packages) {
|
|
44111
44166
|
rawCount++;
|
|
44112
44167
|
const key = `${pkg.name}@${pkg.version}`;
|
|
@@ -44122,7 +44177,7 @@ function discoverProjectsConsolidated(projectPaths, config) {
|
|
|
44122
44177
|
pythonPackages.push(pkg);
|
|
44123
44178
|
}
|
|
44124
44179
|
} catch {
|
|
44125
|
-
unparseable.push(
|
|
44180
|
+
unparseable.push(path);
|
|
44126
44181
|
}
|
|
44127
44182
|
}
|
|
44128
44183
|
return {
|
|
@@ -44371,21 +44426,21 @@ function validateAllowlist(raw) {
|
|
|
44371
44426
|
return { ok: true, allowlist: { schemaVersion: 1, rules, packages } };
|
|
44372
44427
|
}
|
|
44373
44428
|
function loadAllowlist(cwd2) {
|
|
44374
|
-
const
|
|
44375
|
-
if (!
|
|
44429
|
+
const path = findAllowlistFile(cwd2);
|
|
44430
|
+
if (!path) return null;
|
|
44376
44431
|
let raw;
|
|
44377
44432
|
try {
|
|
44378
|
-
raw = JSON.parse(readFileSync10(
|
|
44433
|
+
raw = JSON.parse(readFileSync10(path, "utf-8"));
|
|
44379
44434
|
} catch (e) {
|
|
44380
44435
|
process.stderr.write(
|
|
44381
|
-
`dg: .dg-allowlist.json at ${
|
|
44436
|
+
`dg: .dg-allowlist.json at ${path} is not valid JSON (${e.message}). Ignoring.
|
|
44382
44437
|
`
|
|
44383
44438
|
);
|
|
44384
44439
|
return null;
|
|
44385
44440
|
}
|
|
44386
44441
|
const validation = validateAllowlist(raw);
|
|
44387
44442
|
if (!validation.ok) {
|
|
44388
|
-
process.stderr.write(`dg: .dg-allowlist.json at ${
|
|
44443
|
+
process.stderr.write(`dg: .dg-allowlist.json at ${path} failed validation:
|
|
44389
44444
|
`);
|
|
44390
44445
|
for (const err of validation.errors) {
|
|
44391
44446
|
process.stderr.write(` ${err.path}: ${err.message}
|
|
@@ -44395,7 +44450,7 @@ function loadAllowlist(cwd2) {
|
|
|
44395
44450
|
`);
|
|
44396
44451
|
return null;
|
|
44397
44452
|
}
|
|
44398
|
-
return { ...validation.allowlist, sourcePath:
|
|
44453
|
+
return { ...validation.allowlist, sourcePath: path };
|
|
44399
44454
|
}
|
|
44400
44455
|
function findingRuleId(f) {
|
|
44401
44456
|
return (f.category ?? f.title ?? "").toString();
|
|
@@ -44516,8 +44571,31 @@ function findingFingerprint(pkg, f) {
|
|
|
44516
44571
|
function buildSarif(response, opts = {}) {
|
|
44517
44572
|
const ruleMap = /* @__PURE__ */ new Map();
|
|
44518
44573
|
const results = [];
|
|
44574
|
+
const INCOMPLETE_RULE = "dg.analysis_incomplete";
|
|
44519
44575
|
for (const pkg of response.packages) {
|
|
44576
|
+
if (pkg.action === "analysis_incomplete") {
|
|
44577
|
+
if (!ruleMap.has(INCOMPLETE_RULE)) {
|
|
44578
|
+
ruleMap.set(INCOMPLETE_RULE, {
|
|
44579
|
+
id: INCOMPLETE_RULE,
|
|
44580
|
+
name: INCOMPLETE_RULE,
|
|
44581
|
+
shortDescription: { text: "Package could not be fully analyzed \u2014 treat as unverified" },
|
|
44582
|
+
defaultConfiguration: { level: "warning" }
|
|
44583
|
+
});
|
|
44584
|
+
}
|
|
44585
|
+
results.push({
|
|
44586
|
+
ruleId: INCOMPLETE_RULE,
|
|
44587
|
+
level: "warning",
|
|
44588
|
+
message: { text: `${pkg.name} ${pkg.version}: analysis incomplete \u2014 the scanner could not fully evaluate this package. Treat as unverified, not safe.` },
|
|
44589
|
+
locations: [{
|
|
44590
|
+
physicalLocation: {
|
|
44591
|
+
artifactLocation: { uri: opts.lockfileUri ?? `dg:${pkg.name}@${pkg.version}` }
|
|
44592
|
+
}
|
|
44593
|
+
}],
|
|
44594
|
+
partialFingerprints: { dg_finding: `${pkg.name}@${pkg.version}#${INCOMPLETE_RULE}`.slice(0, 240) }
|
|
44595
|
+
});
|
|
44596
|
+
}
|
|
44520
44597
|
const findings = pkg.findings ?? [];
|
|
44598
|
+
let pkgResultCount = 0;
|
|
44521
44599
|
for (const f of findings) {
|
|
44522
44600
|
const id = findingId(f);
|
|
44523
44601
|
const level = severityToLevel(f.severity);
|
|
@@ -44541,6 +44619,32 @@ function buildSarif(response, opts = {}) {
|
|
|
44541
44619
|
}],
|
|
44542
44620
|
partialFingerprints: { dg_finding: findingFingerprint(pkg, f) }
|
|
44543
44621
|
});
|
|
44622
|
+
pkgResultCount++;
|
|
44623
|
+
}
|
|
44624
|
+
if (pkgResultCount === 0 && (pkg.action === "block" || pkg.action === "warn")) {
|
|
44625
|
+
const ruleId = pkg.action === "block" ? "dg.block" : "dg.warn";
|
|
44626
|
+
const level = pkg.action === "block" ? "error" : "warning";
|
|
44627
|
+
if (!ruleMap.has(ruleId)) {
|
|
44628
|
+
ruleMap.set(ruleId, {
|
|
44629
|
+
id: ruleId,
|
|
44630
|
+
name: ruleId,
|
|
44631
|
+
shortDescription: {
|
|
44632
|
+
text: pkg.action === "block" ? "Package blocked by Dependency Guardian" : "Package flagged (warn) by Dependency Guardian"
|
|
44633
|
+
},
|
|
44634
|
+
defaultConfiguration: { level }
|
|
44635
|
+
});
|
|
44636
|
+
}
|
|
44637
|
+
results.push({
|
|
44638
|
+
ruleId,
|
|
44639
|
+
level,
|
|
44640
|
+
message: { text: `${pkg.name} ${pkg.version}: ${pkg.action} verdict from Dependency Guardian (no individual findings surfaced at this tier).` },
|
|
44641
|
+
locations: [{
|
|
44642
|
+
physicalLocation: {
|
|
44643
|
+
artifactLocation: { uri: opts.lockfileUri ?? `dg:${pkg.name}@${pkg.version}` }
|
|
44644
|
+
}
|
|
44645
|
+
}],
|
|
44646
|
+
partialFingerprints: { dg_finding: `${pkg.name}@${pkg.version}#${ruleId}`.slice(0, 240) }
|
|
44647
|
+
});
|
|
44544
44648
|
}
|
|
44545
44649
|
}
|
|
44546
44650
|
return {
|
|
@@ -44677,7 +44781,7 @@ function shouldFireAudit(policy, decisionAction) {
|
|
|
44677
44781
|
return false;
|
|
44678
44782
|
}
|
|
44679
44783
|
function flagPackages(packages) {
|
|
44680
|
-
return packages.filter((p) => p.
|
|
44784
|
+
return packages.filter((p) => (p.action ?? "pass") !== "pass");
|
|
44681
44785
|
}
|
|
44682
44786
|
async function dispatchPublishCheckAudit(opts) {
|
|
44683
44787
|
try {
|
|
@@ -44704,8 +44808,8 @@ function bypassLogPath2() {
|
|
|
44704
44808
|
}
|
|
44705
44809
|
function recordBypassLocally(record) {
|
|
44706
44810
|
try {
|
|
44707
|
-
const
|
|
44708
|
-
const dir = dirname10(
|
|
44811
|
+
const path = bypassLogPath2();
|
|
44812
|
+
const dir = dirname10(path);
|
|
44709
44813
|
if (!existsSync16(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
44710
44814
|
const full = {
|
|
44711
44815
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -44716,7 +44820,7 @@ function recordBypassLocally(record) {
|
|
|
44716
44820
|
reason: record.reason,
|
|
44717
44821
|
packages: record.packages
|
|
44718
44822
|
};
|
|
44719
|
-
appendFileSync3(
|
|
44823
|
+
appendFileSync3(path, JSON.stringify(full) + "\n", { mode: 384 });
|
|
44720
44824
|
} catch {
|
|
44721
44825
|
}
|
|
44722
44826
|
}
|
|
@@ -44789,13 +44893,13 @@ function wrapperPackagesFromResult(result, topLevelNames) {
|
|
|
44789
44893
|
}));
|
|
44790
44894
|
}
|
|
44791
44895
|
function loadPackageLockJson(cwd2 = process.cwd()) {
|
|
44792
|
-
const
|
|
44793
|
-
if (!existsSync17(
|
|
44896
|
+
const path = resolvePath(cwd2, "package-lock.json");
|
|
44897
|
+
if (!existsSync17(path)) return null;
|
|
44794
44898
|
try {
|
|
44795
|
-
const st = lstatSync5(
|
|
44899
|
+
const st = lstatSync5(path);
|
|
44796
44900
|
if (!st.isFile()) return null;
|
|
44797
44901
|
if (st.size > MAX_PACKAGE_LOCK_BYTES) return null;
|
|
44798
|
-
return JSON.parse(readFileSync11(
|
|
44902
|
+
return JSON.parse(readFileSync11(path, "utf8"));
|
|
44799
44903
|
} catch {
|
|
44800
44904
|
return null;
|
|
44801
44905
|
}
|
|
@@ -44875,7 +44979,7 @@ function maybePrintFirstScanNotice(config) {
|
|
|
44875
44979
|
if (getScanNoticeShownAt2() !== null) return;
|
|
44876
44980
|
process.stderr.write(
|
|
44877
44981
|
import_chalk5.default.dim(
|
|
44878
|
-
" Dependency Guardian sends package names + versions to api.westbayberry.com.\n Anonymous crash reports are on
|
|
44982
|
+
" Dependency Guardian sends package names + versions to api.westbayberry.com.\n Anonymous crash reports are on to help us fix early bugs (no source, paths, or package names);\n opt out with DG_TELEMETRY=0 or DO_NOT_TRACK=1.\n Terms: https://westbayberry.com/terms \xB7 Privacy: https://westbayberry.com/privacy\n"
|
|
44879
44983
|
)
|
|
44880
44984
|
);
|
|
44881
44985
|
recordScanNoticeShown2();
|
|
@@ -44941,6 +45045,7 @@ function handleFreeCapReached2(error, jsonMode = false) {
|
|
|
44941
45045
|
function actionColor(action) {
|
|
44942
45046
|
if (action === "block") return import_chalk5.default.red;
|
|
44943
45047
|
if (action === "warn") return import_chalk5.default.yellow;
|
|
45048
|
+
if (action === "analysis_incomplete") return import_chalk5.default.cyan;
|
|
44944
45049
|
return import_chalk5.default.green;
|
|
44945
45050
|
}
|
|
44946
45051
|
function actionBadge(pkg) {
|
|
@@ -44957,6 +45062,9 @@ function isBlocked(p) {
|
|
|
44957
45062
|
function isWarned(p) {
|
|
44958
45063
|
return p.action === "warn";
|
|
44959
45064
|
}
|
|
45065
|
+
function isIncomplete(p) {
|
|
45066
|
+
return p.action === "analysis_incomplete";
|
|
45067
|
+
}
|
|
44960
45068
|
function renderResultClean(result, _config) {
|
|
44961
45069
|
const lines = [];
|
|
44962
45070
|
const total = result.packages.length;
|
|
@@ -44968,7 +45076,8 @@ function renderResultClean(result, _config) {
|
|
|
44968
45076
|
}
|
|
44969
45077
|
const blocked = result.packages.filter(isBlocked);
|
|
44970
45078
|
const warned = result.packages.filter(isWarned);
|
|
44971
|
-
|
|
45079
|
+
const incomplete = result.packages.filter(isIncomplete);
|
|
45080
|
+
if (result.action === "pass" && blocked.length === 0 && warned.length === 0 && incomplete.length === 0) {
|
|
44972
45081
|
lines.push("");
|
|
44973
45082
|
lines.push(` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("Dependency Guardian")} checked ${total} package${total !== 1 ? "s" : ""}. ${import_chalk5.default.green("No risky behavior found.")}`);
|
|
44974
45083
|
if (result.durationMs) {
|
|
@@ -44977,11 +45086,18 @@ function renderResultClean(result, _config) {
|
|
|
44977
45086
|
lines.push("");
|
|
44978
45087
|
return lines.join("\n");
|
|
44979
45088
|
}
|
|
44980
|
-
const
|
|
44981
|
-
const
|
|
45089
|
+
const headerLabel = result.action === "block" ? "BLOCK" : result.action === "warn" ? "WARN" : result.action === "analysis_incomplete" ? "UNKNOWN" : "PASS";
|
|
45090
|
+
const headerColor = actionColor(result.action);
|
|
45091
|
+
const cleanCount = total - blocked.length - warned.length - incomplete.length;
|
|
45092
|
+
const countParts = [
|
|
45093
|
+
`${blocked.length} block`,
|
|
45094
|
+
`${warned.length} warn`,
|
|
45095
|
+
...incomplete.length > 0 ? [`${incomplete.length} unknown`] : [],
|
|
45096
|
+
`${cleanCount} clean`
|
|
45097
|
+
];
|
|
44982
45098
|
lines.push("");
|
|
44983
45099
|
lines.push(` ${headerColor(import_chalk5.default.bold(headerLabel))} ${import_chalk5.default.bold("Dependency Guardian")} ${import_chalk5.default.dim(`(score ${result.score})`)}`);
|
|
44984
|
-
lines.push(` ${import_chalk5.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned \xB7 ${
|
|
45100
|
+
lines.push(` ${import_chalk5.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned \xB7 ${countParts.join(" \xB7 ")}`)}`);
|
|
44985
45101
|
lines.push("");
|
|
44986
45102
|
const showFirst = (pkgs, color, label) => {
|
|
44987
45103
|
if (pkgs.length === 0) return;
|
|
@@ -44997,10 +45113,13 @@ function renderResultClean(result, _config) {
|
|
|
44997
45113
|
};
|
|
44998
45114
|
showFirst(blocked, import_chalk5.default.red, "Blocked");
|
|
44999
45115
|
showFirst(warned, import_chalk5.default.yellow, "Warnings");
|
|
45116
|
+
showFirst(incomplete, import_chalk5.default.cyan, "Could not analyze");
|
|
45000
45117
|
if (result.action === "block") {
|
|
45001
45118
|
lines.push(` ${import_chalk5.default.dim("Next step:")} review the findings above, then either pin a safe version or use ${import_chalk5.default.bold("--dg-force")} to bypass.`);
|
|
45002
45119
|
} else if (result.action === "warn") {
|
|
45003
45120
|
lines.push(` ${import_chalk5.default.dim("Next step:")} review the warnings; install proceeds unless you set ${import_chalk5.default.bold("--mode block")}.`);
|
|
45121
|
+
} else if (result.action === "analysis_incomplete") {
|
|
45122
|
+
lines.push(` ${import_chalk5.default.dim("Next step:")} one or more packages could not be fully analyzed \u2014 treat as unverified, not safe. Re-run to retry.`);
|
|
45004
45123
|
}
|
|
45005
45124
|
lines.push("");
|
|
45006
45125
|
return lines.join("\n");
|
|
@@ -45019,13 +45138,21 @@ function renderResultDetails(result, _config) {
|
|
|
45019
45138
|
lines.push("");
|
|
45020
45139
|
const blocked = result.packages.filter(isBlocked);
|
|
45021
45140
|
const warned = result.packages.filter(isWarned);
|
|
45022
|
-
const
|
|
45023
|
-
const
|
|
45141
|
+
const incomplete = result.packages.filter(isIncomplete);
|
|
45142
|
+
const rest = result.packages.filter((p) => !isBlocked(p) && !isWarned(p) && !isIncomplete(p));
|
|
45143
|
+
const passWithScore = rest.filter((p) => p.score > 0 && p.score < 60);
|
|
45144
|
+
const clean = rest.filter((p) => p.score === 0);
|
|
45024
45145
|
const total = result.packages.length;
|
|
45025
45146
|
const needsAttention = blocked.length + warned.length;
|
|
45026
|
-
if (needsAttention > 0) {
|
|
45147
|
+
if (needsAttention > 0 || incomplete.length > 0) {
|
|
45148
|
+
const segs = [
|
|
45149
|
+
import_chalk5.default.red(`${blocked.length} block`),
|
|
45150
|
+
import_chalk5.default.yellow(`${warned.length} warn`),
|
|
45151
|
+
...incomplete.length > 0 ? [import_chalk5.default.cyan(`${incomplete.length} unknown`)] : [],
|
|
45152
|
+
import_chalk5.default.green(`${clean.length + passWithScore.length} pass`)
|
|
45153
|
+
];
|
|
45027
45154
|
lines.push(
|
|
45028
|
-
` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${
|
|
45155
|
+
` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${segs.join(` ${import_chalk5.default.dim("\u2502")} `)}`
|
|
45029
45156
|
);
|
|
45030
45157
|
} else {
|
|
45031
45158
|
lines.push(
|
|
@@ -45038,8 +45165,8 @@ function renderResultDetails(result, _config) {
|
|
|
45038
45165
|
lines.push("");
|
|
45039
45166
|
return lines.join("\n");
|
|
45040
45167
|
}
|
|
45041
|
-
if (needsAttention > 0) {
|
|
45042
|
-
const groups = groupPackages([...blocked, ...warned]);
|
|
45168
|
+
if (needsAttention > 0 || incomplete.length > 0) {
|
|
45169
|
+
const groups = groupPackages([...blocked, ...warned, ...incomplete]);
|
|
45043
45170
|
lines.push(` ${import_chalk5.default.bold("Needs Attention")}`);
|
|
45044
45171
|
lines.push(` ${import_chalk5.default.dim("\u2500".repeat(60))}`);
|
|
45045
45172
|
for (const group of groups) {
|
|
@@ -45183,14 +45310,7 @@ async function runStatic(config) {
|
|
|
45183
45310
|
}
|
|
45184
45311
|
if (discovery.pythonPackages.length > 0) {
|
|
45185
45312
|
const pyResult = await callPyPIAnalyzeAPI(discovery.pythonPackages, config);
|
|
45186
|
-
result
|
|
45187
|
-
result.score = Math.max(result.score, pyResult.score);
|
|
45188
|
-
if (pyResult.action === "block" || pyResult.action === "warn" && result.action === "pass") {
|
|
45189
|
-
result.action = pyResult.action;
|
|
45190
|
-
}
|
|
45191
|
-
if (pyResult.freeScansRemaining !== void 0) {
|
|
45192
|
-
result.freeScansRemaining = pyResult.freeScansRemaining;
|
|
45193
|
-
}
|
|
45313
|
+
result = mergeResponses([result, pyResult]);
|
|
45194
45314
|
}
|
|
45195
45315
|
clearSpinner();
|
|
45196
45316
|
dbg(
|
|
@@ -45354,11 +45474,11 @@ function buildInstallArgs(parsed, topLevelSpecs, tree, config) {
|
|
|
45354
45474
|
if (tree.length > 0 && topLevelSpecs.length > 0) {
|
|
45355
45475
|
args = pinTopLevelArgs(args, topLevelSpecs, tree);
|
|
45356
45476
|
}
|
|
45357
|
-
|
|
45358
|
-
|
|
45359
|
-
|
|
45360
|
-
|
|
45361
|
-
|
|
45477
|
+
return injectIgnoreScripts(args, {
|
|
45478
|
+
isNpmFamily: true,
|
|
45479
|
+
strict: config.strict,
|
|
45480
|
+
dgNoScripts: parsed.dgNoScripts
|
|
45481
|
+
});
|
|
45362
45482
|
}
|
|
45363
45483
|
async function scanAndInstallStatic(resolved, parsed, config) {
|
|
45364
45484
|
const topLevelSpecs = resolved.map((p) => `${p.name}@${p.version}`);
|
|
@@ -45387,6 +45507,14 @@ async function scanAndInstallStatic(resolved, parsed, config) {
|
|
|
45387
45507
|
process.stderr.write(
|
|
45388
45508
|
import_chalk5.default.dim(" Only top-level packages would be scanned; transitive deps would slip through. Use --dg-force to bypass.\n\n")
|
|
45389
45509
|
);
|
|
45510
|
+
emitWrapperJson(config, {
|
|
45511
|
+
ecosystem: "npm",
|
|
45512
|
+
packages: [],
|
|
45513
|
+
scanVerdict: "scan_failed",
|
|
45514
|
+
installRan: false,
|
|
45515
|
+
installExitCode: null,
|
|
45516
|
+
error: { code: "tree_resolution_failed", message: treeError }
|
|
45517
|
+
});
|
|
45390
45518
|
process.exit(2);
|
|
45391
45519
|
}
|
|
45392
45520
|
process.stderr.write(
|
|
@@ -45606,6 +45734,42 @@ ${installLine}
|
|
|
45606
45734
|
});
|
|
45607
45735
|
process.exit(2);
|
|
45608
45736
|
}
|
|
45737
|
+
if (result.action === "analysis_incomplete") {
|
|
45738
|
+
const topLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
45739
|
+
const refuse = (config.mode === "block" || config.strict) && !parsed.dgForce;
|
|
45740
|
+
if (refuse) {
|
|
45741
|
+
const specArg = topLevelSpecs.length > 0 ? topLevelSpecs.join(" ") : resolved.map((p) => `${p.name}@${p.version}`).join(" ");
|
|
45742
|
+
process.stderr.write(
|
|
45743
|
+
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG could not verify")} ${topLevel} \u2014 treating as unverified, not safe.
|
|
45744
|
+
Real install was NOT run (--mode block). To override:
|
|
45745
|
+
` + import_chalk5.default.dim(` npm install ${specArg} --dg-force --dg-force-reason="<reason>"
|
|
45746
|
+
|
|
45747
|
+
`)
|
|
45748
|
+
);
|
|
45749
|
+
emitWrapperJson(config, {
|
|
45750
|
+
ecosystem: "npm",
|
|
45751
|
+
packages: wrapperPackagesFromResult(result, new Set(resolved.map((p) => p.name))),
|
|
45752
|
+
scanVerdict: "analysis_incomplete",
|
|
45753
|
+
installRan: false,
|
|
45754
|
+
installExitCode: null
|
|
45755
|
+
});
|
|
45756
|
+
process.exit(4);
|
|
45757
|
+
}
|
|
45758
|
+
process.stderr.write(
|
|
45759
|
+
import_chalk5.default.dim(` DG could not fully verify ${topLevel}; proceeding (mode is not block).
|
|
45760
|
+
|
|
45761
|
+
`)
|
|
45762
|
+
);
|
|
45763
|
+
const code = await runNpm(buildInstallArgs(parsed, topLevelSpecs, tree.packages, config), { stdoutToStderr: !!config.json });
|
|
45764
|
+
emitWrapperJson(config, {
|
|
45765
|
+
ecosystem: "npm",
|
|
45766
|
+
packages: wrapperPackagesFromResult(result, new Set(resolved.map((p) => p.name))),
|
|
45767
|
+
scanVerdict: "analysis_incomplete",
|
|
45768
|
+
installRan: true,
|
|
45769
|
+
installExitCode: code
|
|
45770
|
+
});
|
|
45771
|
+
process.exit(code);
|
|
45772
|
+
}
|
|
45609
45773
|
}
|
|
45610
45774
|
async function runStaticPip(pipArgs, config) {
|
|
45611
45775
|
config = mergeProjectConfig(config, process.argv.slice(2));
|
|
@@ -45695,6 +45859,17 @@ async function runStaticPip(pipArgs, config) {
|
|
|
45695
45859
|
)
|
|
45696
45860
|
);
|
|
45697
45861
|
}
|
|
45862
|
+
const isRequirementsInstall = !!parsed.requirementsFile;
|
|
45863
|
+
if (isRequirementsInstall && !(pipTreeOk && pipTree.hashes.size > 0) && (config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
45864
|
+
process.stderr.write(
|
|
45865
|
+
import_chalk5.default.red(import_chalk5.default.bold(" BLOCKED: ")) + import_chalk5.default.red(`a -r requirements install cannot be pinned to exact versions and no dry-run hashes are available to verify the artifacts.
|
|
45866
|
+
`) + import_chalk5.default.dim(` Install aborted${config.strict ? " in --strict" : " in --mode block"} (resolve\u2192install mismatch risk). Use --mode warn or --dg-force to bypass.
|
|
45867
|
+
|
|
45868
|
+
`)
|
|
45869
|
+
);
|
|
45870
|
+
process.exit(2);
|
|
45871
|
+
}
|
|
45872
|
+
const pipInstallArgs = pinPipArgs(parsed.rawArgs, parsed.packages, resolved);
|
|
45698
45873
|
note(
|
|
45699
45874
|
config,
|
|
45700
45875
|
import_chalk5.default.dim(
|
|
@@ -45723,14 +45898,14 @@ async function runStaticPip(pipArgs, config) {
|
|
|
45723
45898
|
process.stderr.write(
|
|
45724
45899
|
import_chalk5.default.yellow(import_chalk5.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n"))
|
|
45725
45900
|
);
|
|
45726
|
-
const code2 = await runPip(
|
|
45901
|
+
const code2 = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
45727
45902
|
process.exit(code2);
|
|
45728
45903
|
}
|
|
45729
45904
|
process.stderr.write(
|
|
45730
45905
|
import_chalk5.default.yellow(` Warning: Scan failed (${msg}). Proceeding with install (mode=${config.mode}).
|
|
45731
45906
|
`)
|
|
45732
45907
|
);
|
|
45733
|
-
const code = await runPip(
|
|
45908
|
+
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
45734
45909
|
process.exit(code);
|
|
45735
45910
|
return;
|
|
45736
45911
|
}
|
|
@@ -45767,7 +45942,7 @@ ${installLine}
|
|
|
45767
45942
|
`);
|
|
45768
45943
|
printTrialBanner(result, config);
|
|
45769
45944
|
process.stderr.write("\n");
|
|
45770
|
-
const code = await runPip(
|
|
45945
|
+
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
45771
45946
|
emitWrapperJson(config, {
|
|
45772
45947
|
ecosystem: "pypi",
|
|
45773
45948
|
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
@@ -45799,7 +45974,7 @@ ${installLine}
|
|
|
45799
45974
|
});
|
|
45800
45975
|
process.exit(1);
|
|
45801
45976
|
}
|
|
45802
|
-
const code = await runPip(
|
|
45977
|
+
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
45803
45978
|
emitWrapperJson(config, {
|
|
45804
45979
|
ecosystem: "pypi",
|
|
45805
45980
|
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
@@ -45822,7 +45997,7 @@ ${installLine}
|
|
|
45822
45997
|
process.stderr.write(
|
|
45823
45998
|
import_chalk5.default.yellow(import_chalk5.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n"))
|
|
45824
45999
|
);
|
|
45825
|
-
const code = await runPip(
|
|
46000
|
+
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
45826
46001
|
emitWrapperJson(config, {
|
|
45827
46002
|
ecosystem: "pypi",
|
|
45828
46003
|
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
@@ -45857,6 +46032,42 @@ ${installLine}
|
|
|
45857
46032
|
});
|
|
45858
46033
|
process.exit(2);
|
|
45859
46034
|
}
|
|
46035
|
+
if (result.action === "analysis_incomplete") {
|
|
46036
|
+
const pipTopLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
46037
|
+
const refuse = (config.mode === "block" || config.strict) && !parsed.dgForce;
|
|
46038
|
+
if (refuse) {
|
|
46039
|
+
const pipSpecArg = resolved.map((p) => `${p.name}==${p.version}`).join(" ");
|
|
46040
|
+
process.stderr.write(
|
|
46041
|
+
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG could not verify")} ${pipTopLevel} \u2014 treating as unverified, not safe.
|
|
46042
|
+
Real install was NOT run (--mode block). To override:
|
|
46043
|
+
` + import_chalk5.default.dim(` pip install ${pipSpecArg} --dg-force --dg-force-reason="<reason>"
|
|
46044
|
+
|
|
46045
|
+
`)
|
|
46046
|
+
);
|
|
46047
|
+
emitWrapperJson(config, {
|
|
46048
|
+
ecosystem: "pypi",
|
|
46049
|
+
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
46050
|
+
scanVerdict: "analysis_incomplete",
|
|
46051
|
+
installRan: false,
|
|
46052
|
+
installExitCode: null
|
|
46053
|
+
});
|
|
46054
|
+
process.exit(4);
|
|
46055
|
+
}
|
|
46056
|
+
process.stderr.write(
|
|
46057
|
+
import_chalk5.default.dim(` DG could not fully verify ${pipTopLevel}; proceeding (mode is not block).
|
|
46058
|
+
|
|
46059
|
+
`)
|
|
46060
|
+
);
|
|
46061
|
+
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
46062
|
+
emitWrapperJson(config, {
|
|
46063
|
+
ecosystem: "pypi",
|
|
46064
|
+
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
46065
|
+
scanVerdict: "analysis_incomplete",
|
|
46066
|
+
installRan: true,
|
|
46067
|
+
installExitCode: code
|
|
46068
|
+
});
|
|
46069
|
+
process.exit(code);
|
|
46070
|
+
}
|
|
45860
46071
|
}
|
|
45861
46072
|
async function runStaticLogin() {
|
|
45862
46073
|
const {
|
|
@@ -45969,6 +46180,7 @@ var init_static_output = __esm({
|
|
|
45969
46180
|
init_lockfile();
|
|
45970
46181
|
init_npm_wrapper();
|
|
45971
46182
|
init_pip_wrapper();
|
|
46183
|
+
init_wrapper_shared();
|
|
45972
46184
|
init_artifact_integrity();
|
|
45973
46185
|
init_sanitize();
|
|
45974
46186
|
init_format_helpers();
|
|
@@ -46763,11 +46975,11 @@ var init_InteractiveResultsView = __esm({
|
|
|
46763
46975
|
const scanUsage = usageDisplay ? usageDisplay.text : result.freeScansRemaining !== void 0 ? `${result.freeScansRemaining.toLocaleString()} packages left` : scanUsageProp;
|
|
46764
46976
|
const usageNearLimit = usageDisplay?.nearLimit ?? false;
|
|
46765
46977
|
const flagged = (0, import_react30.useMemo)(
|
|
46766
|
-
() => result.packages.filter((p) => p.
|
|
46978
|
+
() => result.packages.filter((p) => (p.action ?? "pass") !== "pass"),
|
|
46767
46979
|
[result.packages]
|
|
46768
46980
|
);
|
|
46769
46981
|
const clean = (0, import_react30.useMemo)(
|
|
46770
|
-
() => result.packages.filter((p) => p.
|
|
46982
|
+
() => result.packages.filter((p) => (p.action ?? "pass") === "pass"),
|
|
46771
46983
|
[result.packages]
|
|
46772
46984
|
);
|
|
46773
46985
|
const total = result.packages.length;
|
|
@@ -47063,8 +47275,8 @@ var init_InteractiveResultsView = __esm({
|
|
|
47063
47275
|
const { body, ext } = formatExport(payload, scope, format);
|
|
47064
47276
|
const scopeTag = scope === "current-license" && currentLicenseIdx !== null ? `${(licenseGroups[currentLicenseIdx]?.spdx ?? "license").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 32)}` : scope;
|
|
47065
47277
|
const filename = `dg-scan-${ts}-${scopeTag}.${ext}`;
|
|
47066
|
-
const
|
|
47067
|
-
writeFileSync11(
|
|
47278
|
+
const path = resolvePath2(process.cwd(), filename);
|
|
47279
|
+
writeFileSync11(path, body, "utf-8");
|
|
47068
47280
|
showExportMsg(`\u2713 Exported to ${filename}`);
|
|
47069
47281
|
} catch (e) {
|
|
47070
47282
|
showExportMsg(`Export failed: ${e.message}`);
|
|
@@ -48461,6 +48673,7 @@ var publish_check_exports = {};
|
|
|
48461
48673
|
__export(publish_check_exports, {
|
|
48462
48674
|
findPypiArtifacts: () => findPypiArtifacts,
|
|
48463
48675
|
npmPackDryRun: () => npmPackDryRun,
|
|
48676
|
+
publishCheckExitCode: () => publishCheckExitCode,
|
|
48464
48677
|
renderPublishCheckResult: () => renderPublishCheckResult,
|
|
48465
48678
|
runNpmPublishCheck: () => runNpmPublishCheck,
|
|
48466
48679
|
runPypiPublishCheck: () => runPypiPublishCheck,
|
|
@@ -48597,6 +48810,12 @@ function summarize(ecosystem, artifact, files, findings) {
|
|
|
48597
48810
|
action
|
|
48598
48811
|
};
|
|
48599
48812
|
}
|
|
48813
|
+
function publishCheckExitCode(action, force) {
|
|
48814
|
+
if (force) return 0;
|
|
48815
|
+
if (action === "block") return 2;
|
|
48816
|
+
if (action === "warn") return 1;
|
|
48817
|
+
return 0;
|
|
48818
|
+
}
|
|
48600
48819
|
async function runNpmPublishCheck(cwd2 = process.cwd()) {
|
|
48601
48820
|
const pack = await npmPackDryRun(cwd2);
|
|
48602
48821
|
if (!pack.ok) return { ok: false, errorMessage: pack.errorMessage };
|
|
@@ -48658,10 +48877,10 @@ function parseTar(buf) {
|
|
|
48658
48877
|
}
|
|
48659
48878
|
return out;
|
|
48660
48879
|
}
|
|
48661
|
-
async function readGzipped(
|
|
48880
|
+
async function readGzipped(path) {
|
|
48662
48881
|
return new Promise((resolve3, reject) => {
|
|
48663
48882
|
const chunks = [];
|
|
48664
|
-
const stream = createReadStream(
|
|
48883
|
+
const stream = createReadStream(path).pipe(createGunzip());
|
|
48665
48884
|
stream.on("data", (c) => chunks.push(c));
|
|
48666
48885
|
stream.on("end", () => resolve3(Buffer.concat(chunks)));
|
|
48667
48886
|
stream.on("error", reject);
|
|
@@ -48894,11 +49113,11 @@ function validateEntry(raw) {
|
|
|
48894
49113
|
};
|
|
48895
49114
|
}
|
|
48896
49115
|
function readRegistry() {
|
|
48897
|
-
const
|
|
48898
|
-
if (!existsSync20(
|
|
49116
|
+
const path = registryPath();
|
|
49117
|
+
if (!existsSync20(path)) return [];
|
|
48899
49118
|
let raw;
|
|
48900
49119
|
try {
|
|
48901
|
-
raw = readFileSync14(
|
|
49120
|
+
raw = readFileSync14(path, "utf-8");
|
|
48902
49121
|
} catch {
|
|
48903
49122
|
return [];
|
|
48904
49123
|
}
|
|
@@ -48919,13 +49138,13 @@ function readRegistry() {
|
|
|
48919
49138
|
return out;
|
|
48920
49139
|
}
|
|
48921
49140
|
function writeRegistry(entries) {
|
|
48922
|
-
const
|
|
48923
|
-
const parent = dirname12(
|
|
49141
|
+
const path = registryPath();
|
|
49142
|
+
const parent = dirname12(path);
|
|
48924
49143
|
if (!existsSync20(parent)) mkdirSync8(parent, { recursive: true, mode: 448 });
|
|
48925
49144
|
const payload = { version: 1, entries };
|
|
48926
|
-
writeFileSync12(
|
|
49145
|
+
writeFileSync12(path, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
48927
49146
|
try {
|
|
48928
|
-
chmodSync4(
|
|
49147
|
+
chmodSync4(path, 384);
|
|
48929
49148
|
} catch {
|
|
48930
49149
|
}
|
|
48931
49150
|
}
|
|
@@ -49524,9 +49743,9 @@ function installPrefix(resolvedBinPath) {
|
|
|
49524
49743
|
if (idx < 0) return null;
|
|
49525
49744
|
return resolvedBinPath.slice(0, idx);
|
|
49526
49745
|
}
|
|
49527
|
-
function canWrite(
|
|
49746
|
+
function canWrite(path) {
|
|
49528
49747
|
try {
|
|
49529
|
-
accessSync(
|
|
49748
|
+
accessSync(path, constants2.W_OK);
|
|
49530
49749
|
return true;
|
|
49531
49750
|
} catch {
|
|
49532
49751
|
return false;
|
|
@@ -49949,9 +50168,9 @@ async function revokeApiKey(apiKey) {
|
|
|
49949
50168
|
return { ok: false, reason: e.message };
|
|
49950
50169
|
}
|
|
49951
50170
|
}
|
|
49952
|
-
function rmFile(
|
|
50171
|
+
function rmFile(path) {
|
|
49953
50172
|
try {
|
|
49954
|
-
unlinkSync7(
|
|
50173
|
+
unlinkSync7(path);
|
|
49955
50174
|
return { ok: true };
|
|
49956
50175
|
} catch (e) {
|
|
49957
50176
|
const code = e.code;
|
|
@@ -49959,9 +50178,9 @@ function rmFile(path2) {
|
|
|
49959
50178
|
return { ok: false, reason: e.message };
|
|
49960
50179
|
}
|
|
49961
50180
|
}
|
|
49962
|
-
function rmTree(
|
|
50181
|
+
function rmTree(path) {
|
|
49963
50182
|
try {
|
|
49964
|
-
rmSync2(
|
|
50183
|
+
rmSync2(path, { recursive: true, force: true });
|
|
49965
50184
|
return { ok: true };
|
|
49966
50185
|
} catch (e) {
|
|
49967
50186
|
return { ok: false, reason: e.message };
|
|
@@ -50950,8 +51169,8 @@ var init_ProjectSelector = __esm({
|
|
|
50950
51169
|
const ecoCountPlainLen = `${proj.ecosystem} ${proj.packageCount} packages`.length;
|
|
50951
51170
|
const fixedPrefixLen = 4;
|
|
50952
51171
|
const pathColWidth = Math.max(20, termCols - fixedPrefixLen - ecoCountPlainLen - 3);
|
|
50953
|
-
const
|
|
50954
|
-
const pathTruncated =
|
|
51172
|
+
const path = sanitize(proj.relativePath);
|
|
51173
|
+
const pathTruncated = path.length > pathColWidth ? path.slice(0, Math.max(1, pathColWidth - 1)) + "\u2026" : path.padEnd(pathColWidth);
|
|
50955
51174
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { backgroundColor: isCursor ? "#1a1a2e" : void 0, wrap: "truncate-end", children: [
|
|
50956
51175
|
prefix,
|
|
50957
51176
|
check,
|
|
@@ -51046,6 +51265,7 @@ var init_App2 = __esm({
|
|
|
51046
51265
|
await init_ProjectSelector();
|
|
51047
51266
|
await init_SetupBanner();
|
|
51048
51267
|
await init_useTerminalSize();
|
|
51268
|
+
init_static_output();
|
|
51049
51269
|
init_terminal_state();
|
|
51050
51270
|
import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
51051
51271
|
App2 = ({ config, userStatus, scanUsage, setupIssues = [] }) => {
|
|
@@ -51084,16 +51304,7 @@ var init_App2 = __esm({
|
|
|
51084
51304
|
}, []);
|
|
51085
51305
|
const handleResultsExit = (0, import_react36.useCallback)(() => {
|
|
51086
51306
|
if (state.phase === "results") {
|
|
51087
|
-
|
|
51088
|
-
if (result.action === "block" && config.mode === "block") {
|
|
51089
|
-
process.exitCode = 2;
|
|
51090
|
-
} else if (result.action === "block" || result.action === "warn") {
|
|
51091
|
-
process.exitCode = 1;
|
|
51092
|
-
} else if (result.action === "analysis_incomplete") {
|
|
51093
|
-
process.exitCode = 4;
|
|
51094
|
-
} else {
|
|
51095
|
-
process.exitCode = 0;
|
|
51096
|
-
}
|
|
51307
|
+
process.exitCode = scanExitCode(state.result.action, config.mode);
|
|
51097
51308
|
}
|
|
51098
51309
|
leaveAltScreen();
|
|
51099
51310
|
exit();
|
|
@@ -51122,7 +51333,10 @@ var init_App2 = __esm({
|
|
|
51122
51333
|
`, 3);
|
|
51123
51334
|
return () => clearTimeout(timer);
|
|
51124
51335
|
}
|
|
51125
|
-
|
|
51336
|
+
if (state.phase === "results") {
|
|
51337
|
+
process.exitCode = scanExitCode(state.result.action, config.mode);
|
|
51338
|
+
}
|
|
51339
|
+
}, [state, config, exitWithMessage]);
|
|
51126
51340
|
use_input_default((input, key) => {
|
|
51127
51341
|
if (state.phase === "discovering" || state.phase === "scanning") {
|
|
51128
51342
|
if (input === "q" || key.escape) {
|
|
@@ -51272,9 +51486,9 @@ function locateInkInstancesPath() {
|
|
|
51272
51486
|
async function initInkInstances() {
|
|
51273
51487
|
if (realInstances) return;
|
|
51274
51488
|
try {
|
|
51275
|
-
const
|
|
51276
|
-
if (!
|
|
51277
|
-
const mod = await import(
|
|
51489
|
+
const path = locateInkInstancesPath();
|
|
51490
|
+
if (!path) return;
|
|
51491
|
+
const mod = await import(path);
|
|
51278
51492
|
realInstances = mod.default ?? null;
|
|
51279
51493
|
} catch {
|
|
51280
51494
|
realInstances = null;
|
|
@@ -51524,6 +51738,8 @@ function reducer4(_state, action) {
|
|
|
51524
51738
|
return { phase: "warn", result: action.result, dgForce: action.dgForce };
|
|
51525
51739
|
case "BLOCKED":
|
|
51526
51740
|
return { phase: "blocked", result: action.result, dgForce: action.dgForce };
|
|
51741
|
+
case "INCOMPLETE":
|
|
51742
|
+
return { phase: "incomplete", result: action.result, message: action.message, proceed: action.proceed };
|
|
51527
51743
|
case "INSTALLING":
|
|
51528
51744
|
return { phase: "installing" };
|
|
51529
51745
|
case "DONE":
|
|
@@ -51558,6 +51774,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51558
51774
|
if (started.current) return;
|
|
51559
51775
|
started.current = true;
|
|
51560
51776
|
const parsed = parsedRef.current;
|
|
51777
|
+
let installArgs = parsed.rawArgs;
|
|
51561
51778
|
(async () => {
|
|
51562
51779
|
try {
|
|
51563
51780
|
if (!parsed.shouldScan) {
|
|
@@ -51586,14 +51803,45 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51586
51803
|
dispatch({ type: "DONE", exitCode: code });
|
|
51587
51804
|
return;
|
|
51588
51805
|
}
|
|
51589
|
-
|
|
51590
|
-
|
|
51806
|
+
const isRequirementsInstall = opts.ecosystem === "pypi" && (parsed.rawArgs.includes("-r") || parsed.rawArgs.includes("--requirement"));
|
|
51807
|
+
if (isRequirementsInstall && (config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
51808
|
+
dispatch({
|
|
51809
|
+
type: "ERROR",
|
|
51810
|
+
message: `A -r requirements install cannot be pinned to the exact scanned versions; refusing in ${config.strict ? "--strict" : "--mode block"} (resolve\u2192install mismatch risk). Use --mode warn or --dg-force to bypass.`,
|
|
51811
|
+
proceed: false
|
|
51812
|
+
});
|
|
51813
|
+
dispatch({ type: "DONE", exitCode: 2 });
|
|
51814
|
+
return;
|
|
51815
|
+
}
|
|
51816
|
+
const pinnedArgs = isRequirementsInstall ? parsed.rawArgs : opts.ecosystem === "npm" ? pinTopLevelArgs(parsed.rawArgs, parsed.packages, resolved) : pinPipArgs(parsed.rawArgs, parsed.packages, resolved);
|
|
51817
|
+
installArgs = injectIgnoreScripts(pinnedArgs, {
|
|
51818
|
+
isNpmFamily: opts.ecosystem === "npm",
|
|
51819
|
+
strict: config.strict,
|
|
51820
|
+
dgNoScripts: parsed.dgNoScripts
|
|
51821
|
+
});
|
|
51822
|
+
let scanSet = resolved;
|
|
51823
|
+
if (opts.resolveTree) {
|
|
51824
|
+
const tree = await opts.resolveTree(specs);
|
|
51825
|
+
if (tree.ok && tree.packages.length > 0) {
|
|
51826
|
+
scanSet = tree.packages;
|
|
51827
|
+
} else if ((config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
51828
|
+
dispatch({
|
|
51829
|
+
type: "ERROR",
|
|
51830
|
+
message: `Could not enumerate the dependency tree (${tree.errorMessage ?? "dry-run produced no tree"}); transitive deps would install unscanned. Install aborted in ${config.strict ? "--strict" : "--mode block"}. Use --dg-force to bypass.`,
|
|
51831
|
+
proceed: false
|
|
51832
|
+
});
|
|
51833
|
+
dispatch({ type: "DONE", exitCode: 2 });
|
|
51834
|
+
return;
|
|
51835
|
+
}
|
|
51836
|
+
}
|
|
51837
|
+
dispatch({ type: "SCANNING", count: scanSet.length });
|
|
51838
|
+
const result = await opts.callAnalyze(scanSet, config);
|
|
51591
51839
|
if (result.action === "pass") {
|
|
51592
51840
|
if (exit) exit();
|
|
51593
51841
|
const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
|
|
51594
51842
|
const line = formatPassLine(result, chalk18);
|
|
51595
51843
|
process.stderr.write(" " + line + "\n\n");
|
|
51596
|
-
const code = await opts.runInstall(
|
|
51844
|
+
const code = await opts.runInstall(installArgs);
|
|
51597
51845
|
process.exit(code);
|
|
51598
51846
|
return;
|
|
51599
51847
|
}
|
|
@@ -51609,7 +51857,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51609
51857
|
});
|
|
51610
51858
|
dispatch({ type: "WARN", result, dgForce: true });
|
|
51611
51859
|
dispatch({ type: "INSTALLING" });
|
|
51612
|
-
const code = await opts.runInstall(
|
|
51860
|
+
const code = await opts.runInstall(installArgs);
|
|
51613
51861
|
dispatch({ type: "DONE", exitCode: code });
|
|
51614
51862
|
return;
|
|
51615
51863
|
}
|
|
@@ -51627,7 +51875,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51627
51875
|
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51628
51876
|
});
|
|
51629
51877
|
dispatch({ type: "INSTALLING" });
|
|
51630
|
-
const code = await opts.runInstall(
|
|
51878
|
+
const code = await opts.runInstall(installArgs);
|
|
51631
51879
|
dispatch({ type: "DONE", exitCode: code });
|
|
51632
51880
|
} else {
|
|
51633
51881
|
dispatch({ type: "DONE", exitCode: 1 });
|
|
@@ -51646,7 +51894,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51646
51894
|
});
|
|
51647
51895
|
dispatch({ type: "BLOCKED", result, dgForce: true });
|
|
51648
51896
|
dispatch({ type: "INSTALLING" });
|
|
51649
|
-
const code = await opts.runInstall(
|
|
51897
|
+
const code = await opts.runInstall(installArgs);
|
|
51650
51898
|
dispatch({ type: "DONE", exitCode: code });
|
|
51651
51899
|
return;
|
|
51652
51900
|
}
|
|
@@ -51664,13 +51912,32 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51664
51912
|
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51665
51913
|
});
|
|
51666
51914
|
dispatch({ type: "INSTALLING" });
|
|
51667
|
-
const code = await opts.runInstall(
|
|
51915
|
+
const code = await opts.runInstall(installArgs);
|
|
51668
51916
|
dispatch({ type: "DONE", exitCode: code });
|
|
51669
51917
|
} else {
|
|
51670
51918
|
dispatch({ type: "DONE", exitCode: 2 });
|
|
51671
51919
|
}
|
|
51672
51920
|
return;
|
|
51673
51921
|
}
|
|
51922
|
+
{
|
|
51923
|
+
const refuseHard = config.mode === "block" || config.strict;
|
|
51924
|
+
const baseMsg = "DG could not fully analyze the install set (analysis incomplete).";
|
|
51925
|
+
if (refuseHard && !parsed.dgForce) {
|
|
51926
|
+
dispatch({
|
|
51927
|
+
type: "INCOMPLETE",
|
|
51928
|
+
result,
|
|
51929
|
+
proceed: false,
|
|
51930
|
+
message: `${baseMsg} Refusing install in ${config.strict ? "--strict" : "--mode block"} \u2014 unverified is not safe. Use --mode warn or --dg-force to bypass.`
|
|
51931
|
+
});
|
|
51932
|
+
dispatch({ type: "DONE", exitCode: 4 });
|
|
51933
|
+
return;
|
|
51934
|
+
}
|
|
51935
|
+
dispatch({ type: "INCOMPLETE", result, proceed: true, message: baseMsg });
|
|
51936
|
+
dispatch({ type: "INSTALLING" });
|
|
51937
|
+
const code = await opts.runInstall(installArgs);
|
|
51938
|
+
dispatch({ type: "DONE", exitCode: code });
|
|
51939
|
+
return;
|
|
51940
|
+
}
|
|
51674
51941
|
} catch (error) {
|
|
51675
51942
|
if (error instanceof FreeCapReachedError) {
|
|
51676
51943
|
dispatch({ type: "FREE_CAP_REACHED" });
|
|
@@ -51688,7 +51955,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51688
51955
|
}
|
|
51689
51956
|
dispatch({ type: "ERROR", message, proceed: true });
|
|
51690
51957
|
dispatch({ type: "INSTALLING" });
|
|
51691
|
-
const code = await opts.runInstall(
|
|
51958
|
+
const code = await opts.runInstall(installArgs);
|
|
51692
51959
|
dispatch({ type: "DONE", exitCode: code });
|
|
51693
51960
|
}
|
|
51694
51961
|
})();
|
|
@@ -51711,11 +51978,13 @@ var init_useWrapperBase = __esm({
|
|
|
51711
51978
|
"use strict";
|
|
51712
51979
|
import_react37 = __toESM(require_react(), 1);
|
|
51713
51980
|
init_client();
|
|
51981
|
+
init_wrapper_shared();
|
|
51714
51982
|
init_npm_wrapper();
|
|
51715
51983
|
init_pip_wrapper();
|
|
51716
51984
|
NPM_OPTIONS = {
|
|
51717
51985
|
parseArgs: parseNpmArgs,
|
|
51718
51986
|
resolvePackages,
|
|
51987
|
+
resolveTree: resolveTreeNpm,
|
|
51719
51988
|
callAnalyze: callAnalyzeAPI,
|
|
51720
51989
|
runInstall: runNpm,
|
|
51721
51990
|
inferSpecsFromContext: () => readBareInstallPackages(process.cwd()),
|
|
@@ -51724,6 +51993,7 @@ var init_useWrapperBase = __esm({
|
|
|
51724
51993
|
PIP_OPTIONS = {
|
|
51725
51994
|
parseArgs: parsePipArgs,
|
|
51726
51995
|
resolvePackages: resolvePackages2,
|
|
51996
|
+
resolveTree: resolveTreePip,
|
|
51727
51997
|
callAnalyze: callPyPIAnalyzeAPI,
|
|
51728
51998
|
runInstall: runPip,
|
|
51729
51999
|
inferSpecsFromContext: (parsed) => {
|
|
@@ -51787,8 +52057,8 @@ var init_ResultsView = __esm({
|
|
|
51787
52057
|
config: _config,
|
|
51788
52058
|
durationMs
|
|
51789
52059
|
}) => {
|
|
51790
|
-
const flagged = result.packages.filter((p) => p.
|
|
51791
|
-
const clean = result.packages.filter((p) => p.
|
|
52060
|
+
const flagged = result.packages.filter((p) => (p.action ?? "pass") !== "pass");
|
|
52061
|
+
const clean = result.packages.filter((p) => (p.action ?? "pass") === "pass");
|
|
51792
52062
|
const total = result.packages.length;
|
|
51793
52063
|
const groups = groupPackages(flagged);
|
|
51794
52064
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
|
|
@@ -51832,7 +52102,7 @@ var init_ResultsView = __esm({
|
|
|
51832
52102
|
import_chalk16.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`)
|
|
51833
52103
|
] }),
|
|
51834
52104
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Newline, {}),
|
|
51835
|
-
groups.filter((g) => g.packages[0].
|
|
52105
|
+
groups.filter((g) => (g.packages[0].action ?? "pass") !== "pass").map((group) => {
|
|
51836
52106
|
const rep = group.packages[0];
|
|
51837
52107
|
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`;
|
|
51838
52108
|
const visibleFindings = rep.findings.filter((f) => f.severity > 1).sort((a, b) => b.severity - a.severity);
|
|
@@ -51943,13 +52213,15 @@ function reasonTag(pkg) {
|
|
|
51943
52213
|
function countSummary(result) {
|
|
51944
52214
|
let block = 0;
|
|
51945
52215
|
let warn = 0;
|
|
52216
|
+
let unknown = 0;
|
|
51946
52217
|
let clean = 0;
|
|
51947
52218
|
for (const p of result.packages) {
|
|
51948
52219
|
if (p.action === "block") block++;
|
|
51949
52220
|
else if (p.action === "warn") warn++;
|
|
52221
|
+
else if (p.action === "analysis_incomplete") unknown++;
|
|
51950
52222
|
else clean++;
|
|
51951
52223
|
}
|
|
51952
|
-
return { block, warn, clean };
|
|
52224
|
+
return { block, warn, unknown, clean };
|
|
51953
52225
|
}
|
|
51954
52226
|
var import_jsx_runtime17, WrapperVerdictLine;
|
|
51955
52227
|
var init_WrapperVerdictLine = __esm({
|
|
@@ -52020,6 +52292,7 @@ var init_WrapperVerdictLine = __esm({
|
|
|
52020
52292
|
const parts = [];
|
|
52021
52293
|
if (counts.block > 0) parts.push(`${counts.block} block`);
|
|
52022
52294
|
if (counts.warn > 0) parts.push(`${counts.warn} warn`);
|
|
52295
|
+
if (counts.unknown > 0) parts.push(`${counts.unknown} unknown`);
|
|
52023
52296
|
if (counts.clean > 0) parts.push(`${counts.clean} clean`);
|
|
52024
52297
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
52025
52298
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { color, children: [
|
|
@@ -52118,6 +52391,14 @@ var init_WrapperApp = __esm({
|
|
|
52118
52391
|
showDetails && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ResultsView, { result: state.result, config, durationMs: state.result.durationMs }) }),
|
|
52119
52392
|
!state.dgForce && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ConfirmPrompt, { message: "", onConfirm: handleConfirm, onReject: handleReject })
|
|
52120
52393
|
] });
|
|
52394
|
+
case "incomplete":
|
|
52395
|
+
if (state.proceed) {
|
|
52396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { color: "yellow", children: [
|
|
52397
|
+
state.message,
|
|
52398
|
+
" Proceeding with install."
|
|
52399
|
+
] });
|
|
52400
|
+
}
|
|
52401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorView, { error: new Error(state.message) });
|
|
52121
52402
|
case "installing":
|
|
52122
52403
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner2, { label: labels.installing });
|
|
52123
52404
|
case "done":
|
|
@@ -52197,26 +52478,33 @@ function parseCondaArgs(args) {
|
|
|
52197
52478
|
async function resolveTopLevel(_parsed) {
|
|
52198
52479
|
return { resolved: [], failed: [] };
|
|
52199
52480
|
}
|
|
52200
|
-
async function runStaticConda(args) {
|
|
52481
|
+
async function runStaticConda(args, ecosystem, config) {
|
|
52201
52482
|
const parsed = parseCondaArgs(args);
|
|
52202
|
-
if (
|
|
52483
|
+
if (parsed.shouldScan && (config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
52484
|
+
process.stderr.write(
|
|
52485
|
+
import_chalk18.default.red(import_chalk18.default.bold(" \u2717 BLOCKED: ")) + import_chalk18.default.red(`${ecosystem} packages cannot be scanned (the scanner backend does not support this ecosystem).
|
|
52486
|
+
`) + import_chalk18.default.dim(` --mode ${config.strict ? "strict" : "block"} \u21D2 refusing to install unscanned packages. Use --mode warn or --dg-force to bypass.
|
|
52487
|
+
|
|
52488
|
+
`)
|
|
52489
|
+
);
|
|
52490
|
+
return 2;
|
|
52491
|
+
}
|
|
52492
|
+
if (parsed.shouldScan && process.stderr.isTTY) {
|
|
52203
52493
|
process.stderr.write(
|
|
52204
|
-
import_chalk18.default.yellow(`\u2139\uFE0F DG:
|
|
52205
|
-
`) + import_chalk18.default.dim(` Passing through to real
|
|
52494
|
+
import_chalk18.default.yellow(`\u2139\uFE0F DG: ${ecosystem} packages aren't yet scanned (the scanner backend doesn't support this ecosystem yet).
|
|
52495
|
+
`) + import_chalk18.default.dim(` Passing through to real ${ecosystem}. Use \`dg verify\` for individual pypi-known packages.
|
|
52206
52496
|
|
|
52207
52497
|
`)
|
|
52208
52498
|
);
|
|
52209
52499
|
}
|
|
52210
|
-
const real = resolveRealBinary(
|
|
52500
|
+
const real = resolveRealBinary(ecosystem);
|
|
52211
52501
|
if (!real) {
|
|
52212
|
-
process.stderr.write(`dg: real
|
|
52502
|
+
process.stderr.write(`dg: real ${ecosystem} not found on PATH
|
|
52213
52503
|
`);
|
|
52214
52504
|
return 127;
|
|
52215
52505
|
}
|
|
52216
|
-
const nonce = readNonce();
|
|
52217
|
-
const env3 = nonce ? { ...process.env, DG_SHIM_ACTIVE: nonce } : { ...process.env };
|
|
52218
52506
|
return await new Promise((resolve3) => {
|
|
52219
|
-
const child = spawn5(real, parsed.rawArgs, { stdio: "inherit", env:
|
|
52507
|
+
const child = spawn5(real, parsed.rawArgs, { stdio: "inherit", env: childInstallEnv() });
|
|
52220
52508
|
child.on("close", (code) => resolve3(code ?? 1));
|
|
52221
52509
|
child.on("error", () => resolve3(1));
|
|
52222
52510
|
});
|
|
@@ -52596,7 +52884,11 @@ function parseUvArgs(args) {
|
|
|
52596
52884
|
for (let i = argStart; i < filtered.length; i++) {
|
|
52597
52885
|
const arg = filtered[i];
|
|
52598
52886
|
if (arg === "-r" || arg === "--requirement") {
|
|
52599
|
-
|
|
52887
|
+
const file = filtered[i + 1];
|
|
52888
|
+
if (file !== void 0) {
|
|
52889
|
+
i++;
|
|
52890
|
+
packages.push(...parseRequirementsFile(file));
|
|
52891
|
+
}
|
|
52600
52892
|
continue;
|
|
52601
52893
|
}
|
|
52602
52894
|
if (arg.startsWith("-")) {
|
|
@@ -52757,9 +53049,7 @@ function emitJson(config, result) {
|
|
|
52757
53049
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
52758
53050
|
}
|
|
52759
53051
|
function shimSentinelEnv3() {
|
|
52760
|
-
|
|
52761
|
-
if (!nonce) return process.env;
|
|
52762
|
-
return { ...process.env, DG_SHIM_ACTIVE: nonce };
|
|
53052
|
+
return childInstallEnv();
|
|
52763
53053
|
}
|
|
52764
53054
|
async function spawnRealBinary(adapter7, args) {
|
|
52765
53055
|
const real = resolveRealBinary(adapter7.realBinaryName);
|
|
@@ -52804,8 +53094,46 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
52804
53094
|
`)
|
|
52805
53095
|
);
|
|
52806
53096
|
}
|
|
53097
|
+
const isRequirementsInstall = adapter7.apiKind === "pypi" && (parsed.rawArgs.includes("-r") || parsed.rawArgs.includes("--requirement"));
|
|
53098
|
+
let pinnedArgs = parsed.rawArgs;
|
|
53099
|
+
if (adapter7.apiKind === "npm") {
|
|
53100
|
+
pinnedArgs = pinTopLevelArgs(parsed.rawArgs, parsed.packages, resolved);
|
|
53101
|
+
} else if (!isRequirementsInstall) {
|
|
53102
|
+
pinnedArgs = pinPipArgs(parsed.rawArgs, parsed.packages, resolved);
|
|
53103
|
+
}
|
|
53104
|
+
if (isRequirementsInstall && (config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
53105
|
+
if (!config.json && !config.quiet) {
|
|
53106
|
+
process.stderr.write(
|
|
53107
|
+
import_chalk19.default.red(import_chalk19.default.bold(" \u2717 BLOCKED: ")) + import_chalk19.default.red(`a -r requirements install cannot be pinned to the exact scanned versions.
|
|
53108
|
+
`) + import_chalk19.default.dim(` --mode ${config.strict ? "strict" : "block"} \u21D2 refusing (would risk a resolve\u2192install mismatch). Use --mode warn or --dg-force to bypass.
|
|
53109
|
+
|
|
53110
|
+
`)
|
|
53111
|
+
);
|
|
53112
|
+
}
|
|
53113
|
+
emitJson(config, {
|
|
53114
|
+
ecosystem: adapter7.ecosystem,
|
|
53115
|
+
packages: [],
|
|
53116
|
+
scanVerdict: "scan_failed",
|
|
53117
|
+
installRan: false,
|
|
53118
|
+
installExitCode: null,
|
|
53119
|
+
error: { code: "unpinnable_requirements", message: "-r requirements install cannot be pinned to exact versions" }
|
|
53120
|
+
});
|
|
53121
|
+
return 2;
|
|
53122
|
+
}
|
|
53123
|
+
if (isRequirementsInstall && !config.json && !config.quiet) {
|
|
53124
|
+
process.stderr.write(
|
|
53125
|
+
import_chalk19.default.dim(` Note: -r requirements install cannot be pinned to exact versions; installing as specified.
|
|
53126
|
+
`)
|
|
53127
|
+
);
|
|
53128
|
+
}
|
|
53129
|
+
const installArgs = injectIgnoreScripts(pinnedArgs, {
|
|
53130
|
+
isNpmFamily: adapter7.apiKind === "npm",
|
|
53131
|
+
strict: config.strict,
|
|
53132
|
+
dgNoScripts: parsed.dgNoScripts
|
|
53133
|
+
});
|
|
52807
53134
|
let scanSet = resolved;
|
|
52808
53135
|
let treeOk = true;
|
|
53136
|
+
let treeError;
|
|
52809
53137
|
if (adapter7.resolveTransitive) {
|
|
52810
53138
|
const tree = await adapter7.resolveTransitive(parsed);
|
|
52811
53139
|
if (tree.ok && tree.packages.length > 0) {
|
|
@@ -52825,15 +53153,36 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
52825
53153
|
`)
|
|
52826
53154
|
);
|
|
52827
53155
|
}
|
|
52828
|
-
} else if (!tree.ok
|
|
53156
|
+
} else if (!tree.ok) {
|
|
52829
53157
|
treeOk = false;
|
|
53158
|
+
treeError = tree.errorMessage ?? "unknown";
|
|
53159
|
+
}
|
|
53160
|
+
}
|
|
53161
|
+
if (!treeOk && (config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
53162
|
+
if (!config.json && !config.quiet) {
|
|
52830
53163
|
process.stderr.write(
|
|
52831
|
-
import_chalk19.default.
|
|
53164
|
+
import_chalk19.default.red(import_chalk19.default.bold(" \u2717 BLOCKED: ")) + import_chalk19.default.red(`could not enumerate transitive dependencies (${treeError}); they would install unscanned.
|
|
53165
|
+
`) + import_chalk19.default.dim(` --mode block \u21D2 refusing install. Use --mode warn or --dg-force to bypass.
|
|
53166
|
+
|
|
52832
53167
|
`)
|
|
52833
53168
|
);
|
|
52834
53169
|
}
|
|
53170
|
+
emitJson(config, {
|
|
53171
|
+
ecosystem: adapter7.ecosystem,
|
|
53172
|
+
packages: [],
|
|
53173
|
+
scanVerdict: "scan_failed",
|
|
53174
|
+
installRan: false,
|
|
53175
|
+
installExitCode: null,
|
|
53176
|
+
error: { code: "tree_resolution_failed", message: treeError ?? "transitive resolution failed" }
|
|
53177
|
+
});
|
|
53178
|
+
return 2;
|
|
53179
|
+
}
|
|
53180
|
+
if (!treeOk && !config.json && !config.quiet) {
|
|
53181
|
+
process.stderr.write(
|
|
53182
|
+
import_chalk19.default.dim(` Transitive resolution unavailable (${treeError}); scanning top-level only.
|
|
53183
|
+
`)
|
|
53184
|
+
);
|
|
52835
53185
|
}
|
|
52836
|
-
void treeOk;
|
|
52837
53186
|
let result;
|
|
52838
53187
|
try {
|
|
52839
53188
|
if (adapter7.apiKind === "npm") {
|
|
@@ -52859,10 +53208,10 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
52859
53208
|
});
|
|
52860
53209
|
return 1;
|
|
52861
53210
|
}
|
|
52862
|
-
if (config.mode === "block" && !parsed.dgForce) {
|
|
53211
|
+
if ((config.mode === "block" || config.strict) && !parsed.dgForce) {
|
|
52863
53212
|
process.stderr.write(
|
|
52864
53213
|
import_chalk19.default.red(` \u2717 DG scan failed: ${err.message}
|
|
52865
|
-
`) + import_chalk19.default.dim(` --mode block + scan failure \u21D2 refusing install. Use --mode warn or --dg-force to bypass.
|
|
53214
|
+
`) + import_chalk19.default.dim(` --mode ${config.strict ? "strict" : "block"} + scan failure \u21D2 refusing install. Use --mode warn or --dg-force to bypass.
|
|
52866
53215
|
|
|
52867
53216
|
`)
|
|
52868
53217
|
);
|
|
@@ -52874,7 +53223,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
52874
53223
|
installExitCode: null,
|
|
52875
53224
|
error: { code: "scan_failed", message: err.message }
|
|
52876
53225
|
});
|
|
52877
|
-
return
|
|
53226
|
+
return 2;
|
|
52878
53227
|
}
|
|
52879
53228
|
if (!config.json && !config.quiet) {
|
|
52880
53229
|
process.stderr.write(
|
|
@@ -52882,7 +53231,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
52882
53231
|
`)
|
|
52883
53232
|
);
|
|
52884
53233
|
}
|
|
52885
|
-
const code2 = await spawnRealBinary(adapter7,
|
|
53234
|
+
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
52886
53235
|
emitJson(config, {
|
|
52887
53236
|
ecosystem: adapter7.ecosystem,
|
|
52888
53237
|
packages: [],
|
|
@@ -52911,7 +53260,7 @@ ${installLine}
|
|
|
52911
53260
|
}
|
|
52912
53261
|
process.stderr.write("\n");
|
|
52913
53262
|
}
|
|
52914
|
-
const code2 = await spawnRealBinary(adapter7,
|
|
53263
|
+
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
52915
53264
|
emitJson(config, {
|
|
52916
53265
|
ecosystem: adapter7.ecosystem,
|
|
52917
53266
|
packages: packagesFromResult(result, topLevelNames),
|
|
@@ -52958,7 +53307,7 @@ ${installLine}
|
|
|
52958
53307
|
} else if (!config.json && !config.quiet) {
|
|
52959
53308
|
process.stderr.write(import_chalk19.default.dim(" Proceeding (non-interactive).\n"));
|
|
52960
53309
|
}
|
|
52961
|
-
const code2 = await spawnRealBinary(adapter7,
|
|
53310
|
+
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
52962
53311
|
emitJson(config, {
|
|
52963
53312
|
ecosystem: adapter7.ecosystem,
|
|
52964
53313
|
packages: packagesFromResult(result, topLevelNames),
|
|
@@ -52986,7 +53335,7 @@ ${installLine}
|
|
|
52986
53335
|
|
|
52987
53336
|
`));
|
|
52988
53337
|
}
|
|
52989
|
-
const code2 = await spawnRealBinary(adapter7,
|
|
53338
|
+
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
52990
53339
|
emitJson(config, {
|
|
52991
53340
|
ecosystem: adapter7.ecosystem,
|
|
52992
53341
|
packages: packagesFromResult(result, topLevelNames),
|
|
@@ -53024,11 +53373,38 @@ ${installLine}
|
|
|
53024
53373
|
});
|
|
53025
53374
|
return 2;
|
|
53026
53375
|
}
|
|
53027
|
-
const
|
|
53376
|
+
const refuseHard = config.mode === "block" || config.strict;
|
|
53377
|
+
const unverifiedList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53378
|
+
if (refuseHard && !parsed.dgForce) {
|
|
53379
|
+
if (!config.json) {
|
|
53380
|
+
process.stderr.write(
|
|
53381
|
+
` ${import_chalk19.default.red("\u2717")} ${import_chalk19.default.bold("DG could not verify")} ${unverifiedList} \u2014 analysis incomplete.
|
|
53382
|
+
` + import_chalk19.default.dim(` --mode ${config.strict ? "strict" : "block"} \u21D2 refusing install (unverified is not safe). Use --mode warn or --dg-force to bypass.
|
|
53383
|
+
|
|
53384
|
+
`)
|
|
53385
|
+
);
|
|
53386
|
+
}
|
|
53387
|
+
emitJson(config, {
|
|
53388
|
+
ecosystem: adapter7.ecosystem,
|
|
53389
|
+
packages: packagesFromResult(result, topLevelNames),
|
|
53390
|
+
scanVerdict: "analysis_incomplete",
|
|
53391
|
+
installRan: false,
|
|
53392
|
+
installExitCode: null,
|
|
53393
|
+
error: { code: "analysis_incomplete", message: "scanner could not fully analyze the install set" }
|
|
53394
|
+
});
|
|
53395
|
+
return 4;
|
|
53396
|
+
}
|
|
53397
|
+
if (!config.json && !config.quiet) {
|
|
53398
|
+
process.stderr.write(
|
|
53399
|
+
import_chalk19.default.yellow(` \u26A0 DG could not fully verify ${unverifiedList} (analysis incomplete). Proceeding with install (mode=${config.mode}).
|
|
53400
|
+
`)
|
|
53401
|
+
);
|
|
53402
|
+
}
|
|
53403
|
+
const code = await spawnRealBinary(adapter7, installArgs);
|
|
53028
53404
|
emitJson(config, {
|
|
53029
53405
|
ecosystem: adapter7.ecosystem,
|
|
53030
53406
|
packages: packagesFromResult(result, topLevelNames),
|
|
53031
|
-
scanVerdict: "
|
|
53407
|
+
scanVerdict: "analysis_incomplete",
|
|
53032
53408
|
installRan: true,
|
|
53033
53409
|
installExitCode: code
|
|
53034
53410
|
});
|
|
@@ -53044,6 +53420,9 @@ var init_wrapper_factory = __esm({
|
|
|
53044
53420
|
init_install();
|
|
53045
53421
|
init_audit_dispatcher();
|
|
53046
53422
|
init_allowlist();
|
|
53423
|
+
init_wrapper_shared();
|
|
53424
|
+
init_npm_wrapper();
|
|
53425
|
+
init_pip_wrapper();
|
|
53047
53426
|
}
|
|
53048
53427
|
});
|
|
53049
53428
|
|
|
@@ -53264,7 +53643,7 @@ async function main() {
|
|
|
53264
53643
|
const v = args[ecoArgIdx + 1];
|
|
53265
53644
|
if (v === "npm" || v === "pypi") ecosystem = v;
|
|
53266
53645
|
}
|
|
53267
|
-
const { runNpmPublishCheck: runNpmPublishCheck2, runPypiPublishCheck: runPypiPublishCheck2, renderPublishCheckResult: renderPublishCheckResult2 } = await Promise.resolve().then(() => (init_publish_check(), publish_check_exports));
|
|
53646
|
+
const { runNpmPublishCheck: runNpmPublishCheck2, runPypiPublishCheck: runPypiPublishCheck2, renderPublishCheckResult: renderPublishCheckResult2, publishCheckExitCode: publishCheckExitCode2 } = await Promise.resolve().then(() => (init_publish_check(), publish_check_exports));
|
|
53268
53647
|
const { existsSync: existsSync25 } = await import("node:fs");
|
|
53269
53648
|
const { join: join15 } = await import("node:path");
|
|
53270
53649
|
if (ecosystem === "auto") {
|
|
@@ -53294,7 +53673,7 @@ async function main() {
|
|
|
53294
53673
|
} else {
|
|
53295
53674
|
process.stderr.write(renderPublishCheckResult2(result));
|
|
53296
53675
|
}
|
|
53297
|
-
if (result.action === "block"
|
|
53676
|
+
if (result.action === "block") {
|
|
53298
53677
|
try {
|
|
53299
53678
|
const reasonIdx = args.indexOf("--dg-force-reason");
|
|
53300
53679
|
const bypassReason = reasonIdx >= 0 ? args[reasonIdx + 1] : void 0;
|
|
@@ -53314,9 +53693,7 @@ async function main() {
|
|
|
53314
53693
|
} catch {
|
|
53315
53694
|
}
|
|
53316
53695
|
}
|
|
53317
|
-
|
|
53318
|
-
if (result.action === "analysis_incomplete") process.exit(4);
|
|
53319
|
-
process.exit(0);
|
|
53696
|
+
process.exit(publishCheckExitCode2(result.action, force));
|
|
53320
53697
|
}
|
|
53321
53698
|
if (rawCommand === "hook") {
|
|
53322
53699
|
const { handleHookCommand: handleHookCommand2 } = await Promise.resolve().then(() => (init_hook(), hook_exports));
|
|
@@ -53520,10 +53897,8 @@ async function handleWrapInternal(argv) {
|
|
|
53520
53897
|
const ecoTyped = ecosystem;
|
|
53521
53898
|
const spawnReal = async (real, args) => {
|
|
53522
53899
|
const { spawn: spawn7 } = await import("node:child_process");
|
|
53523
|
-
const {
|
|
53524
|
-
const
|
|
53525
|
-
const env3 = nonce ? { ...process.env, DG_SHIM_ACTIVE: nonce } : { ...process.env };
|
|
53526
|
-
const child = spawn7(real, args, { stdio: "inherit", env: env3 });
|
|
53900
|
+
const { childInstallEnv: childInstallEnv2 } = await Promise.resolve().then(() => (init_install(), install_exports));
|
|
53901
|
+
const child = spawn7(real, args, { stdio: "inherit", env: childInstallEnv2() });
|
|
53527
53902
|
return await new Promise((resolve3) => {
|
|
53528
53903
|
child.on("close", (code) => resolve3(code ?? 1));
|
|
53529
53904
|
child.on("error", () => resolve3(1));
|
|
@@ -53573,7 +53948,7 @@ async function handleWrapInternal(argv) {
|
|
|
53573
53948
|
}
|
|
53574
53949
|
if (ecosystem === "conda" || ecosystem === "mamba") {
|
|
53575
53950
|
const { runStaticConda: runStaticConda2 } = await Promise.resolve().then(() => (init_conda_wrapper(), conda_wrapper_exports));
|
|
53576
|
-
return await runStaticConda2(wrapperArgs);
|
|
53951
|
+
return await runStaticConda2(wrapperArgs, ecosystem, config);
|
|
53577
53952
|
}
|
|
53578
53953
|
const adapterImports = {
|
|
53579
53954
|
pnpm: () => Promise.resolve().then(() => (init_pnpm_wrapper(), pnpm_wrapper_exports)),
|