core/converters/graph.source.converter.ts
core/converters/graph.source.converter.ts is a file in Bane's Lab Build Scripts. 71 lines of code and 16 definitions.
import type { AnatomyFile, AnatomyFolder } from "@banes-lab/web/types/anatomy.types.js";
import type { Graph, SourceIds, Vocabulary } from "#types/graph.types";
import { ANATOMY_PREFIX } from "#configuration/constants/graph.constants";
import type { GraphNode } from "@banes-lab/web/types/graph.types.js";
import type { SourceTree } from "#types/source.types";
import { graphNode } from "#core/factories/graph.factory";
const FOLDER_KIND = "folder";
const FILE_KIND = "file";
const DEFINITION_KIND = "definition";
const SOURCE_LAYER = "source:";
interface Scope {
readonly ids: SourceIds;
readonly layer: GraphNode["layer"];
readonly vocabulary: Vocabulary;
}
const fileGraph = function fileGraph(file: AnatomyFile, folderRef: string, scope: Scope): Graph {
const { ids, layer, vocabulary } = scope;
const fileRef = ANATOMY_PREFIX + ids.fileId(file.path);
const definitions = file.definitions.map((definition) => ({
...graphNode(ANATOMY_PREFIX + definition.id, DEFINITION_KIND, layer, definition.name),
href: ids.nodeHref(file.path, definition.line),
}));
const calls = file.definitions.flatMap((definition) =>
definition.callees.map((callee) => ({
from: ANATOMY_PREFIX + definition.id,
relation: vocabulary.calls,
to: ANATOMY_PREFIX + callee.id,
})),
);
return {
edges: [
{ from: folderRef, relation: vocabulary.contains, to: fileRef },
...definitions.map((held) => ({ from: fileRef, relation: vocabulary.contains, to: held.ref })),
...calls,
],
nodes: [graphNode(fileRef, FILE_KIND, layer, ids.localPath(file.path)), ...definitions],
};
};
const folderGraph = function folderGraph(folder: AnatomyFolder, scope: Scope): Graph {
const ref = ANATOMY_PREFIX + scope.ids.folderId(folder.path);
const files = folder.files.map((file) => fileGraph(file, ref, scope));
const children = folder.folders.map((child) => ({
graph: folderGraph(child, scope),
ref: ANATOMY_PREFIX + scope.ids.folderId(child.path),
}));
return {
edges: [
...children.map((child) => ({ from: ref, relation: scope.vocabulary.contains, to: child.ref })),
...files.flatMap((part) => part.edges),
...children.flatMap((child) => child.graph.edges),
],
nodes: [
{
...graphNode(ref, FOLDER_KIND, scope.layer, scope.ids.localPath(folder.path)),
href: scope.ids.folderHref(folder.path),
},
...files.flatMap((part) => part.nodes),
...children.flatMap((child) => child.graph.nodes),
],
};
};
export const sourceGraph = function sourceGraph(
trees: readonly SourceTree[],
ids: SourceIds,
vocabulary: Vocabulary,
): Graph {
const parts = trees.map((tree) =>
folderGraph(tree.snapshot.tree, { ids, layer: `${SOURCE_LAYER}${tree.tab}`, vocabulary }),
);
return { edges: parts.flatMap((part) => part.edges), nodes: parts.flatMap((part) => part.nodes) };
};