147 lines
5.0 KiB
TypeScript
147 lines
5.0 KiB
TypeScript
import type { ExecutionOptions } from "../AnalysisProvider.js";
|
|
import type { JavaScriptRuntimeObservationPort } from "./JavaScriptRuntimeObservationPort.js";
|
|
import { createJavaScriptRuntimeObservationEvidence } from "./JavaScriptRuntimeObservationEvidence.js";
|
|
import type { Evidence } from "../../domain/evidence.js";
|
|
import {
|
|
AnalysisCancelledError,
|
|
AnalysisCapabilityUnavailableError,
|
|
AnalysisOutputError,
|
|
} from "../../domain/analysisErrorCore.js";
|
|
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
|
|
import type {
|
|
ListJavaScriptRuntimeTargetsInput,
|
|
ObserveJavaScriptRuntimeInput,
|
|
} from "../../domain/javascript/javascriptRuntimeObservation.js";
|
|
import { err, ok, type Result } from "../../domain/result.js";
|
|
import { completeProviderEvidence } from "../ProviderOperationExecution.js";
|
|
import {
|
|
javascriptRuntimeObservationSchema,
|
|
javascriptRuntimeTargetListSchema,
|
|
} from "../../domain/javascript/javascriptRuntimeObservation.js";
|
|
|
|
/** List targets exposed by the explicitly selected loopback Inspector. */
|
|
export const listJavaScriptRuntimeTargets = async (
|
|
provider: JavaScriptRuntimeObservationPort | undefined,
|
|
input: ListJavaScriptRuntimeTargetsInput,
|
|
options: ExecutionOptions = {},
|
|
): Promise<Result<Evidence, AnalysisError>> => {
|
|
const ready = requireProvider(provider, "list_javascript_runtime_targets");
|
|
if (!ready.ok) return ready;
|
|
if (options.signal?.aborted)
|
|
return err(
|
|
new AnalysisCancelledError("list_javascript_runtime_targets", {
|
|
cause: options.signal.reason,
|
|
}),
|
|
);
|
|
const result = await ready.value.listTargets(input, options);
|
|
if (!result.ok) return result;
|
|
const report = javascriptRuntimeTargetListSchema.safeParse(result.value);
|
|
if (!report.success)
|
|
return err(
|
|
new AnalysisOutputError(
|
|
"list_javascript_runtime_targets",
|
|
"Inspector returned a malformed target list.",
|
|
{ cause: report.error },
|
|
),
|
|
);
|
|
return runtimeEvidence(
|
|
"list_javascript_runtime_targets",
|
|
input,
|
|
report.data,
|
|
ready.value.identity(),
|
|
options,
|
|
);
|
|
};
|
|
|
|
/** Observe one attach-only Inspector target selected by the request. */
|
|
export const observeJavaScriptRuntime = async (
|
|
provider: JavaScriptRuntimeObservationPort | undefined,
|
|
input: ObserveJavaScriptRuntimeInput,
|
|
options: ExecutionOptions = {},
|
|
): Promise<Result<Evidence, AnalysisError>> => {
|
|
const ready = requireProvider(provider, "observe_javascript_runtime");
|
|
if (!ready.ok) return ready;
|
|
if (options.signal?.aborted)
|
|
return err(
|
|
new AnalysisCancelledError("observe_javascript_runtime", {
|
|
cause: options.signal.reason,
|
|
}),
|
|
);
|
|
const result = await ready.value.observe(input, options);
|
|
if (!result.ok) {
|
|
const partial = result.error.partialObservation;
|
|
if (
|
|
partial !== undefined &&
|
|
!("evidence_id" in partial) &&
|
|
!("kind" in partial)
|
|
) {
|
|
const report = javascriptRuntimeObservationSchema.safeParse(partial);
|
|
if (!report.success && result.error instanceof AnalysisCancelledError)
|
|
return err(
|
|
new AnalysisOutputError(
|
|
"observe_javascript_runtime",
|
|
"Inspector retained a malformed completed runtime observation.",
|
|
{ cause: report.error },
|
|
),
|
|
);
|
|
if (report.success)
|
|
result.error.partialObservation =
|
|
createJavaScriptRuntimeObservationEvidence(
|
|
"observe_javascript_runtime",
|
|
input,
|
|
report.data,
|
|
ready.value.identity(),
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
const report = javascriptRuntimeObservationSchema.safeParse(result.value);
|
|
if (!report.success)
|
|
return err(
|
|
new AnalysisOutputError(
|
|
"observe_javascript_runtime",
|
|
"Inspector returned a malformed runtime observation.",
|
|
{ cause: report.error },
|
|
),
|
|
);
|
|
return runtimeEvidence(
|
|
"observe_javascript_runtime",
|
|
input,
|
|
report.data,
|
|
ready.value.identity(),
|
|
options,
|
|
);
|
|
};
|
|
|
|
const requireProvider = (
|
|
provider: JavaScriptRuntimeObservationPort | undefined,
|
|
operation: "list_javascript_runtime_targets" | "observe_javascript_runtime",
|
|
): Result<JavaScriptRuntimeObservationPort, AnalysisError> =>
|
|
provider === undefined
|
|
? err(
|
|
new AnalysisCapabilityUnavailableError(
|
|
"rea-v8-inspector",
|
|
operation,
|
|
"V8 Inspector observation provider is not configured",
|
|
),
|
|
)
|
|
: ok(provider);
|
|
|
|
const runtimeEvidence = (
|
|
operation: Parameters<typeof createJavaScriptRuntimeObservationEvidence>[0],
|
|
input: Parameters<typeof createJavaScriptRuntimeObservationEvidence>[1],
|
|
result: Parameters<typeof createJavaScriptRuntimeObservationEvidence>[2],
|
|
provider: Parameters<typeof createJavaScriptRuntimeObservationEvidence>[3],
|
|
options: ExecutionOptions,
|
|
): Result<Evidence, AnalysisError> => {
|
|
return completeProviderEvidence(
|
|
createJavaScriptRuntimeObservationEvidence(
|
|
operation,
|
|
input,
|
|
result,
|
|
provider,
|
|
),
|
|
options.signal,
|
|
);
|
|
};
|