rea/src/application/JavaScriptJsonModules.ts

47 lines
1.4 KiB
TypeScript

import type { JavaScriptJsonModuleObservation } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
/** Parse one approved JSON module without evaluating JavaScript or resolving imports. */
export const analyzeJavaScriptJsonModule = (
file: JavaScriptArtifactFile,
): JavaScriptJsonModuleObservation => {
if (!file.text.included)
return {
path: file.path,
sha256: file.sha256,
status: "unavailable",
top_level_keys: [],
omitted_top_level_keys: null,
limitation: `JSON module text was unavailable: ${file.text.reason}.`,
};
let value: unknown;
try {
value = JSON.parse(file.text.value);
} catch {
return {
path: file.path,
sha256: file.sha256,
status: "invalid",
top_level_keys: [],
omitted_top_level_keys: 0,
limitation: "JSON module is not valid JSON.",
};
}
const keys =
typeof value === "object" && value !== null && !Array.isArray(value)
? Object.keys(value).sort(compareCodePoints)
: [];
const retained = keys.slice(0, 128);
return {
path: file.path,
sha256: file.sha256,
status: "included",
top_level_keys: retained,
omitted_top_level_keys: keys.length - retained.length,
limitation: null,
};
};
const compareCodePoints = (left: string, right: string): number =>
left < right ? -1 : left > right ? 1 : 0;