refactor(core): extract shared dedup helpers

This commit is contained in:
Peter Steinberger
2026-03-07 10:40:49 +00:00
parent 14c61bb33f
commit 3c71e2bd48
114 changed files with 3400 additions and 2040 deletions

View File

@@ -540,12 +540,9 @@ async function resolveOutsideBoundaryPathAsync(params: {
return null;
}
const kind = await getPathKind(params.context.absolutePath, false);
return buildOutsideLexicalBoundaryPath({
return buildOutsideBoundaryPathFromContext({
boundaryLabel: params.boundaryLabel,
rootCanonicalPath: params.context.rootCanonicalPath,
absolutePath: params.context.absolutePath,
canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath,
rootPath: params.context.rootPath,
context: params.context,
kind,
});
}
@@ -558,13 +555,25 @@ function resolveOutsideBoundaryPathSync(params: {
return null;
}
const kind = getPathKindSync(params.context.absolutePath, false);
return buildOutsideBoundaryPathFromContext({
boundaryLabel: params.boundaryLabel,
context: params.context,
kind,
});
}
function buildOutsideBoundaryPathFromContext(params: {
boundaryLabel: string;
context: BoundaryResolutionContext;
kind: { exists: boolean; kind: ResolvedBoundaryPathKind };
}): ResolvedBoundaryPath {
return buildOutsideLexicalBoundaryPath({
boundaryLabel: params.boundaryLabel,
rootCanonicalPath: params.context.rootCanonicalPath,
absolutePath: params.context.absolutePath,
canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath,
rootPath: params.context.rootPath,
kind,
kind: params.kind,
});
}

View File

@@ -11,6 +11,30 @@ export type ExecHost = "sandbox" | "gateway" | "node";
export type ExecSecurity = "deny" | "allowlist" | "full";
export type ExecAsk = "off" | "on-miss" | "always";
export function normalizeExecHost(value?: string | null): ExecHost | null {
const normalized = value?.trim().toLowerCase();
if (normalized === "sandbox" || normalized === "gateway" || normalized === "node") {
return normalized;
}
return null;
}
export function normalizeExecSecurity(value?: string | null): ExecSecurity | null {
const normalized = value?.trim().toLowerCase();
if (normalized === "deny" || normalized === "allowlist" || normalized === "full") {
return normalized;
}
return null;
}
export function normalizeExecAsk(value?: string | null): ExecAsk | null {
const normalized = value?.trim().toLowerCase();
if (normalized === "off" || normalized === "on-miss" || normalized === "always") {
return normalized;
}
return null;
}
export type SystemRunApprovalBinding = {
argv: string[];
cwd: string | null;

View File

@@ -10,8 +10,7 @@ import {
import { rejectPendingPairingRequest } from "./pairing-pending.js";
import { generatePairingToken, verifyPairingToken } from "./pairing-token.js";
export type NodePairingPendingRequest = {
requestId: string;
type NodePairingNodeMetadata = {
nodeId: string;
displayName?: string;
platform?: string;
@@ -24,26 +23,18 @@ export type NodePairingPendingRequest = {
commands?: string[];
permissions?: Record<string, boolean>;
remoteIp?: string;
};
export type NodePairingPendingRequest = NodePairingNodeMetadata & {
requestId: string;
silent?: boolean;
isRepair?: boolean;
ts: number;
};
export type NodePairingPairedNode = {
nodeId: string;
export type NodePairingPairedNode = Omit<NodePairingNodeMetadata, "requestId"> & {
token: string;
displayName?: string;
platform?: string;
version?: string;
coreVersion?: string;
uiVersion?: string;
deviceFamily?: string;
modelIdentifier?: string;
caps?: string[];
commands?: string[];
bins?: string[];
permissions?: Record<string, boolean>;
remoteIp?: string;
createdAtMs: number;
approvedAtMs: number;
lastConnectedAtMs?: number;

View File

@@ -0,0 +1,19 @@
import { describe, expect, it } from "vitest";
import { parseFiniteNumber } from "./parse-finite-number.js";
describe("parseFiniteNumber", () => {
it("returns finite numbers", () => {
expect(parseFiniteNumber(42)).toBe(42);
});
it("parses numeric strings", () => {
expect(parseFiniteNumber("3.14")).toBe(3.14);
});
it("returns undefined for non-finite or non-numeric values", () => {
expect(parseFiniteNumber(Number.NaN)).toBeUndefined();
expect(parseFiniteNumber(Number.POSITIVE_INFINITY)).toBeUndefined();
expect(parseFiniteNumber("not-a-number")).toBeUndefined();
expect(parseFiniteNumber(null)).toBeUndefined();
});
});

View File

@@ -0,0 +1,12 @@
export function parseFiniteNumber(value: unknown): number | undefined {
if (typeof value === "number" && Number.isFinite(value)) {
return value;
}
if (typeof value === "string") {
const parsed = Number.parseFloat(value);
if (Number.isFinite(parsed)) {
return parsed;
}
}
return undefined;
}

View File

@@ -1,3 +1,4 @@
import { parseFiniteNumber as parseFiniteNumberish } from "./parse-finite-number.js";
import { PROVIDER_LABELS } from "./provider-usage.shared.js";
import type { ProviderUsageSnapshot, UsageProviderId } from "./provider-usage.types.js";
@@ -17,16 +18,7 @@ export async function fetchJson(
}
export function parseFiniteNumber(value: unknown): number | undefined {
if (typeof value === "number" && Number.isFinite(value)) {
return value;
}
if (typeof value === "string") {
const parsed = Number.parseFloat(value);
if (Number.isFinite(parsed)) {
return parsed;
}
}
return undefined;
return parseFiniteNumberish(value);
}
type BuildUsageHttpErrorSnapshotOptions = {