@patchstack/connect 0.3.33 → 0.4.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/cli.js +164 -32
- package/dist/cli.js.map +1 -1
- package/dist/protect.cjs +260 -65
- package/dist/protect.cjs.map +1 -1
- package/dist/protect.edge.js +260 -65
- package/dist/protect.edge.js.map +3 -3
- package/dist/protect.js +260 -65
- package/dist/protect.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2176,7 +2176,7 @@ function ensureSourceMarker(cwd, shell, framework) {
|
|
|
2176
2176
|
}
|
|
2177
2177
|
|
|
2178
2178
|
// src/guide.ts
|
|
2179
|
-
import { existsSync as
|
|
2179
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
|
|
2180
2180
|
import path9 from "path";
|
|
2181
2181
|
|
|
2182
2182
|
// src/protect/install/util.ts
|
|
@@ -2193,8 +2193,8 @@ function hasDependency(cwd, name) {
|
|
|
2193
2193
|
return false;
|
|
2194
2194
|
}
|
|
2195
2195
|
}
|
|
2196
|
-
function hasResolvableCredential(cwd) {
|
|
2197
|
-
if ((
|
|
2196
|
+
function hasResolvableCredential(cwd, env = process.env) {
|
|
2197
|
+
if ((env.PATCHSTACK_API_KEY ?? "") !== "" || (env.PATCHSTACK_PULSE_AUTH ?? "") !== "") {
|
|
2198
2198
|
return true;
|
|
2199
2199
|
}
|
|
2200
2200
|
for (const file of [".patchstackrc.local.json", ".patchstackrc.json"]) {
|
|
@@ -2209,6 +2209,9 @@ function hasResolvableCredential(cwd) {
|
|
|
2209
2209
|
}
|
|
2210
2210
|
var SITE_UUID_PLACEHOLDER = "__PATCHSTACK_SITE_UUID__";
|
|
2211
2211
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2212
|
+
function isSiteUuid(value) {
|
|
2213
|
+
return typeof value === "string" && UUID_RE.test(value);
|
|
2214
|
+
}
|
|
2212
2215
|
function bakeSiteUuid(cwd, guardRelPath) {
|
|
2213
2216
|
const rc = join2(cwd, ".patchstackrc.json");
|
|
2214
2217
|
if (!existsSync2(rc)) {
|
|
@@ -3487,6 +3490,121 @@ var expressAdapter = {
|
|
|
3487
3490
|
verify: (cwd) => verifyRegister(cwd, SPEC6)
|
|
3488
3491
|
};
|
|
3489
3492
|
|
|
3493
|
+
// src/protect/install/reporting.ts
|
|
3494
|
+
import { existsSync as existsSync10 } from "fs";
|
|
3495
|
+
import { join as join12 } from "path";
|
|
3496
|
+
|
|
3497
|
+
// src/protect/reporting-state.js
|
|
3498
|
+
var REPORTING_STATES = Object.freeze([
|
|
3499
|
+
/** Enrolled, managed rules, credential present, not opted out. Events are sent. */
|
|
3500
|
+
"on",
|
|
3501
|
+
/** `PATCHSTACK_REPORT_DETECTIONS=0`. An explicit, per-deployment opt-out. */
|
|
3502
|
+
"disabled-by-config",
|
|
3503
|
+
/** `PATCHSTACK_TELEMETRY=0`. The broader switch, which covers this along with everything else. */
|
|
3504
|
+
"disabled-by-telemetry-opt-out",
|
|
3505
|
+
/** No site identity: a local or unenrolled install. Nothing to report against. */
|
|
3506
|
+
"not-enrolled",
|
|
3507
|
+
/**
|
|
3508
|
+
* A site identity, but the rules running are not the platform's — the caller's own bundle, or none.
|
|
3509
|
+
* There is no managed rule document to attribute a detection to, so a report would name a rule id the
|
|
3510
|
+
* platform never issued.
|
|
3511
|
+
*/
|
|
3512
|
+
"no-managed-rules",
|
|
3513
|
+
/** Enrolled with managed rules, but no credential resolved, so a report would be refused. */
|
|
3514
|
+
"unavailable-no-credential"
|
|
3515
|
+
]);
|
|
3516
|
+
function optedOut(value) {
|
|
3517
|
+
if (value === void 0 || value === null || value === "") return false;
|
|
3518
|
+
return /^(0|false|off|no)$/i.test(String(value));
|
|
3519
|
+
}
|
|
3520
|
+
function reportingState(input) {
|
|
3521
|
+
const env = input.env ?? (typeof process !== "undefined" ? process.env : void 0) ?? {};
|
|
3522
|
+
if (input.configOptOut === true) return { state: "disabled-by-config", reports: false };
|
|
3523
|
+
if (optedOut(env.PATCHSTACK_REPORT_DETECTIONS)) return { state: "disabled-by-config", reports: false };
|
|
3524
|
+
if (optedOut(env.PATCHSTACK_TELEMETRY)) return { state: "disabled-by-telemetry-opt-out", reports: false };
|
|
3525
|
+
const siteUuid = input.siteUuid;
|
|
3526
|
+
if (typeof siteUuid !== "string" || siteUuid === "") return { state: "not-enrolled", reports: false };
|
|
3527
|
+
if (input.hasCredential !== true) return { state: "unavailable-no-credential", reports: false };
|
|
3528
|
+
const managed = input.ruleOrigin === "api" || input.ruleOrigin === "cache";
|
|
3529
|
+
if (!managed) return { state: "no-managed-rules", reports: false };
|
|
3530
|
+
return { state: "on", reports: true };
|
|
3531
|
+
}
|
|
3532
|
+
function explainReportingState(state) {
|
|
3533
|
+
switch (state) {
|
|
3534
|
+
case "on":
|
|
3535
|
+
return "Security events are reported to Patchstack for this site.";
|
|
3536
|
+
case "disabled-by-config":
|
|
3537
|
+
return "Reporting is off because PATCHSTACK_REPORT_DETECTIONS is set to a false value.";
|
|
3538
|
+
case "disabled-by-telemetry-opt-out":
|
|
3539
|
+
return "Reporting is off because PATCHSTACK_TELEMETRY is set to a false value, which covers all telemetry.";
|
|
3540
|
+
case "not-enrolled":
|
|
3541
|
+
return "Reporting is off because this install has no site identity \u2014 it is not enrolled in Patchstack-managed mitigation.";
|
|
3542
|
+
case "no-managed-rules":
|
|
3543
|
+
return "Reporting is off because the rules in force did not come from Patchstack, so a detection could not be attributed to a managed rule.";
|
|
3544
|
+
case "unavailable-no-credential":
|
|
3545
|
+
return "Reporting is unavailable because no API credential resolved, so a report would be refused.";
|
|
3546
|
+
default:
|
|
3547
|
+
return `Unrecognised reporting state: ${String(state)}.`;
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
|
|
3551
|
+
// src/protect/install/reporting.ts
|
|
3552
|
+
function siteIdentity(cwd, env) {
|
|
3553
|
+
const rc = join12(cwd, ".patchstackrc.json");
|
|
3554
|
+
let recorded;
|
|
3555
|
+
if (existsSync10(rc)) {
|
|
3556
|
+
try {
|
|
3557
|
+
recorded = JSON.parse(read(rc)).siteUuid;
|
|
3558
|
+
} catch {
|
|
3559
|
+
recorded = void 0;
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
if (isSiteUuid(recorded)) return { uuid: recorded, found: true };
|
|
3563
|
+
const fromEnv = env.PATCHSTACK_SITE_UUID;
|
|
3564
|
+
if (isSiteUuid(fromEnv)) return { uuid: fromEnv, found: true };
|
|
3565
|
+
const anything = typeof recorded === "string" && recorded !== "" || (fromEnv ?? "") !== "";
|
|
3566
|
+
return { uuid: null, found: anything };
|
|
3567
|
+
}
|
|
3568
|
+
function reportingChecks(cwd, env = process.env) {
|
|
3569
|
+
const { uuid: siteUuid, found: identityFound } = siteIdentity(cwd, env);
|
|
3570
|
+
const hasCredential = hasResolvableCredential(cwd, env);
|
|
3571
|
+
const { state } = reportingState({ siteUuid, hasCredential, ruleOrigin: "api", env });
|
|
3572
|
+
const checks = [
|
|
3573
|
+
{
|
|
3574
|
+
group: "reporting",
|
|
3575
|
+
label: "this app is enrolled (a site identity is recorded)",
|
|
3576
|
+
ok: siteUuid !== null,
|
|
3577
|
+
hint: identityFound ? "a site identity is recorded but is not a usable UUID \u2014 check `siteUuid` in .patchstackrc.json, or PATCHSTACK_SITE_UUID. The guard protects the app and reports nothing, because there is nothing to attribute a detection to." : "no site identity \u2014 run `npx @patchstack/connect scan` to provision one, or set PATCHSTACK_SITE_UUID in the deployment. Without it the guard protects the app but reports nothing."
|
|
3578
|
+
}
|
|
3579
|
+
];
|
|
3580
|
+
if (state === "on") {
|
|
3581
|
+
checks.push({
|
|
3582
|
+
group: "reporting",
|
|
3583
|
+
label: "detection reporting is switched on for this environment",
|
|
3584
|
+
ok: true,
|
|
3585
|
+
unverifiable: true,
|
|
3586
|
+
hint: "nothing here switches it off, but whether it actually reports depends on the rules the guard resolves at runtime: reporting is on for Patchstack-delivered rules and off for a bundle of your own (`no-managed-rules`). Read `protection.detectionReporting` in the running app for the settled answer. This also only judges the environment it ran in \u2014 a deployment may set an opt-out this machine cannot see."
|
|
3587
|
+
});
|
|
3588
|
+
} else {
|
|
3589
|
+
checks.push({
|
|
3590
|
+
group: "reporting",
|
|
3591
|
+
label: `detection reporting is off for this environment (${state})`,
|
|
3592
|
+
ok: state === "disabled-by-config" || state === "disabled-by-telemetry-opt-out",
|
|
3593
|
+
hint: `${explainReportingState(state)} Judged from this environment only; a deployment's is not this one.`
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
checks.push({
|
|
3597
|
+
group: "reporting",
|
|
3598
|
+
// A wired guard says events CAN be sent. It says nothing about whether any were, or whether the
|
|
3599
|
+
// platform took them, and this is where an operator would otherwise assume both.
|
|
3600
|
+
label: "delivery health (events attempted, acknowledged, refused, dropped)",
|
|
3601
|
+
ok: true,
|
|
3602
|
+
unverifiable: true,
|
|
3603
|
+
hint: "not observable from here \u2014 the counters live in the running guard. Call `protection.detectionHealth()` in the deployment: it is undefined when there is no reporter, and otherwise reports what was attempted, acknowledged, refused and dropped for queue pressure. A wired guard is not evidence that anything arrived."
|
|
3604
|
+
});
|
|
3605
|
+
return checks;
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3490
3608
|
// src/protect/install/index.ts
|
|
3491
3609
|
var ADAPTERS = [
|
|
3492
3610
|
tanstackSupabaseAdapter,
|
|
@@ -3537,17 +3655,25 @@ function runVerify(cwd) {
|
|
|
3537
3655
|
const adapter = ADAPTERS.find((a) => a.detect(cwd));
|
|
3538
3656
|
if (adapter) {
|
|
3539
3657
|
const result = adapter.verify(cwd);
|
|
3540
|
-
return {
|
|
3658
|
+
return {
|
|
3659
|
+
stack: adapter.label,
|
|
3660
|
+
...result,
|
|
3661
|
+
checks: [...result.checks, ...credentialNote(cwd, adapter.name), ...reportingChecks(cwd)]
|
|
3662
|
+
};
|
|
3541
3663
|
}
|
|
3542
3664
|
const generic = genericVerify(cwd);
|
|
3543
|
-
return {
|
|
3665
|
+
return {
|
|
3666
|
+
stack: "generic",
|
|
3667
|
+
...generic,
|
|
3668
|
+
checks: [...generic.checks, ...credentialNote(cwd, "generic"), ...reportingChecks(cwd)]
|
|
3669
|
+
};
|
|
3544
3670
|
} catch (err) {
|
|
3545
3671
|
return { stack: "unknown", wired: false, checks: [{ label: "verification failed", ok: false, hint: String(err?.message ?? err) }] };
|
|
3546
3672
|
}
|
|
3547
3673
|
}
|
|
3548
3674
|
|
|
3549
3675
|
// src/widget.ts
|
|
3550
|
-
import { existsSync as
|
|
3676
|
+
import { existsSync as existsSync11, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
3551
3677
|
import path8 from "path";
|
|
3552
3678
|
var WIDGET_SCRIPT_URL = "https://cdn.patchstack.com/patchstack-widget.js";
|
|
3553
3679
|
var WIDGET_MARKER_ATTR = "data-patchstack-connect-widget";
|
|
@@ -3586,7 +3712,7 @@ ${indent}</body>`;
|
|
|
3586
3712
|
}
|
|
3587
3713
|
function findSourceShell(cwd) {
|
|
3588
3714
|
for (const candidate of SOURCE_SHELL_CANDIDATES) {
|
|
3589
|
-
if (
|
|
3715
|
+
if (existsSync11(path8.join(cwd, candidate))) {
|
|
3590
3716
|
return candidate;
|
|
3591
3717
|
}
|
|
3592
3718
|
}
|
|
@@ -3680,7 +3806,7 @@ function detectPackageManager(cwd) {
|
|
|
3680
3806
|
return declared;
|
|
3681
3807
|
}
|
|
3682
3808
|
for (const { filename, pm } of PM_BY_LOCKFILE) {
|
|
3683
|
-
if (
|
|
3809
|
+
if (existsSync12(path9.join(cwd, filename))) {
|
|
3684
3810
|
return pm;
|
|
3685
3811
|
}
|
|
3686
3812
|
}
|
|
@@ -3777,7 +3903,7 @@ function resolveWidgetFileHint(cwd, framework) {
|
|
|
3777
3903
|
...GENERIC_WIDGET_FILES
|
|
3778
3904
|
];
|
|
3779
3905
|
for (const candidate of candidates) {
|
|
3780
|
-
if (
|
|
3906
|
+
if (existsSync12(path9.join(cwd, candidate))) {
|
|
3781
3907
|
return candidate;
|
|
3782
3908
|
}
|
|
3783
3909
|
}
|
|
@@ -4160,10 +4286,10 @@ import { writeFileSync as writeFileSync8 } from "fs";
|
|
|
4160
4286
|
// src/map/ts-loader.ts
|
|
4161
4287
|
import { createRequire } from "module";
|
|
4162
4288
|
import { pathToFileURL } from "url";
|
|
4163
|
-
import { join as
|
|
4289
|
+
import { join as join13 } from "path";
|
|
4164
4290
|
async function loadTypeScript(cwd) {
|
|
4165
4291
|
try {
|
|
4166
|
-
const req = createRequire(pathToFileURL(
|
|
4292
|
+
const req = createRequire(pathToFileURL(join13(cwd, "package.json")));
|
|
4167
4293
|
const resolved = req.resolve("typescript");
|
|
4168
4294
|
const mod = await import(pathToFileURL(resolved).href);
|
|
4169
4295
|
return mod.default ?? mod;
|
|
@@ -4435,7 +4561,7 @@ function npmPackageOf(spec) {
|
|
|
4435
4561
|
|
|
4436
4562
|
// src/map/sources.ts
|
|
4437
4563
|
import { readFileSync as readFileSync8, readdirSync as readdirSync5, realpathSync, statSync as statSync3 } from "fs";
|
|
4438
|
-
import { join as
|
|
4564
|
+
import { join as join14, relative as relative2, isAbsolute } from "path";
|
|
4439
4565
|
|
|
4440
4566
|
// src/map/routes.ts
|
|
4441
4567
|
var ROUTE_REGISTER_NAMES = ["get", "post", "put", "patch", "delete", "options", "all", "head", "use"];
|
|
@@ -4519,7 +4645,7 @@ function hasEntrySignal(text) {
|
|
|
4519
4645
|
}
|
|
4520
4646
|
function detectFramework(cwd) {
|
|
4521
4647
|
try {
|
|
4522
|
-
const pkg = JSON.parse(readFileSync8(
|
|
4648
|
+
const pkg = JSON.parse(readFileSync8(join14(cwd, "package.json"), "utf8"));
|
|
4523
4649
|
const d = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
4524
4650
|
if (d["@tanstack/react-start"] || d["@tanstack/start"] || d["@tanstack/solid-start"]) return "tanstack-start";
|
|
4525
4651
|
if (d["next"]) return "next";
|
|
@@ -4531,11 +4657,11 @@ function detectFramework(cwd) {
|
|
|
4531
4657
|
} catch {
|
|
4532
4658
|
}
|
|
4533
4659
|
try {
|
|
4534
|
-
if (statSync3(
|
|
4660
|
+
if (statSync3(join14(cwd, "supabase", "functions")).isDirectory()) return "supabase-functions";
|
|
4535
4661
|
} catch {
|
|
4536
4662
|
}
|
|
4537
4663
|
try {
|
|
4538
|
-
if (statSync3(
|
|
4664
|
+
if (statSync3(join14(cwd, "functions")).isDirectory()) return "deno-functions";
|
|
4539
4665
|
} catch {
|
|
4540
4666
|
}
|
|
4541
4667
|
return "unknown";
|
|
@@ -4577,7 +4703,7 @@ function probeForSource(dir, budget) {
|
|
|
4577
4703
|
for (const e of entries) {
|
|
4578
4704
|
if (budget.left-- <= 0) return "unknown";
|
|
4579
4705
|
if (e.isDirectory()) {
|
|
4580
|
-
if (!SKIP_IS_DEFINITIONAL.has(e.name)) dirs.push(
|
|
4706
|
+
if (!SKIP_IS_DEFINITIONAL.has(e.name)) dirs.push(join14(dir, e.name));
|
|
4581
4707
|
} else if (isSourceFile(e.name)) return true;
|
|
4582
4708
|
else if (e.isSymbolicLink()) return "unknown";
|
|
4583
4709
|
}
|
|
@@ -4614,13 +4740,13 @@ function collectSources(dir, boundary, opts, out = [], seen = /* @__PURE__ */ ne
|
|
|
4614
4740
|
const probeable = !SKIP_IS_DEFINITIONAL.has(e.name);
|
|
4615
4741
|
if (probeable && !e.isDirectory() && e.isSymbolicLink()) stats.skippedUnknown++;
|
|
4616
4742
|
else if (probeable && e.isDirectory()) {
|
|
4617
|
-
const held = probeForSource(
|
|
4618
|
-
if (held === true) stats.skippedWithSource.push(
|
|
4743
|
+
const held = probeForSource(join14(dir, e.name), probeBudget);
|
|
4744
|
+
if (held === true) stats.skippedWithSource.push(join14(dir, e.name));
|
|
4619
4745
|
else if (held === "unknown") stats.skippedUnknown++;
|
|
4620
4746
|
}
|
|
4621
4747
|
continue;
|
|
4622
4748
|
}
|
|
4623
|
-
const full =
|
|
4749
|
+
const full = join14(dir, e.name);
|
|
4624
4750
|
if (e.isDirectory()) collectSources(full, boundary, opts, out, seen, stats, probeBudget);
|
|
4625
4751
|
else if (e.isSymbolicLink()) {
|
|
4626
4752
|
let st, real;
|
|
@@ -4690,7 +4816,7 @@ function detectDeploymentShapes(cwd, opts = {}) {
|
|
|
4690
4816
|
const found = [];
|
|
4691
4817
|
for (const candidate of DEPLOYMENT_SHAPES) {
|
|
4692
4818
|
for (const file of candidate.files ?? []) {
|
|
4693
|
-
const full =
|
|
4819
|
+
const full = join14(cwd, file);
|
|
4694
4820
|
try {
|
|
4695
4821
|
if (statSync3(full).isFile() && inProject(full)) {
|
|
4696
4822
|
found.push({ shape: candidate.shape, source: file, evidence: candidate.evidence });
|
|
@@ -4700,7 +4826,7 @@ function detectDeploymentShapes(cwd, opts = {}) {
|
|
|
4700
4826
|
}
|
|
4701
4827
|
}
|
|
4702
4828
|
for (const dir of candidate.dirs ?? []) {
|
|
4703
|
-
const full =
|
|
4829
|
+
const full = join14(cwd, dir);
|
|
4704
4830
|
try {
|
|
4705
4831
|
if (!statSync3(full).isDirectory() || !inProject(full)) continue;
|
|
4706
4832
|
} catch {
|
|
@@ -4719,7 +4845,7 @@ function holdsFunctionEntry(dir) {
|
|
|
4719
4845
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
4720
4846
|
if (!entry.isDirectory() || entry.name.startsWith("_")) continue;
|
|
4721
4847
|
try {
|
|
4722
|
-
for (const nested of readdirSync5(
|
|
4848
|
+
for (const nested of readdirSync5(join14(dir, entry.name), { withFileTypes: true })) {
|
|
4723
4849
|
if (nested.isFile() && /^index\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(nested.name)) return true;
|
|
4724
4850
|
}
|
|
4725
4851
|
} catch {
|
|
@@ -4735,7 +4861,7 @@ function holdsSourceFile(dir) {
|
|
|
4735
4861
|
if (entry.isFile() && isSourceFile(entry.name)) return true;
|
|
4736
4862
|
if (entry.isDirectory()) {
|
|
4737
4863
|
try {
|
|
4738
|
-
for (const nested of readdirSync5(
|
|
4864
|
+
for (const nested of readdirSync5(join14(dir, entry.name), { withFileTypes: true })) {
|
|
4739
4865
|
if (nested.isFile() && isSourceFile(nested.name)) return true;
|
|
4740
4866
|
}
|
|
4741
4867
|
} catch {
|
|
@@ -4749,7 +4875,7 @@ function holdsSourceFile(dir) {
|
|
|
4749
4875
|
|
|
4750
4876
|
// src/map/surface.ts
|
|
4751
4877
|
import { readFileSync as readFileSync9 } from "fs";
|
|
4752
|
-
import { join as
|
|
4878
|
+
import { join as join15 } from "path";
|
|
4753
4879
|
var STATIC_GENERATORS = [
|
|
4754
4880
|
{ dep: "vite", label: "vite" },
|
|
4755
4881
|
{ dep: "react-scripts", label: "create-react-app" },
|
|
@@ -4787,7 +4913,7 @@ var SHAPE_SIGNAL = {
|
|
|
4787
4913
|
};
|
|
4788
4914
|
function readManifest(cwd) {
|
|
4789
4915
|
try {
|
|
4790
|
-
const parsed = JSON.parse(readFileSync9(
|
|
4916
|
+
const parsed = JSON.parse(readFileSync9(join15(cwd, "package.json"), "utf8"));
|
|
4791
4917
|
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
4792
4918
|
} catch {
|
|
4793
4919
|
return null;
|
|
@@ -4800,7 +4926,7 @@ function nextExportsStatically(cwd, manifest, ts) {
|
|
|
4800
4926
|
for (const file of ["next.config.js", "next.config.mjs", "next.config.ts", "next.config.cjs"]) {
|
|
4801
4927
|
let text;
|
|
4802
4928
|
try {
|
|
4803
|
-
text = readFileSync9(
|
|
4929
|
+
text = readFileSync9(join15(cwd, file), "utf8");
|
|
4804
4930
|
} catch {
|
|
4805
4931
|
continue;
|
|
4806
4932
|
}
|
|
@@ -5212,7 +5338,7 @@ function dedupeSinks(sinks, owner) {
|
|
|
5212
5338
|
|
|
5213
5339
|
// src/map/module-graph.ts
|
|
5214
5340
|
import { readFileSync as readFileSync10, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
|
|
5215
|
-
import { dirname as dirname7, join as
|
|
5341
|
+
import { dirname as dirname7, join as join16, relative as relative3, resolve as resolvePath } from "path";
|
|
5216
5342
|
var RESOLVE_EXTS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
5217
5343
|
function createModuleGraph(ts, opts) {
|
|
5218
5344
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -5290,7 +5416,7 @@ function resolveRelativeModule(fromFile, spec) {
|
|
|
5290
5416
|
}
|
|
5291
5417
|
candidates.push(base);
|
|
5292
5418
|
for (const e of RESOLVE_EXTS) candidates.push(base + e);
|
|
5293
|
-
for (const e of RESOLVE_EXTS) candidates.push(
|
|
5419
|
+
for (const e of RESOLVE_EXTS) candidates.push(join16(base, "index" + e));
|
|
5294
5420
|
for (const c of candidates) {
|
|
5295
5421
|
try {
|
|
5296
5422
|
if (statSync4(c).isFile()) return c;
|
|
@@ -5974,7 +6100,7 @@ function handlerEntry(name, kindLabel, params, body, ts, localSinks, bindings, c
|
|
|
5974
6100
|
|
|
5975
6101
|
// src/map/imports.ts
|
|
5976
6102
|
import { readFileSync as readFileSync11 } from "fs";
|
|
5977
|
-
import { join as
|
|
6103
|
+
import { join as join17 } from "path";
|
|
5978
6104
|
var MAX_SITES = 5;
|
|
5979
6105
|
var NPM_NAME = /^(?:@[^/@\s~][^/@\s]*\/)?[^/@\s.~][^/@\s]*$/;
|
|
5980
6106
|
function isNpmPackageName(pkg) {
|
|
@@ -5985,7 +6111,7 @@ function readPathAliases(cwd) {
|
|
|
5985
6111
|
for (const name of ["tsconfig.json", "jsconfig.json"]) {
|
|
5986
6112
|
let paths;
|
|
5987
6113
|
try {
|
|
5988
|
-
const raw = readFileSync11(
|
|
6114
|
+
const raw = readFileSync11(join17(cwd, name), "utf8");
|
|
5989
6115
|
const parsed = JSON.parse(stripJsonComments(raw));
|
|
5990
6116
|
paths = parsed.compilerOptions?.paths;
|
|
5991
6117
|
} catch {
|
|
@@ -7213,12 +7339,18 @@ async function runProtectCommand(args) {
|
|
|
7213
7339
|
if (args.flags.get("check") === true) {
|
|
7214
7340
|
const report = runVerify(process.cwd());
|
|
7215
7341
|
console.log(`patchstack protect --check (${report.stack}):`);
|
|
7216
|
-
|
|
7342
|
+
const line = (c) => {
|
|
7217
7343
|
const mark = c.unverifiable ? "?" : c.ok ? "\u2713" : "\u2717";
|
|
7218
7344
|
const note = c.unverifiable || !c.ok ? c.hint : void 0;
|
|
7219
7345
|
console.log(` ${mark} ${c.label}${note ? ` \u2014 ${note}` : ""}`);
|
|
7220
|
-
}
|
|
7346
|
+
};
|
|
7347
|
+
for (const c of report.checks.filter((c2) => c2.group !== "reporting")) line(c);
|
|
7221
7348
|
console.log(report.wired ? "guard is wired \u2713" : "guard is NOT fully wired \u2717");
|
|
7349
|
+
const reporting = report.checks.filter((c) => c.group === "reporting");
|
|
7350
|
+
if (reporting.length > 0) {
|
|
7351
|
+
console.log("reporting to Patchstack (does not affect the verdict above):");
|
|
7352
|
+
for (const c of reporting) line(c);
|
|
7353
|
+
}
|
|
7222
7354
|
if (report.checks.some((c) => c.unverifiable)) {
|
|
7223
7355
|
console.log("One or more checks could not be answered from here \u2014 see the `?` lines above.");
|
|
7224
7356
|
}
|