refactor(javascript): share the reconstruction input contract

Remove the reconstruction-only request schema and consume the canonical parsed
JavaScript application input. Production already owns parsing at the service
boundary; direct test seams now use that same schema instead of a weaker path
contract. Preserve format, filesystem, source selection and lifecycle validation.

Add a NUL-path regression for canonical admission and typed input-error
projection. Verified 63 focused cases plus static, build, docs, discovery and
duplication checks; no target execution or real-provider claims.
This commit is contained in:
morluto committed 2026-10-24 15:02:26 +08:00
1 parent d68d03e88f
commit bdf15b9bd5
5 files changed
+49 -31

No files matched your search

@@ -20,8 +20,11 @@ import { createJavaScriptArtifactReader as createReader } from "../../artifacts/
import type { JavaScriptApplicationGraph } from "../../domain/javascript/javascriptApplicationGraph.js";
import type { JavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticGraph.js";
import type { JavaScriptSourceSelection } from "../../domain/javascript/javascriptSourceSelection.js";
import type { ElectronBoundarySummary } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { parseOwnedJavaScriptApplicationAnalysisSteps } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import {
parseOwnedJavaScriptApplicationAnalysisSteps,
type AnalyzeJavaScriptApplicationInput,
type ElectronBoundarySummary,
} from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { AnalysisError } from "../../domain/analysisErrorBase.js";
import { analysisErrorWithCleanupFailure } from "../../domain/analysisErrorCleanup.js";
import { ArtifactOperationError } from "../../domain/artifactOperationError.js";
@@ -38,10 +41,6 @@ import { JAVASCRIPT_ANALYSIS_RESOURCE_DEFAULTS } from "../../domain/javascript/j
import { createOwnedJavaScriptApplicationEvidenceCooperatively } from "./JavaScriptApplicationEvidence.js";
import { readJavaScriptArtifactFiles } from "../../artifacts/javascript/JavaScriptArtifactFiles.js";
import { buildImmutableJavaScriptArtifactGraphSteps } from "./JavaScriptArtifactGraphBuilder.js";
import {
javascriptArtifactReconstructionInputSchema,
type JavaScriptArtifactReconstructionInput,
} from "./JavaScriptArtifactReconstructionInput.js";
import { scanCanonicalArtifactInventoryInScope } from "../../artifacts/inventory/scanCanonical.js";
import { createJavaScriptNextAppContext } from "./JavaScriptNextAppContext.js";
import { summarizeElectronBoundaries } from "./ElectronBoundaryAnalysis.js";
@@ -80,9 +79,9 @@ export interface JavaScriptArtifactReconstructionResult {
readonly limitations: readonly string[];
}
/** Reconstruct one local ASAR or extracted directory without executing code. */
/** Reconstruct a parsed local ASAR/directory request without executing code. */
export const reconstructJavaScriptArtifact = async (
rawInput: unknown,
input: AnalyzeJavaScriptApplicationInput,
scope: ArtifactResourceScope,
signal?: AbortSignal,
progress?: ProgressReporter,
@@ -101,7 +100,6 @@ export const reconstructJavaScriptArtifact = async (
});
await checkpointJavaScriptAnalysis(signal);
};
const input = javascriptArtifactReconstructionInputSchema.parse(rawInput);
abortIfNeeded(signal);
const { path, metadata } = await resolveSelectedInput(input.input_path);
const format = resolveFormat(path, metadata, input);
@@ -487,7 +485,7 @@ const selectedInputResolutionMessage = (
const resolveFormat = (
path: string,
metadata: Stats,
input: JavaScriptArtifactReconstructionInput,
input: AnalyzeJavaScriptApplicationInput,
): "asar" | "directory" => {
const observed = metadata.isDirectory()
? "directory"