fix(javascript): retain unavailable source processing scopes

This commit is contained in:
morluto committed 2026-10-24 04:14:17 +08:00
1 parent 62f7b5e4cd
commit 1cc16128ea
4 files changed
+80 -10

No files matched your search

@@ -216,7 +216,10 @@ export interface RoleAssetLinkInput {
/** An explicit processing/selection gap with the applicable phase's authority. */
export interface UnavailableParseInput {
readonly file: JavaScriptArtifactFile;
/** Missing source bytes are anchored to their observed inventory container. */
readonly file: Pick<JavaScriptArtifactFile, "path" | "container_sha256"> & {
readonly sha256: string | null;
};
readonly asset: ApplicationNode;
readonly operation: string;
readonly authority: JavaScriptArtifactAnalysisScope["authority"];
@@ -319,10 +322,11 @@ export const addUnavailableStaticParseScope = (
context: JavaScriptArtifactGraphContext,
input: UnavailableParseInput,
): void => {
const artifactSha256 = input.file.sha256 ?? input.file.container_sha256;
const node = context.accumulator.addNode({
kind: "unknown",
identity: artifactLocalIdentity(
input.file.sha256,
artifactSha256,
"static-parse-scope",
`${input.operation}:${input.file.path}`,
),
@@ -335,13 +339,16 @@ export const addUnavailableStaticParseScope = (
path: input.file.path,
operation: input.operation,
limitation: input.limitation,
...(input.file.sha256 === null
? { source_bytes_available: false }
: {}),
...(input.failure === undefined
? {}
: { analysis_failure: input.failure }),
},
evidence: unavailableStaticEvidence({
authority: input.authority,
sha256: input.file.sha256,
sha256: artifactSha256,
path: input.file.path,
operation: input.operation,
coverage:
@@ -362,7 +369,7 @@ export const addUnavailableStaticParseScope = (
relation: "contains",
properties: { scope: "unavailable-static-analysis" },
evidence: artifactObservationEvidence({
sha256: input.file.sha256,
sha256: artifactSha256,
path: input.file.path,
operation: "associate-unavailable-parse-scope",
coverage: completeApplicationCoverage(),
@@ -356,20 +356,23 @@ export const addJavaScriptArtifactFiles = (
},
});
}
addUnavailableAsarEntries(context);
addUnavailableArtifactEntries(context);
};
const addUnavailableAsarEntries = (
const addUnavailableArtifactEntries = (
context: JavaScriptArtifactGraphContext,
): void => {
for (const file of context.fileSet.unavailable_relevant_files) {
if (!isAsarContainer(context, file.container_sha256)) continue;
const asar = isAsarContainer(context, file.container_sha256);
const operation = asar
? "inventory-asar-unavailable-entry"
: "inventory-unavailable-entry";
const limitations = [
...(file.limitations ?? []),
`The inventoried ${file.kind ?? "relevant"} entry has unavailable bytes; no content artifact identity can be established.`,
];
const entry = context.accumulator.addNode({
kind: "asar-entry",
kind: asar ? "asar-entry" : "artifact",
identity: {
strategy: "canonical-path",
stability: "artifact-version",
@@ -380,6 +383,7 @@ const addUnavailableAsarEntries = (
{
label: file.path,
properties: {
path: file.path,
entry_sha256: file.sha256,
bytes: file.bytes,
inventory_artifact_id: file.inventory_artifact_id,
@@ -394,7 +398,7 @@ const addUnavailableAsarEntries = (
evidence: artifactObservationEvidence({
sha256: file.container_sha256,
path: file.path,
operation: "inventory-asar-unavailable-entry",
operation,
coverage: partialApplicationCoverage([], null),
limitations,
}),
@@ -415,11 +419,29 @@ const addUnavailableAsarEntries = (
evidence: artifactObservationEvidence({
sha256: file.container_sha256,
path: file.path,
operation: "inventory-asar-unavailable-entry",
operation,
coverage: partialApplicationCoverage([], null),
limitations,
}),
});
const scope =
file.kind === undefined
? null
: javascriptArtifactAnalysisScopes[file.kind];
if (scope !== null)
addUnavailableStaticParseScope(context, {
file,
asset: entry,
...scope,
limitation: limitations.join(" "),
...(file.inventory_occurrence_id === undefined
? {}
: {
details: {
inventory_occurrence_id: file.inventory_occurrence_id,
},
}),
});
if (file.kind === "native-addon" || file.artifact_kind === "native-addon") {
const addon = context.accumulator.addNode({
kind: "native-addon",