diff --git a/data-extraction/src/js/api/default-extractors/ObjectGraphExtractor.ts b/data-extraction/src/js/api/default-extractors/ObjectGraphExtractor.ts new file mode 100644 index 0000000..942f8a0 --- /dev/null +++ b/data-extraction/src/js/api/default-extractors/ObjectGraphExtractor.ts @@ -0,0 +1,79 @@ +import { ExtractedData } from "../../../DataExtractionResult"; +import { + DataExtractor, + ExtractionCollector, + DataExtractorContext, +} from "../DataExtractorApi"; +import { createGraph, CreateGraphEdge } from "../../helpers"; + +export class ObjectGraphExtractor implements DataExtractor { + readonly id = "object-graph"; + + getExtractions( + data: unknown, + collector: ExtractionCollector, + context: DataExtractorContext + ): void { + function isObject(val: unknown): val is object { + if (typeof val !== "object") { + return false; + } + if (!val) { + return false; + } + return true; + } + if (!isObject(data)) { + return; + } + + collector.addExtraction({ + id: "object-graph", + name: "Object Graph", + priority: 99, + extractData() { + return createGraph( + [data], + item => { + let label = ""; + const edges = new Array>(); + if (item instanceof Set) { + label = "Set"; + for (const value of item.values()) { + if (isObject(value)) { + edges.push({ label: "item", to: value }); + } + } + } else if (item instanceof Map) { + label = "Map"; + for (const [key, value] of item.entries()) { + if (isObject(value)) { + edges.push({ label: key, to: value }); + } + } + } else { + for (const [key, val] of Object.entries(item)) { + if (isObject(val)) { + edges.push({ label: key, to: val }); + } + } + + const className = item.constructor + ? item.constructor.name + : "?"; + label = className; + } + + return { + shape: "box", + edges, + color: item === data ? "lightblue" : undefined, + label, + }; + }, + { maxSize: 50 } + ); + }, + }); + } +} diff --git a/data-extraction/src/js/api/default-extractors/registerDefaultDataExtractors.ts b/data-extraction/src/js/api/default-extractors/registerDefaultDataExtractors.ts index 2d22b61..a9c8984 100644 --- a/data-extraction/src/js/api/default-extractors/registerDefaultDataExtractors.ts +++ b/data-extraction/src/js/api/default-extractors/registerDefaultDataExtractors.ts @@ -4,18 +4,23 @@ import { AsIsDataExtractor } from "./AsIsDataExtractor"; import { GetDebugVisualizationDataExtractor } from "./GetDebugVisualizationDataExtractor"; import { ToStringDataExtractor } from "./ToStringExtractor"; import { PlotDataExtractor } from "./PlotlyDataExtractor"; +import { ObjectGraphExtractor } from "./ObjectGraphExtractor"; +import { getDataExtractorApi } from "../injection"; /** * The default data extractors should be registered by VS Code automatically. * Registering them manually ensures that they are up to date. */ -export function registerDefaultDataExtractors(api: DataExtractorApi) { +export function registerDefaultExtractors( + api: DataExtractorApi = getDataExtractorApi() +) { for (const item of [ new TypeScriptAstDataExtractor(), new AsIsDataExtractor(), new GetDebugVisualizationDataExtractor(), new ToStringDataExtractor(), new PlotDataExtractor(), + new ObjectGraphExtractor(), ]) { api.registerExtractor(item); }