@westbayberry/dg 1.0.53 → 1.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/index.mjs +249 -114
- package/dist/packages/cli/src/alt-screen.js +36 -0
- package/dist/packages/cli/src/api.js +322 -0
- package/dist/packages/cli/src/auth.js +218 -0
- package/dist/packages/cli/src/bin.js +386 -0
- package/dist/packages/cli/src/config.js +228 -0
- package/dist/packages/cli/src/discover.js +126 -0
- package/dist/packages/cli/src/first-run.js +135 -0
- package/dist/packages/cli/src/hook.js +360 -0
- package/dist/packages/cli/src/lockfile.js +303 -0
- package/dist/packages/cli/src/npm-wrapper.js +218 -0
- package/dist/packages/cli/src/pip-wrapper.js +273 -0
- package/dist/packages/cli/src/sanitize.js +38 -0
- package/dist/packages/cli/src/scan-core.js +144 -0
- package/dist/packages/cli/src/setup-status.js +46 -0
- package/dist/packages/cli/src/static-output.js +625 -0
- package/dist/packages/cli/src/telemetry.js +141 -0
- package/dist/packages/cli/src/ui/App.js +137 -0
- package/dist/packages/cli/src/ui/InitApp.js +391 -0
- package/dist/packages/cli/src/ui/LoginApp.js +51 -0
- package/dist/packages/cli/src/ui/NpmWrapperApp.js +73 -0
- package/dist/packages/cli/src/ui/PipWrapperApp.js +72 -0
- package/dist/packages/cli/src/ui/components/ConfirmPrompt.js +24 -0
- package/dist/packages/cli/src/ui/components/DemoScanAnimation.js +26 -0
- package/dist/packages/cli/src/ui/components/DurationLine.js +7 -0
- package/dist/packages/cli/src/ui/components/ErrorView.js +30 -0
- package/dist/packages/cli/src/ui/components/FileSavePrompt.js +210 -0
- package/dist/packages/cli/src/ui/components/InteractiveResultsView.js +557 -0
- package/dist/packages/cli/src/ui/components/Mascot.js +33 -0
- package/dist/packages/cli/src/ui/components/ProgressBar.js +51 -0
- package/dist/packages/cli/src/ui/components/ProgressDots.js +35 -0
- package/dist/packages/cli/src/ui/components/ProjectSelector.js +60 -0
- package/dist/packages/cli/src/ui/components/ResultsView.js +105 -0
- package/dist/packages/cli/src/ui/components/ScanResultCard.js +54 -0
- package/dist/packages/cli/src/ui/components/ScoreHeader.js +142 -0
- package/dist/packages/cli/src/ui/components/SetupBanner.js +17 -0
- package/dist/packages/cli/src/ui/components/Spinner.js +11 -0
- package/dist/packages/cli/src/ui/hooks/useExpandAnimation.js +44 -0
- package/dist/packages/cli/src/ui/hooks/useInit.js +341 -0
- package/dist/packages/cli/src/ui/hooks/useLogin.js +121 -0
- package/dist/packages/cli/src/ui/hooks/useNpmWrapper.js +192 -0
- package/dist/packages/cli/src/ui/hooks/usePipWrapper.js +195 -0
- package/dist/packages/cli/src/ui/hooks/useScan.js +202 -0
- package/dist/packages/cli/src/ui/hooks/useTerminalSize.js +29 -0
- package/dist/packages/cli/src/update-check.js +152 -0
- package/dist/packages/cli/src/wizard-demo-data.js +63 -0
- package/dist/src/ecosystem.js +2 -0
- package/dist/src/lockfile/diff.js +38 -0
- package/dist/src/lockfile/parse_package_json.js +41 -0
- package/dist/src/lockfile/parse_package_lock.js +55 -0
- package/dist/src/lockfile/parse_pipfile_lock.js +69 -0
- package/dist/src/lockfile/parse_pnpm_lock.js +62 -0
- package/dist/src/lockfile/parse_poetry_lock.js +71 -0
- package/dist/src/lockfile/parse_requirements.js +83 -0
- package/dist/src/lockfile/parse_yarn_lock.js +66 -0
- package/dist/src/logger.js +21 -0
- package/dist/src/npm/h2pool.js +161 -0
- package/dist/src/npm/registry.js +299 -0
- package/dist/src/npm/tarball.js +274 -0
- package/dist/src/pypi/registry.js +299 -0
- package/dist/src/pypi/tarball.js +361 -0
- package/dist/src/types.js +2 -0
- package/package.json +6 -3
package/dist/index.mjs
CHANGED
|
@@ -46241,9 +46241,10 @@ __export(auth_exports, {
|
|
|
46241
46241
|
maskKey: () => maskKey,
|
|
46242
46242
|
openBrowser: () => openBrowser,
|
|
46243
46243
|
pollAuthSession: () => pollAuthSession,
|
|
46244
|
-
saveCredentials: () => saveCredentials
|
|
46244
|
+
saveCredentials: () => saveCredentials,
|
|
46245
|
+
scrubAuthToken: () => scrubAuthToken
|
|
46245
46246
|
});
|
|
46246
|
-
import { readFileSync as readFileSync2, writeFileSync, unlinkSync, existsSync as existsSync2, chmodSync } from "node:fs";
|
|
46247
|
+
import { readFileSync as readFileSync2, writeFileSync, unlinkSync, existsSync as existsSync2, chmodSync, lstatSync, openSync, fchmodSync, closeSync, constants as fsConstants } from "node:fs";
|
|
46247
46248
|
import { join as join4 } from "node:path";
|
|
46248
46249
|
import { homedir } from "node:os";
|
|
46249
46250
|
import { spawn } from "node:child_process";
|
|
@@ -46296,7 +46297,47 @@ async function pollAuthSession(sessionId) {
|
|
|
46296
46297
|
function configPath() {
|
|
46297
46298
|
return join4(homedir(), CONFIG_FILE);
|
|
46298
46299
|
}
|
|
46300
|
+
function ensureConfigPerms(path2) {
|
|
46301
|
+
let st;
|
|
46302
|
+
try {
|
|
46303
|
+
st = lstatSync(path2);
|
|
46304
|
+
} catch {
|
|
46305
|
+
return;
|
|
46306
|
+
}
|
|
46307
|
+
if (!st || typeof st.isSymbolicLink !== "function") return;
|
|
46308
|
+
if (st.isSymbolicLink()) {
|
|
46309
|
+
process.stderr.write(
|
|
46310
|
+
`Warning: ${path2} is a symlink; refusing to chmod (would affect the symlink target). Replace with a regular file to enforce 0o600.
|
|
46311
|
+
`
|
|
46312
|
+
);
|
|
46313
|
+
return;
|
|
46314
|
+
}
|
|
46315
|
+
if (typeof st.isFile === "function" && !st.isFile()) return;
|
|
46316
|
+
const mode = (st.mode ?? 384) & 511;
|
|
46317
|
+
if (mode === 384) return;
|
|
46318
|
+
process.stderr.write(
|
|
46319
|
+
`Warning: ${path2} has perms 0o${mode.toString(8)} (expected 0o600); re-tightening.
|
|
46320
|
+
`
|
|
46321
|
+
);
|
|
46322
|
+
let fd;
|
|
46323
|
+
try {
|
|
46324
|
+
fd = openSync(path2, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
46325
|
+
fchmodSync(fd, 384);
|
|
46326
|
+
} catch {
|
|
46327
|
+
} finally {
|
|
46328
|
+
if (fd !== void 0) {
|
|
46329
|
+
try {
|
|
46330
|
+
closeSync(fd);
|
|
46331
|
+
} catch {
|
|
46332
|
+
}
|
|
46333
|
+
}
|
|
46334
|
+
}
|
|
46335
|
+
}
|
|
46336
|
+
function scrubAuthToken(s) {
|
|
46337
|
+
return s.replace(/\bdgk_[A-Za-z0-9]{16,}\b/g, "dgk_<REDACTED>").replace(/\bBearer\s+[A-Za-z0-9_.-]{24,}\b/g, "Bearer <REDACTED>");
|
|
46338
|
+
}
|
|
46299
46339
|
function readConfig() {
|
|
46340
|
+
ensureConfigPerms(configPath());
|
|
46300
46341
|
let raw;
|
|
46301
46342
|
try {
|
|
46302
46343
|
raw = readFileSync2(configPath(), "utf-8");
|
|
@@ -46418,20 +46459,65 @@ var config_exports = {};
|
|
|
46418
46459
|
__export(config_exports, {
|
|
46419
46460
|
USAGE: () => USAGE,
|
|
46420
46461
|
getVersion: () => getVersion,
|
|
46421
|
-
parseConfig: () => parseConfig
|
|
46462
|
+
parseConfig: () => parseConfig,
|
|
46463
|
+
warnUnknownDgrcKeys: () => warnUnknownDgrcKeys
|
|
46422
46464
|
});
|
|
46423
46465
|
import { parseArgs } from "node:util";
|
|
46424
46466
|
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "node:fs";
|
|
46425
46467
|
import { join as join5, dirname as dirname3 } from "node:path";
|
|
46426
46468
|
import { fileURLToPath } from "node:url";
|
|
46427
46469
|
import { homedir as homedir2 } from "node:os";
|
|
46470
|
+
function levenshtein(a, b) {
|
|
46471
|
+
if (a === b) return 0;
|
|
46472
|
+
if (a.length === 0) return b.length;
|
|
46473
|
+
if (b.length === 0) return a.length;
|
|
46474
|
+
const m = a.length;
|
|
46475
|
+
const n = b.length;
|
|
46476
|
+
let prev = Array.from({ length: n + 1 }, (_, i) => i);
|
|
46477
|
+
let curr = new Array(n + 1);
|
|
46478
|
+
for (let i = 1; i <= m; i++) {
|
|
46479
|
+
curr[0] = i;
|
|
46480
|
+
for (let j = 1; j <= n; j++) {
|
|
46481
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
46482
|
+
curr[j] = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost);
|
|
46483
|
+
}
|
|
46484
|
+
[prev, curr] = [curr, prev];
|
|
46485
|
+
}
|
|
46486
|
+
return prev[n];
|
|
46487
|
+
}
|
|
46488
|
+
function warnUnknownDgrcKeys(parsed, source) {
|
|
46489
|
+
for (const key of Object.keys(parsed)) {
|
|
46490
|
+
if (KNOWN_DGRC_KEYS.includes(key)) continue;
|
|
46491
|
+
if (INTERNAL_DGRC_KEYS.includes(key)) continue;
|
|
46492
|
+
let bestKey = null;
|
|
46493
|
+
let bestDistance = Infinity;
|
|
46494
|
+
for (const known of KNOWN_DGRC_KEYS) {
|
|
46495
|
+
const d = levenshtein(key, known);
|
|
46496
|
+
if (d < bestDistance) {
|
|
46497
|
+
bestDistance = d;
|
|
46498
|
+
bestKey = known;
|
|
46499
|
+
}
|
|
46500
|
+
}
|
|
46501
|
+
const suggestion = bestKey && bestDistance <= 2 ? ` (did you mean "${bestKey}"?)` : ` (valid keys: ${KNOWN_DGRC_KEYS.join(", ")})`;
|
|
46502
|
+
process.stderr.write(
|
|
46503
|
+
`Warning: unknown key "${key}" in ${source}${suggestion}; ignored.
|
|
46504
|
+
`
|
|
46505
|
+
);
|
|
46506
|
+
}
|
|
46507
|
+
}
|
|
46428
46508
|
function loadDgrc() {
|
|
46429
46509
|
const cwdPath = join5(process.cwd(), ".dgrc.json");
|
|
46430
46510
|
const homePath = join5(homedir2(), ".dgrc.json");
|
|
46431
46511
|
let config3 = {};
|
|
46432
46512
|
if (existsSync3(homePath)) {
|
|
46433
46513
|
try {
|
|
46434
|
-
|
|
46514
|
+
const home = JSON.parse(readFileSync3(homePath, "utf-8"));
|
|
46515
|
+
warnUnknownDgrcKeys(home, homePath);
|
|
46516
|
+
const homeFiltered = {};
|
|
46517
|
+
for (const k of KNOWN_DGRC_KEYS) {
|
|
46518
|
+
if (k in home) homeFiltered[k] = home[k];
|
|
46519
|
+
}
|
|
46520
|
+
config3 = homeFiltered;
|
|
46435
46521
|
} catch {
|
|
46436
46522
|
process.stderr.write(`Warning: Failed to parse ${homePath}, ignoring.
|
|
46437
46523
|
`);
|
|
@@ -46440,8 +46526,11 @@ function loadDgrc() {
|
|
|
46440
46526
|
if (existsSync3(cwdPath) && cwdPath !== homePath) {
|
|
46441
46527
|
try {
|
|
46442
46528
|
const cwd2 = JSON.parse(readFileSync3(cwdPath, "utf-8"));
|
|
46443
|
-
|
|
46444
|
-
|
|
46529
|
+
warnUnknownDgrcKeys(cwd2, cwdPath);
|
|
46530
|
+
for (const k of KNOWN_DGRC_KEYS) {
|
|
46531
|
+
if (k === "apiKey" || k === "apiUrl") continue;
|
|
46532
|
+
if (k in cwd2) config3[k] = cwd2[k];
|
|
46533
|
+
}
|
|
46445
46534
|
} catch {
|
|
46446
46535
|
process.stderr.write(`Warning: Failed to parse ${cwdPath}, ignoring.
|
|
46447
46536
|
`);
|
|
@@ -46454,6 +46543,14 @@ function validateApiUrl(url) {
|
|
|
46454
46543
|
const parsed = new URL(url);
|
|
46455
46544
|
const rawHost = parsed.hostname;
|
|
46456
46545
|
const host = rawHost.startsWith("[") && rawHost.endsWith("]") ? rawHost.slice(1, -1) : rawHost;
|
|
46546
|
+
const isLinkLocal = /^169\.254\./.test(host) || /^fe[89ab][0-9a-f]:/i.test(host);
|
|
46547
|
+
if (isLinkLocal) {
|
|
46548
|
+
process.stderr.write(
|
|
46549
|
+
`Error: API URL host ${host} is link-local / metadata; refusing (SSRF defense). If you genuinely need this, set DG_API_URL to the explicit hostname of your test target.
|
|
46550
|
+
`
|
|
46551
|
+
);
|
|
46552
|
+
process.exit(1);
|
|
46553
|
+
}
|
|
46457
46554
|
const isLocal = host === "localhost" || // IPv4: loopback, RFC 1918, CGNAT. Proper octet regex — not prefix matching,
|
|
46458
46555
|
// which would wrongly accept `192.1680.0.1` or `100.1.2.3` (public).
|
|
46459
46556
|
/^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.)/.test(host) || // IPv6: loopback and unique local (fc00::/7 → fc** or fd**)
|
|
@@ -46492,7 +46589,8 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
46492
46589
|
mode: { type: "string" },
|
|
46493
46590
|
"max-packages": { type: "string" },
|
|
46494
46591
|
json: { type: "boolean", default: false },
|
|
46495
|
-
"scan-all": { type: "boolean", default:
|
|
46592
|
+
"scan-all": { type: "boolean", default: true },
|
|
46593
|
+
"changed-only": { type: "boolean", default: false },
|
|
46496
46594
|
"base-lockfile": { type: "string" },
|
|
46497
46595
|
workspace: { type: "string", short: "w" },
|
|
46498
46596
|
output: { type: "string", short: "o" },
|
|
@@ -46533,8 +46631,7 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
46533
46631
|
}
|
|
46534
46632
|
const command = positionals[0] ?? "scan";
|
|
46535
46633
|
const dgrc = loadDgrc();
|
|
46536
|
-
const apiKey = dgrc.apiKey && typeof dgrc.apiKey === "string" && dgrc.apiKey.startsWith("dg_live_") ? dgrc.apiKey : null;
|
|
46537
|
-
const deviceId = getOrCreateDeviceId();
|
|
46634
|
+
const apiKey = dgrc.apiKey && typeof dgrc.apiKey === "string" && (dgrc.apiKey.startsWith("dg_live_") || dgrc.apiKey.startsWith("dg_test_")) ? dgrc.apiKey : null;
|
|
46538
46635
|
const modeRaw = values.mode ?? process.env.DG_MODE ?? dgrc.mode ?? "warn";
|
|
46539
46636
|
if (!["block", "warn", "off"].includes(modeRaw)) {
|
|
46540
46637
|
process.stderr.write(
|
|
@@ -46549,16 +46646,18 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
46549
46646
|
process.stderr.write("Error: --max-packages must be a number between 1 and 10000\n");
|
|
46550
46647
|
process.exit(1);
|
|
46551
46648
|
}
|
|
46649
|
+
const apiUrl = validateApiUrl(
|
|
46650
|
+
values["api-url"] ?? process.env.DG_API_URL ?? dgrc.apiUrl ?? "https://api.westbayberry.com"
|
|
46651
|
+
);
|
|
46652
|
+
const deviceId = getOrCreateDeviceId();
|
|
46552
46653
|
return {
|
|
46553
46654
|
apiKey,
|
|
46554
46655
|
deviceId,
|
|
46555
|
-
apiUrl
|
|
46556
|
-
values["api-url"] ?? process.env.DG_API_URL ?? dgrc.apiUrl ?? "https://api.westbayberry.com"
|
|
46557
|
-
),
|
|
46656
|
+
apiUrl,
|
|
46558
46657
|
mode: modeRaw,
|
|
46559
46658
|
maxPackages,
|
|
46560
46659
|
json: values.json,
|
|
46561
|
-
scanAll: values["scan-all"],
|
|
46660
|
+
scanAll: values["changed-only"] ? false : values["scan-all"],
|
|
46562
46661
|
baseLockfile: values["base-lockfile"] ?? null,
|
|
46563
46662
|
workspace: values.workspace ?? process.env.DG_WORKSPACE ?? null,
|
|
46564
46663
|
outputFile: values.output ?? null,
|
|
@@ -46566,11 +46665,13 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
46566
46665
|
debug: debug2
|
|
46567
46666
|
};
|
|
46568
46667
|
}
|
|
46569
|
-
var USAGE;
|
|
46668
|
+
var KNOWN_DGRC_KEYS, INTERNAL_DGRC_KEYS, USAGE;
|
|
46570
46669
|
var init_config = __esm({
|
|
46571
46670
|
"src/config.ts"() {
|
|
46572
46671
|
"use strict";
|
|
46573
46672
|
init_auth();
|
|
46673
|
+
KNOWN_DGRC_KEYS = ["apiKey", "apiUrl", "mode", "maxPackages"];
|
|
46674
|
+
INTERNAL_DGRC_KEYS = ["deviceId", "firstRunCompletedAt"];
|
|
46574
46675
|
USAGE = `
|
|
46575
46676
|
Dependency Guardian \u2014 Supply chain security scanner
|
|
46576
46677
|
|
|
@@ -46603,7 +46704,8 @@ var init_config = __esm({
|
|
|
46603
46704
|
--mode <mode> block | warn | off (default: warn)
|
|
46604
46705
|
--max-packages <n> Max packages per scan (default: 10000)
|
|
46605
46706
|
--json Output JSON for CI parsing
|
|
46606
|
-
--scan-all Scan all packages
|
|
46707
|
+
--scan-all Scan all packages (default)
|
|
46708
|
+
--changed-only Only scan packages changed since base lockfile
|
|
46607
46709
|
--base-lockfile <path> Path to base lockfile for explicit diff
|
|
46608
46710
|
--workspace <dir> Scan a specific workspace subdirectory
|
|
46609
46711
|
--output, -o <file> Save JSON results to file (use with --json)
|
|
@@ -46718,7 +46820,13 @@ function parsePackageSpec(spec) {
|
|
|
46718
46820
|
versionSpec: spec.slice(atIdx + 1)
|
|
46719
46821
|
};
|
|
46720
46822
|
}
|
|
46823
|
+
function isFlagLikeSpec(spec) {
|
|
46824
|
+
return spec.startsWith("-");
|
|
46825
|
+
}
|
|
46721
46826
|
async function resolveVersion(spec) {
|
|
46827
|
+
if (isFlagLikeSpec(spec)) {
|
|
46828
|
+
return null;
|
|
46829
|
+
}
|
|
46722
46830
|
return new Promise((resolve2) => {
|
|
46723
46831
|
const child = spawn2("npm", ["view", spec, "version"], {
|
|
46724
46832
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -82402,18 +82510,26 @@ var discover_exports = {};
|
|
|
82402
82510
|
__export(discover_exports, {
|
|
82403
82511
|
discoverProjects: () => discoverProjects
|
|
82404
82512
|
});
|
|
82405
|
-
import {
|
|
82513
|
+
import { readFileSync as readFileSync7, readdirSync, lstatSync as lstatSync2 } from "node:fs";
|
|
82406
82514
|
import { join as join8, relative as relative2, basename as basename2 } from "node:path";
|
|
82407
82515
|
function discoverProjects(root) {
|
|
82408
82516
|
const projects = [];
|
|
82409
82517
|
walk(root, root, 0, projects);
|
|
82410
82518
|
return projects.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
82411
82519
|
}
|
|
82520
|
+
function isSafeRegularFile(path2) {
|
|
82521
|
+
try {
|
|
82522
|
+
const st = lstatSync2(path2);
|
|
82523
|
+
return st.isFile() && !st.isSymbolicLink();
|
|
82524
|
+
} catch {
|
|
82525
|
+
return false;
|
|
82526
|
+
}
|
|
82527
|
+
}
|
|
82412
82528
|
function walk(dir, root, depth, out) {
|
|
82413
82529
|
if (depth > MAX_DEPTH) return;
|
|
82414
82530
|
for (const lockfile of NPM_LOCKFILES) {
|
|
82415
82531
|
const lockPath = join8(dir, lockfile);
|
|
82416
|
-
if (
|
|
82532
|
+
if (isSafeRegularFile(lockPath)) {
|
|
82417
82533
|
const count = countNpmPackages(lockPath);
|
|
82418
82534
|
if (count > 0) {
|
|
82419
82535
|
out.push({
|
|
@@ -82429,7 +82545,7 @@ function walk(dir, root, depth, out) {
|
|
|
82429
82545
|
}
|
|
82430
82546
|
for (const depFile of PYTHON_DEPFILES) {
|
|
82431
82547
|
const depPath = join8(dir, depFile);
|
|
82432
|
-
if (
|
|
82548
|
+
if (isSafeRegularFile(depPath)) {
|
|
82433
82549
|
const count = countPythonPackages(depPath, depFile);
|
|
82434
82550
|
if (count > 0) {
|
|
82435
82551
|
out.push({
|
|
@@ -82453,7 +82569,7 @@ function walk(dir, root, depth, out) {
|
|
|
82453
82569
|
if (SKIP_DIRS.has(entry) || entry.startsWith(".")) continue;
|
|
82454
82570
|
const full = join8(dir, entry);
|
|
82455
82571
|
try {
|
|
82456
|
-
const st =
|
|
82572
|
+
const st = lstatSync2(full);
|
|
82457
82573
|
if (st.isDirectory() && !st.isSymbolicLink()) {
|
|
82458
82574
|
walk(full, root, depth + 1, out);
|
|
82459
82575
|
}
|
|
@@ -82546,7 +82662,8 @@ __export(hook_exports, {
|
|
|
82546
82662
|
});
|
|
82547
82663
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
82548
82664
|
import {
|
|
82549
|
-
existsSync as
|
|
82665
|
+
existsSync as existsSync6,
|
|
82666
|
+
lstatSync as lstatSync3,
|
|
82550
82667
|
readFileSync as readFileSync8,
|
|
82551
82668
|
writeFileSync as writeFileSync3,
|
|
82552
82669
|
mkdirSync,
|
|
@@ -82554,9 +82671,40 @@ import {
|
|
|
82554
82671
|
unlinkSync as unlinkSync2
|
|
82555
82672
|
} from "node:fs";
|
|
82556
82673
|
import { join as join9, dirname as dirname4 } from "node:path";
|
|
82557
|
-
function
|
|
82674
|
+
function assertSafeWriteTarget(target) {
|
|
82675
|
+
const parent = dirname4(target);
|
|
82676
|
+
try {
|
|
82677
|
+
const parentStat = lstatSync3(parent);
|
|
82678
|
+
if (parentStat.isSymbolicLink()) {
|
|
82679
|
+
throw new Error(
|
|
82680
|
+
`refusing to write to ${target}: parent dir ${parent} is a symlink (possible path-traversal attack)`
|
|
82681
|
+
);
|
|
82682
|
+
}
|
|
82683
|
+
} catch (e) {
|
|
82684
|
+
if (e instanceof Error && e.message.startsWith("refusing")) {
|
|
82685
|
+
throw e;
|
|
82686
|
+
}
|
|
82687
|
+
}
|
|
82688
|
+
try {
|
|
82689
|
+
const targetStat = lstatSync3(target);
|
|
82690
|
+
if (targetStat.isSymbolicLink()) {
|
|
82691
|
+
throw new Error(
|
|
82692
|
+
`refusing to write to ${target}: target is a symlink (possible path-traversal attack)`
|
|
82693
|
+
);
|
|
82694
|
+
}
|
|
82695
|
+
} catch (e) {
|
|
82696
|
+
if (e instanceof Error && e.message.startsWith("refusing")) {
|
|
82697
|
+
throw e;
|
|
82698
|
+
}
|
|
82699
|
+
}
|
|
82700
|
+
}
|
|
82701
|
+
function safeWriteFileSync(target, content) {
|
|
82702
|
+
assertSafeWriteTarget(target);
|
|
82703
|
+
writeFileSync3(target, content);
|
|
82704
|
+
}
|
|
82705
|
+
function findHooksDir() {
|
|
82558
82706
|
try {
|
|
82559
|
-
return execFileSync2("git", ["rev-parse", "--git-
|
|
82707
|
+
return execFileSync2("git", ["rev-parse", "--git-path", "hooks"], {
|
|
82560
82708
|
encoding: "utf-8",
|
|
82561
82709
|
stdio: ["pipe", "pipe", "pipe"]
|
|
82562
82710
|
}).trim();
|
|
@@ -82579,9 +82727,9 @@ function detectHookFramework(repoRoot) {
|
|
|
82579
82727
|
const huskyHook = join9(root, ".husky", "pre-commit");
|
|
82580
82728
|
const lefthookConfig = join9(root, "lefthook.yml");
|
|
82581
82729
|
const lefthookConfigYaml = join9(root, "lefthook.yaml");
|
|
82582
|
-
const
|
|
82583
|
-
const bareHook = join9(
|
|
82584
|
-
if (
|
|
82730
|
+
const hooksDir = findHooksDir();
|
|
82731
|
+
const bareHook = join9(hooksDir, "pre-commit");
|
|
82732
|
+
if (existsSync6(huskyHook)) {
|
|
82585
82733
|
const content = readFileSync8(huskyHook, "utf-8");
|
|
82586
82734
|
return {
|
|
82587
82735
|
framework: "husky",
|
|
@@ -82590,7 +82738,7 @@ function detectHookFramework(repoRoot) {
|
|
|
82590
82738
|
};
|
|
82591
82739
|
}
|
|
82592
82740
|
for (const cfg of [lefthookConfig, lefthookConfigYaml]) {
|
|
82593
|
-
if (
|
|
82741
|
+
if (existsSync6(cfg)) {
|
|
82594
82742
|
const content = readFileSync8(cfg, "utf-8");
|
|
82595
82743
|
const installed2 = /^\s+dependency-guardian\s*:/m.test(content);
|
|
82596
82744
|
return {
|
|
@@ -82601,7 +82749,7 @@ function detectHookFramework(repoRoot) {
|
|
|
82601
82749
|
}
|
|
82602
82750
|
}
|
|
82603
82751
|
let installed = false;
|
|
82604
|
-
if (
|
|
82752
|
+
if (existsSync6(bareHook)) {
|
|
82605
82753
|
installed = readFileSync8(bareHook, "utf-8").includes(HOOK_MARKER);
|
|
82606
82754
|
}
|
|
82607
82755
|
return {
|
|
@@ -82623,7 +82771,7 @@ ${HUSKY_SNIPPET}`;
|
|
|
82623
82771
|
|
|
82624
82772
|
${LEFTHOOK_ENTRY}`;
|
|
82625
82773
|
case "bare":
|
|
82626
|
-
if (
|
|
82774
|
+
if (existsSync6(info.targetFile)) {
|
|
82627
82775
|
return `Will append to existing hook at ${info.targetFile}:
|
|
82628
82776
|
${HOOK_SECTION}`;
|
|
82629
82777
|
}
|
|
@@ -82637,7 +82785,7 @@ function installHuskyHook(targetFile) {
|
|
|
82637
82785
|
process.stderr.write(" Hook already installed in Husky.\n");
|
|
82638
82786
|
return;
|
|
82639
82787
|
}
|
|
82640
|
-
|
|
82788
|
+
safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HUSKY_SNIPPET);
|
|
82641
82789
|
try {
|
|
82642
82790
|
chmodSync2(targetFile, 493);
|
|
82643
82791
|
} catch {
|
|
@@ -82659,7 +82807,7 @@ function installLefthookHook(targetFile) {
|
|
|
82659
82807
|
/^(\s{2}commands\s*:\s*)$/m,
|
|
82660
82808
|
`$1
|
|
82661
82809
|
${LEFTHOOK_MARKER}:
|
|
82662
|
-
glob: "{package-lock.json,yarn.lock,pnpm-lock.yaml,npm-shrinkwrap.json}"
|
|
82810
|
+
glob: "**/{package-lock.json,yarn.lock,pnpm-lock.yaml,npm-shrinkwrap.json,requirements.txt,requirements-*.txt,Pipfile.lock,poetry.lock}"
|
|
82663
82811
|
run: dg scan --mode block`
|
|
82664
82812
|
);
|
|
82665
82813
|
} else {
|
|
@@ -82673,20 +82821,20 @@ function installLefthookHook(targetFile) {
|
|
|
82673
82821
|
} else {
|
|
82674
82822
|
updated = existing.trimEnd() + "\n\n" + LEFTHOOK_ENTRY;
|
|
82675
82823
|
}
|
|
82676
|
-
|
|
82824
|
+
safeWriteFileSync(targetFile, updated);
|
|
82677
82825
|
process.stderr.write(` Added Dependency Guardian to ${targetFile}
|
|
82678
82826
|
`);
|
|
82679
82827
|
}
|
|
82680
82828
|
function installBareHook(targetFile) {
|
|
82681
82829
|
const hooksDir = dirname4(targetFile);
|
|
82682
82830
|
mkdirSync(hooksDir, { recursive: true });
|
|
82683
|
-
if (
|
|
82831
|
+
if (existsSync6(targetFile)) {
|
|
82684
82832
|
const existing = readFileSync8(targetFile, "utf-8");
|
|
82685
82833
|
if (existing.includes(HOOK_MARKER)) {
|
|
82686
82834
|
process.stderr.write(" Hook already installed.\n");
|
|
82687
82835
|
return;
|
|
82688
82836
|
}
|
|
82689
|
-
|
|
82837
|
+
safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HOOK_SECTION);
|
|
82690
82838
|
chmodSync2(targetFile, 493);
|
|
82691
82839
|
process.stderr.write(
|
|
82692
82840
|
` Appended Dependency Guardian hook to existing ${targetFile}
|
|
@@ -82694,7 +82842,7 @@ function installBareHook(targetFile) {
|
|
|
82694
82842
|
);
|
|
82695
82843
|
return;
|
|
82696
82844
|
}
|
|
82697
|
-
|
|
82845
|
+
safeWriteFileSync(targetFile, HOOK_SCRIPT);
|
|
82698
82846
|
chmodSync2(targetFile, 493);
|
|
82699
82847
|
process.stderr.write(` Installed git pre-commit hook at ${targetFile}
|
|
82700
82848
|
`);
|
|
@@ -82717,12 +82865,12 @@ function installHook() {
|
|
|
82717
82865
|
installHookForFramework(info);
|
|
82718
82866
|
}
|
|
82719
82867
|
function uninstallHook() {
|
|
82720
|
-
const
|
|
82721
|
-
const hookPath = join9(
|
|
82868
|
+
const hooksDir = findHooksDir();
|
|
82869
|
+
const hookPath = join9(hooksDir, "pre-commit");
|
|
82722
82870
|
try {
|
|
82723
82871
|
const root = findRepoRoot();
|
|
82724
82872
|
const huskyPath = join9(root, ".husky", "pre-commit");
|
|
82725
|
-
if (
|
|
82873
|
+
if (existsSync6(huskyPath)) {
|
|
82726
82874
|
const content2 = readFileSync8(huskyPath, "utf-8");
|
|
82727
82875
|
if (content2.includes(HOOK_MARKER)) {
|
|
82728
82876
|
const startIdx2 = content2.indexOf(MARKER_START);
|
|
@@ -82731,7 +82879,7 @@ function uninstallHook() {
|
|
|
82731
82879
|
const before = content2.slice(0, startIdx2).trimEnd();
|
|
82732
82880
|
const after = content2.slice(endIdx2 + MARKER_END.length).trimStart();
|
|
82733
82881
|
const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
|
|
82734
|
-
|
|
82882
|
+
safeWriteFileSync(huskyPath, remaining);
|
|
82735
82883
|
process.stderr.write(
|
|
82736
82884
|
` Removed Dependency Guardian section from ${huskyPath}
|
|
82737
82885
|
`
|
|
@@ -82741,14 +82889,14 @@ function uninstallHook() {
|
|
|
82741
82889
|
}
|
|
82742
82890
|
}
|
|
82743
82891
|
for (const cfg of [join9(root, "lefthook.yml"), join9(root, "lefthook.yaml")]) {
|
|
82744
|
-
if (
|
|
82892
|
+
if (existsSync6(cfg)) {
|
|
82745
82893
|
const content2 = readFileSync8(cfg, "utf-8");
|
|
82746
82894
|
if (/^\s+dependency-guardian\s*:/m.test(content2)) {
|
|
82747
82895
|
const stripped = content2.replace(
|
|
82748
82896
|
/^\s+dependency-guardian\s*:\s*\n(?:\s{6,}.*\n)+/gm,
|
|
82749
82897
|
""
|
|
82750
82898
|
);
|
|
82751
|
-
|
|
82899
|
+
safeWriteFileSync(cfg, stripped);
|
|
82752
82900
|
process.stderr.write(
|
|
82753
82901
|
` Removed Dependency Guardian section from ${cfg}
|
|
82754
82902
|
`
|
|
@@ -82759,7 +82907,7 @@ function uninstallHook() {
|
|
|
82759
82907
|
}
|
|
82760
82908
|
} catch {
|
|
82761
82909
|
}
|
|
82762
|
-
if (!
|
|
82910
|
+
if (!existsSync6(hookPath)) {
|
|
82763
82911
|
process.stderr.write(" No hook to remove.\n");
|
|
82764
82912
|
return;
|
|
82765
82913
|
}
|
|
@@ -82782,7 +82930,7 @@ function uninstallHook() {
|
|
|
82782
82930
|
const before = content.slice(0, startIdx).trimEnd();
|
|
82783
82931
|
const after = content.slice(endIdx + MARKER_END.length).trimStart();
|
|
82784
82932
|
const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
|
|
82785
|
-
|
|
82933
|
+
safeWriteFileSync(hookPath, remaining);
|
|
82786
82934
|
process.stderr.write(
|
|
82787
82935
|
` Removed Dependency Guardian section from ${hookPath}
|
|
82788
82936
|
`
|
|
@@ -82828,16 +82976,12 @@ var init_hook = __esm({
|
|
|
82828
82976
|
HOOK_SCRIPT = `#!/bin/sh
|
|
82829
82977
|
${HOOK_MARKER} \u2014 installed by \`dg hook install\`
|
|
82830
82978
|
|
|
82831
|
-
#
|
|
82832
|
-
|
|
82833
|
-
|
|
82834
|
-
|
|
82835
|
-
|
|
82836
|
-
|
|
82837
|
-
fi
|
|
82838
|
-
done
|
|
82839
|
-
|
|
82840
|
-
if [ -z "$STAGED" ]; then
|
|
82979
|
+
# Match any of the watched lockfiles, including in subdirectories
|
|
82980
|
+
# (monorepos) \u2014 the regex anchors at start-of-path OR after a slash.
|
|
82981
|
+
# Mirrors the GitHub-App side which is monorepo-aware via basename
|
|
82982
|
+
# matching against NPM_DEPENDENCY_FILES + isPythonDepFile.
|
|
82983
|
+
if ! git diff --cached --name-only | grep -qE \\
|
|
82984
|
+
'(^|/)(package-lock\\.json|npm-shrinkwrap\\.json|yarn\\.lock|pnpm-lock\\.yaml|requirements(-[^/]+)?\\.txt|Pipfile\\.lock|poetry\\.lock)$'; then
|
|
82841
82985
|
exit 0
|
|
82842
82986
|
fi
|
|
82843
82987
|
|
|
@@ -82874,7 +83018,7 @@ ${MARKER_START}
|
|
|
82874
83018
|
${HOOK_MARKER} \u2014 installed by \`dg hook install\`
|
|
82875
83019
|
DG_BIN=$(command -v dg 2>/dev/null || command -v dependency-guardian 2>/dev/null)
|
|
82876
83020
|
if [ -n "$DG_BIN" ]; then
|
|
82877
|
-
if git diff --cached --name-only | grep -qE '
|
|
83021
|
+
if git diff --cached --name-only | grep -qE '(^|/)(package-lock\\.json|npm-shrinkwrap\\.json|yarn\\.lock|pnpm-lock\\.yaml|requirements(-[^/]+)?\\.txt|Pipfile\\.lock|poetry\\.lock)$'; then
|
|
82878
83022
|
echo "Dependency Guardian: lockfile change detected, scanning..." >&2
|
|
82879
83023
|
NO_COLOR=1 "$DG_BIN" scan --mode block
|
|
82880
83024
|
DG_EXIT=$?
|
|
@@ -82889,7 +83033,7 @@ ${MARKER_END}
|
|
|
82889
83033
|
LEFTHOOK_ENTRY = ` pre-commit:
|
|
82890
83034
|
commands:
|
|
82891
83035
|
${LEFTHOOK_MARKER}:
|
|
82892
|
-
glob: "{package-lock.json,yarn.lock,pnpm-lock.yaml,npm-shrinkwrap.json}"
|
|
83036
|
+
glob: "**/{package-lock.json,yarn.lock,pnpm-lock.yaml,npm-shrinkwrap.json,requirements.txt,requirements-*.txt,Pipfile.lock,poetry.lock}"
|
|
82893
83037
|
run: dg scan --mode block
|
|
82894
83038
|
`;
|
|
82895
83039
|
USAGE2 = `
|
|
@@ -83154,7 +83298,7 @@ var init_parse_package_json = __esm({
|
|
|
83154
83298
|
|
|
83155
83299
|
// src/lockfile.ts
|
|
83156
83300
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
83157
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
83301
|
+
import { readFileSync as readFileSync9, existsSync as existsSync7, statSync } from "node:fs";
|
|
83158
83302
|
import { join as join10 } from "node:path";
|
|
83159
83303
|
function readFileSafe(path2) {
|
|
83160
83304
|
const size = statSync(path2).size;
|
|
@@ -83171,7 +83315,7 @@ function discoverChanges(cwd2, config3) {
|
|
|
83171
83315
|
const pythonDepFiles = ["requirements.txt", "Pipfile.lock", "poetry.lock"];
|
|
83172
83316
|
let pythonPackages = [];
|
|
83173
83317
|
for (const pyFile of pythonDepFiles) {
|
|
83174
|
-
if (
|
|
83318
|
+
if (existsSync7(join10(cwd2, pyFile))) {
|
|
83175
83319
|
const pyPkgs = parsePythonDepFile(cwd2, pyFile);
|
|
83176
83320
|
for (const p of pyPkgs) {
|
|
83177
83321
|
if (p.version === "latest") continue;
|
|
@@ -83196,66 +83340,53 @@ function discoverChanges(cwd2, config3) {
|
|
|
83196
83340
|
const headContent = readFileSafe(lockfileInfo.path);
|
|
83197
83341
|
const headParsed = parseLockfileByType(headContent, lockfileInfo.type);
|
|
83198
83342
|
const directDeps = getDirectDeps(cwd2);
|
|
83199
|
-
if (config3.scanAll) {
|
|
83200
|
-
const packages2 = [];
|
|
83201
|
-
for (const [name, entry] of headParsed.packages) {
|
|
83202
|
-
if (packages2.length >= config3.maxPackages) break;
|
|
83203
|
-
if (entry.optional && entry.hasPlatformRestriction) continue;
|
|
83204
|
-
if (name === SELF_PACKAGE) continue;
|
|
83205
|
-
packages2.push({
|
|
83206
|
-
name,
|
|
83207
|
-
version: entry.version,
|
|
83208
|
-
previousVersion: null,
|
|
83209
|
-
isNew: true
|
|
83210
|
-
});
|
|
83211
|
-
}
|
|
83212
|
-
return { packages: packages2, pythonPackages, method: "scan-all", skipped: [] };
|
|
83213
|
-
}
|
|
83214
83343
|
if (config3.baseLockfile) {
|
|
83215
|
-
if (!
|
|
83344
|
+
if (!existsSync7(config3.baseLockfile)) {
|
|
83216
83345
|
throw new Error(`Base lockfile not found: ${config3.baseLockfile}`);
|
|
83217
83346
|
}
|
|
83218
|
-
const
|
|
83219
|
-
const baseParsed = parseLockfile(baseContent2);
|
|
83220
|
-
const diff2 = diffLockfiles(baseParsed, headParsed, config3.maxPackages, directDeps);
|
|
83221
|
-
return {
|
|
83222
|
-
packages: diff2.changes.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
83223
|
-
pythonPackages,
|
|
83224
|
-
method: "base-lockfile",
|
|
83225
|
-
skipped: diff2.skipped
|
|
83226
|
-
};
|
|
83227
|
-
}
|
|
83228
|
-
const baseContent = getGitBaseLockfile(cwd2);
|
|
83229
|
-
if (baseContent !== null) {
|
|
83347
|
+
const baseContent = readFileSafe(config3.baseLockfile);
|
|
83230
83348
|
const baseParsed = parseLockfile(baseContent);
|
|
83231
83349
|
const diff2 = diffLockfiles(baseParsed, headParsed, config3.maxPackages, directDeps);
|
|
83232
83350
|
return {
|
|
83233
83351
|
packages: diff2.changes.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
83234
83352
|
pythonPackages,
|
|
83235
|
-
method: "
|
|
83353
|
+
method: "base-lockfile",
|
|
83236
83354
|
skipped: diff2.skipped
|
|
83237
83355
|
};
|
|
83238
83356
|
}
|
|
83239
|
-
|
|
83240
|
-
|
|
83241
|
-
|
|
83242
|
-
|
|
83243
|
-
|
|
83244
|
-
const diff2 = diffPackageJsons(basePkgJson, headPkgJson, config3.maxPackages);
|
|
83245
|
-
const resolved = diff2.changes.map((change) => {
|
|
83246
|
-
const lockEntry = headParsed.packages.get(change.name);
|
|
83247
|
-
return {
|
|
83248
|
-
...change,
|
|
83249
|
-
newVersion: lockEntry?.version ?? change.newVersion
|
|
83250
|
-
};
|
|
83251
|
-
});
|
|
83357
|
+
if (!config3.scanAll) {
|
|
83358
|
+
const baseContent = getGitBaseLockfile(cwd2);
|
|
83359
|
+
if (baseContent !== null) {
|
|
83360
|
+
const baseParsed = parseLockfile(baseContent);
|
|
83361
|
+
const diff2 = diffLockfiles(baseParsed, headParsed, config3.maxPackages, directDeps);
|
|
83252
83362
|
return {
|
|
83253
|
-
packages:
|
|
83363
|
+
packages: diff2.changes.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
83254
83364
|
pythonPackages,
|
|
83255
|
-
method: "
|
|
83256
|
-
skipped:
|
|
83365
|
+
method: "git-diff",
|
|
83366
|
+
skipped: diff2.skipped
|
|
83257
83367
|
};
|
|
83258
83368
|
}
|
|
83369
|
+
const pkgJsonPath = join10(cwd2, "package.json");
|
|
83370
|
+
if (existsSync7(pkgJsonPath)) {
|
|
83371
|
+
const headPkgJson = readFileSafe(pkgJsonPath);
|
|
83372
|
+
const basePkgJson = getGitBaseFile(cwd2, "package.json");
|
|
83373
|
+
if (basePkgJson !== null) {
|
|
83374
|
+
const diff2 = diffPackageJsons(basePkgJson, headPkgJson, config3.maxPackages);
|
|
83375
|
+
const resolved = diff2.changes.map((change) => {
|
|
83376
|
+
const lockEntry = headParsed.packages.get(change.name);
|
|
83377
|
+
return {
|
|
83378
|
+
...change,
|
|
83379
|
+
newVersion: lockEntry?.version ?? change.newVersion
|
|
83380
|
+
};
|
|
83381
|
+
});
|
|
83382
|
+
return {
|
|
83383
|
+
packages: resolved.map(toPackageInput).filter((p) => p.name !== SELF_PACKAGE),
|
|
83384
|
+
pythonPackages,
|
|
83385
|
+
method: "fallback",
|
|
83386
|
+
skipped: []
|
|
83387
|
+
};
|
|
83388
|
+
}
|
|
83389
|
+
}
|
|
83259
83390
|
}
|
|
83260
83391
|
const packages = [];
|
|
83261
83392
|
for (const [name, entry] of headParsed.packages) {
|
|
@@ -83269,7 +83400,7 @@ function discoverChanges(cwd2, config3) {
|
|
|
83269
83400
|
isNew: true
|
|
83270
83401
|
});
|
|
83271
83402
|
}
|
|
83272
|
-
return { packages, pythonPackages, method: "
|
|
83403
|
+
return { packages, pythonPackages, method: "scan-all", skipped: [] };
|
|
83273
83404
|
}
|
|
83274
83405
|
function findLockfile(cwd2) {
|
|
83275
83406
|
const candidates = [
|
|
@@ -83280,7 +83411,7 @@ function findLockfile(cwd2) {
|
|
|
83280
83411
|
];
|
|
83281
83412
|
for (const [name, type] of candidates) {
|
|
83282
83413
|
const p = join10(cwd2, name);
|
|
83283
|
-
if (
|
|
83414
|
+
if (existsSync7(p)) return { path: p, type };
|
|
83284
83415
|
}
|
|
83285
83416
|
return null;
|
|
83286
83417
|
}
|
|
@@ -84160,13 +84291,17 @@ function useInit(opts = {}) {
|
|
|
84160
84291
|
`);
|
|
84161
84292
|
allOutcomes.push(outcome);
|
|
84162
84293
|
}
|
|
84163
|
-
const allPackages =
|
|
84164
|
-
|
|
84165
|
-
)
|
|
84166
|
-
|
|
84167
|
-
|
|
84168
|
-
|
|
84169
|
-
|
|
84294
|
+
const allPackages = [];
|
|
84295
|
+
const seen = /* @__PURE__ */ new Set();
|
|
84296
|
+
for (const outcome of allOutcomes) {
|
|
84297
|
+
for (const pkg of outcome.result?.result.packages ?? []) {
|
|
84298
|
+
const key = `${pkg.name}@${pkg.version}`;
|
|
84299
|
+
if (seen.has(key)) continue;
|
|
84300
|
+
seen.add(key);
|
|
84301
|
+
allPackages.push(pkg);
|
|
84302
|
+
}
|
|
84303
|
+
}
|
|
84304
|
+
const totalScanned = seen.size;
|
|
84170
84305
|
const totalDuration = allOutcomes.reduce(
|
|
84171
84306
|
(sum, o) => sum + (o.result?.durationMs ?? 0),
|
|
84172
84307
|
0
|
|
@@ -88204,7 +88339,7 @@ var init_LoginApp = __esm({
|
|
|
88204
88339
|
|
|
88205
88340
|
// src/pip-wrapper.ts
|
|
88206
88341
|
import { spawn as spawn3 } from "node:child_process";
|
|
88207
|
-
import { readFileSync as readFileSync10, existsSync as
|
|
88342
|
+
import { readFileSync as readFileSync10, existsSync as existsSync8 } from "node:fs";
|
|
88208
88343
|
function parsePipArgs(args) {
|
|
88209
88344
|
let dgForce = false;
|
|
88210
88345
|
const filtered = [];
|
|
@@ -88267,7 +88402,7 @@ function pipFlagTakesValue(flag) {
|
|
|
88267
88402
|
return false;
|
|
88268
88403
|
}
|
|
88269
88404
|
function parseRequirementsFile(filePath) {
|
|
88270
|
-
if (!
|
|
88405
|
+
if (!existsSync8(filePath)) return [];
|
|
88271
88406
|
try {
|
|
88272
88407
|
const content = readFileSync10(filePath, "utf-8");
|
|
88273
88408
|
const specs = [];
|
|
@@ -88407,7 +88542,7 @@ var FileSavePrompt_exports = {};
|
|
|
88407
88542
|
__export(FileSavePrompt_exports, {
|
|
88408
88543
|
FileSavePrompt: () => FileSavePrompt
|
|
88409
88544
|
});
|
|
88410
|
-
import { existsSync as
|
|
88545
|
+
import { existsSync as existsSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
88411
88546
|
import { dirname as dirname5, join as join11 } from "node:path";
|
|
88412
88547
|
function listDirectory(dir) {
|
|
88413
88548
|
try {
|
|
@@ -88509,7 +88644,7 @@ var init_FileSavePrompt = __esm({
|
|
|
88509
88644
|
if (key.return) {
|
|
88510
88645
|
const fullName = ensureJsonExtension(state.filename);
|
|
88511
88646
|
const fullPath = join11(state.directory, fullName);
|
|
88512
|
-
if (!state.confirmOverwrite &&
|
|
88647
|
+
if (!state.confirmOverwrite && existsSync9(fullPath)) {
|
|
88513
88648
|
dispatch({ type: "CONFIRM_OVERWRITE" });
|
|
88514
88649
|
return;
|
|
88515
88650
|
}
|