@grafema/util 0.3.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/dist/api/GraphAPI.d.ts +87 -0
- package/dist/api/GraphAPI.d.ts.map +1 -0
- package/dist/api/GraphAPI.js +212 -0
- package/dist/api/GraphAPI.js.map +1 -0
- package/dist/api/GuaranteeAPI.d.ts +147 -0
- package/dist/api/GuaranteeAPI.d.ts.map +1 -0
- package/dist/api/GuaranteeAPI.js +290 -0
- package/dist/api/GuaranteeAPI.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +214 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +441 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +199 -0
- package/dist/core/CoverageAnalyzer.js.map +1 -0
- package/dist/core/FileExplainer.d.ts +101 -0
- package/dist/core/FileExplainer.d.ts.map +1 -0
- package/dist/core/FileExplainer.js +140 -0
- package/dist/core/FileExplainer.js.map +1 -0
- package/dist/core/FileOverview.d.ts +124 -0
- package/dist/core/FileOverview.d.ts.map +1 -0
- package/dist/core/FileOverview.js +279 -0
- package/dist/core/FileOverview.js.map +1 -0
- package/dist/core/GrafemaUri.d.ts +66 -0
- package/dist/core/GrafemaUri.d.ts.map +1 -0
- package/dist/core/GrafemaUri.js +191 -0
- package/dist/core/GrafemaUri.js.map +1 -0
- package/dist/core/GraphBackend.d.ts +158 -0
- package/dist/core/GraphBackend.d.ts.map +1 -0
- package/dist/core/GraphBackend.js +85 -0
- package/dist/core/GraphBackend.js.map +1 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +104 -0
- package/dist/core/GraphFreshnessChecker.js.map +1 -0
- package/dist/core/GuaranteeManager.d.ts +254 -0
- package/dist/core/GuaranteeManager.d.ts.map +1 -0
- package/dist/core/GuaranteeManager.js +447 -0
- package/dist/core/GuaranteeManager.js.map +1 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +46 -0
- package/dist/core/HashUtils.js.map +1 -0
- package/dist/core/IncrementalReanalyzer.d.ts +33 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +67 -0
- package/dist/core/IncrementalReanalyzer.js.map +1 -0
- package/dist/core/ResourceRegistry.d.ts +17 -0
- package/dist/core/ResourceRegistry.d.ts.map +1 -0
- package/dist/core/ResourceRegistry.js +32 -0
- package/dist/core/ResourceRegistry.js.map +1 -0
- package/dist/core/SemanticId.d.ts +159 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +291 -0
- package/dist/core/SemanticId.js.map +1 -0
- package/dist/core/VersionManager.d.ts +166 -0
- package/dist/core/VersionManager.d.ts.map +1 -0
- package/dist/core/VersionManager.js +239 -0
- package/dist/core/VersionManager.js.map +1 -0
- package/dist/core/brandNodeInternal.d.ts +14 -0
- package/dist/core/brandNodeInternal.d.ts.map +1 -0
- package/dist/core/brandNodeInternal.js +4 -0
- package/dist/core/brandNodeInternal.js.map +1 -0
- package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
- package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
- package/dist/core/nodes/GuaranteeNode.js +118 -0
- package/dist/core/nodes/GuaranteeNode.js.map +1 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +130 -0
- package/dist/core/nodes/IssueNode.js.map +1 -0
- package/dist/core/nodes/NodeKind.d.ts +104 -0
- package/dist/core/nodes/NodeKind.d.ts.map +1 -0
- package/dist/core/nodes/NodeKind.js +166 -0
- package/dist/core/nodes/NodeKind.js.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +103 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +133 -0
- package/dist/diagnostics/DiagnosticCollector.js.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +122 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +300 -0
- package/dist/diagnostics/DiagnosticReporter.js.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +44 -0
- package/dist/diagnostics/DiagnosticWriter.js.map +1 -0
- package/dist/diagnostics/categories.d.ts +57 -0
- package/dist/diagnostics/categories.d.ts.map +1 -0
- package/dist/diagnostics/categories.js +71 -0
- package/dist/diagnostics/categories.js.map +1 -0
- package/dist/diagnostics/index.d.ts +17 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +15 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/errors/GrafemaError.d.ts +200 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +209 -0
- package/dist/errors/GrafemaError.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/instructions/index.d.ts +8 -0
- package/dist/instructions/index.d.ts.map +1 -0
- package/dist/instructions/index.js +20 -0
- package/dist/instructions/index.js.map +1 -0
- package/dist/instructions/onboarding.md +133 -0
- package/dist/knowledge/KnowledgeBase.d.ts +113 -0
- package/dist/knowledge/KnowledgeBase.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeBase.js +420 -0
- package/dist/knowledge/KnowledgeBase.js.map +1 -0
- package/dist/knowledge/SemanticAddressResolver.d.ts +59 -0
- package/dist/knowledge/SemanticAddressResolver.d.ts.map +1 -0
- package/dist/knowledge/SemanticAddressResolver.js +160 -0
- package/dist/knowledge/SemanticAddressResolver.js.map +1 -0
- package/dist/knowledge/git-ingest.d.ts +58 -0
- package/dist/knowledge/git-ingest.d.ts.map +1 -0
- package/dist/knowledge/git-ingest.js +301 -0
- package/dist/knowledge/git-ingest.js.map +1 -0
- package/dist/knowledge/git-queries.d.ts +86 -0
- package/dist/knowledge/git-queries.d.ts.map +1 -0
- package/dist/knowledge/git-queries.js +177 -0
- package/dist/knowledge/git-queries.js.map +1 -0
- package/dist/knowledge/index.d.ts +14 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +10 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/knowledge/parser.d.ts +39 -0
- package/dist/knowledge/parser.d.ts.map +1 -0
- package/dist/knowledge/parser.js +292 -0
- package/dist/knowledge/parser.js.map +1 -0
- package/dist/knowledge/types.d.ts +133 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +8 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/logging/Logger.d.ts +98 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +274 -0
- package/dist/logging/Logger.js.map +1 -0
- package/dist/notation/archetypes.d.ts +36 -0
- package/dist/notation/archetypes.d.ts.map +1 -0
- package/dist/notation/archetypes.js +173 -0
- package/dist/notation/archetypes.js.map +1 -0
- package/dist/notation/fold.d.ts +25 -0
- package/dist/notation/fold.d.ts.map +1 -0
- package/dist/notation/fold.js +598 -0
- package/dist/notation/fold.js.map +1 -0
- package/dist/notation/index.d.ts +18 -0
- package/dist/notation/index.d.ts.map +1 -0
- package/dist/notation/index.js +16 -0
- package/dist/notation/index.js.map +1 -0
- package/dist/notation/lodExtractor.d.ts +32 -0
- package/dist/notation/lodExtractor.d.ts.map +1 -0
- package/dist/notation/lodExtractor.js +149 -0
- package/dist/notation/lodExtractor.js.map +1 -0
- package/dist/notation/nameShortener.d.ts +22 -0
- package/dist/notation/nameShortener.d.ts.map +1 -0
- package/dist/notation/nameShortener.js +24 -0
- package/dist/notation/nameShortener.js.map +1 -0
- package/dist/notation/perspectives.d.ts +11 -0
- package/dist/notation/perspectives.d.ts.map +1 -0
- package/dist/notation/perspectives.js +16 -0
- package/dist/notation/perspectives.js.map +1 -0
- package/dist/notation/renderer.d.ts +31 -0
- package/dist/notation/renderer.d.ts.map +1 -0
- package/dist/notation/renderer.js +315 -0
- package/dist/notation/renderer.js.map +1 -0
- package/dist/notation/traceRenderer.d.ts +39 -0
- package/dist/notation/traceRenderer.d.ts.map +1 -0
- package/dist/notation/traceRenderer.js +358 -0
- package/dist/notation/traceRenderer.js.map +1 -0
- package/dist/notation/types.d.ts +66 -0
- package/dist/notation/types.d.ts.map +1 -0
- package/dist/notation/types.js +10 -0
- package/dist/notation/types.js.map +1 -0
- package/dist/queries/NodeContext.d.ts +81 -0
- package/dist/queries/NodeContext.d.ts.map +1 -0
- package/dist/queries/NodeContext.js +196 -0
- package/dist/queries/NodeContext.js.map +1 -0
- package/dist/queries/findCallsInFunction.d.ts +62 -0
- package/dist/queries/findCallsInFunction.d.ts.map +1 -0
- package/dist/queries/findCallsInFunction.js +169 -0
- package/dist/queries/findCallsInFunction.js.map +1 -0
- package/dist/queries/findContainingFunction.d.ts +57 -0
- package/dist/queries/findContainingFunction.d.ts.map +1 -0
- package/dist/queries/findContainingFunction.js +91 -0
- package/dist/queries/findContainingFunction.js.map +1 -0
- package/dist/queries/index.d.ts +18 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +14 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/traceDataflow.d.ts +65 -0
- package/dist/queries/traceDataflow.d.ts.map +1 -0
- package/dist/queries/traceDataflow.js +754 -0
- package/dist/queries/traceDataflow.js.map +1 -0
- package/dist/queries/traceValues.d.ts +70 -0
- package/dist/queries/traceValues.d.ts.map +1 -0
- package/dist/queries/traceValues.js +373 -0
- package/dist/queries/traceValues.js.map +1 -0
- package/dist/queries/types.d.ts +166 -0
- package/dist/queries/types.d.ts.map +1 -0
- package/dist/queries/types.js +10 -0
- package/dist/queries/types.js.map +1 -0
- package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
- package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +125 -0
- package/dist/schema/GraphSchemaExtractor.js.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +113 -0
- package/dist/schema/InterfaceSchemaExtractor.js.map +1 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +356 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.js +748 -0
- package/dist/storage/backends/RFDBServerBackend.js.map +1 -0
- package/dist/storage/backends/typeValidation.d.ts +47 -0
- package/dist/storage/backends/typeValidation.d.ts.map +1 -0
- package/dist/storage/backends/typeValidation.js +141 -0
- package/dist/storage/backends/typeValidation.js.map +1 -0
- package/dist/utils/findRfdbBinary.d.ts +67 -0
- package/dist/utils/findRfdbBinary.d.ts.map +1 -0
- package/dist/utils/findRfdbBinary.js +261 -0
- package/dist/utils/findRfdbBinary.js.map +1 -0
- package/dist/utils/lazyDownload.d.ts +43 -0
- package/dist/utils/lazyDownload.d.ts.map +1 -0
- package/dist/utils/lazyDownload.js +175 -0
- package/dist/utils/lazyDownload.js.map +1 -0
- package/dist/utils/moduleResolution.d.ts +134 -0
- package/dist/utils/moduleResolution.d.ts.map +1 -0
- package/dist/utils/moduleResolution.js +189 -0
- package/dist/utils/moduleResolution.js.map +1 -0
- package/dist/utils/resolveNodeFile.d.ts +13 -0
- package/dist/utils/resolveNodeFile.d.ts.map +1 -0
- package/dist/utils/resolveNodeFile.js +18 -0
- package/dist/utils/resolveNodeFile.js.map +1 -0
- package/dist/utils/startRfdbServer.d.ts +63 -0
- package/dist/utils/startRfdbServer.d.ts.map +1 -0
- package/dist/utils/startRfdbServer.js +142 -0
- package/dist/utils/startRfdbServer.js.map +1 -0
- package/dist/validation/PathValidator.d.ts +80 -0
- package/dist/validation/PathValidator.d.ts.map +1 -0
- package/dist/validation/PathValidator.js +252 -0
- package/dist/validation/PathValidator.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +26 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
- package/src/api/GraphAPI.ts +307 -0
- package/src/api/GuaranteeAPI.ts +402 -0
- package/src/config/ConfigLoader.ts +653 -0
- package/src/config/index.ts +13 -0
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/FileOverview.ts +397 -0
- package/src/core/GrafemaUri.ts +216 -0
- package/src/core/GraphBackend.ts +266 -0
- package/src/core/GraphFreshnessChecker.ts +145 -0
- package/src/core/GuaranteeManager.ts +684 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +106 -0
- package/src/core/ResourceRegistry.ts +39 -0
- package/src/core/SemanticId.ts +423 -0
- package/src/core/VersionManager.ts +405 -0
- package/src/core/brandNodeInternal.ts +16 -0
- package/src/core/nodes/GuaranteeNode.ts +162 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/NodeKind.ts +192 -0
- package/src/diagnostics/DiagnosticCollector.ts +170 -0
- package/src/diagnostics/DiagnosticReporter.ts +395 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/categories.ts +104 -0
- package/src/diagnostics/index.ts +30 -0
- package/src/errors/GrafemaError.ts +297 -0
- package/src/index.ts +261 -0
- package/src/instructions/index.ts +21 -0
- package/src/instructions/onboarding.md +133 -0
- package/src/knowledge/KnowledgeBase.ts +486 -0
- package/src/knowledge/SemanticAddressResolver.ts +191 -0
- package/src/knowledge/git-ingest.ts +402 -0
- package/src/knowledge/git-queries.ts +269 -0
- package/src/knowledge/index.ts +29 -0
- package/src/knowledge/parser.ts +294 -0
- package/src/knowledge/types.ts +146 -0
- package/src/logging/Logger.ts +303 -0
- package/src/notation/archetypes.ts +189 -0
- package/src/notation/fold.ts +696 -0
- package/src/notation/index.ts +27 -0
- package/src/notation/lodExtractor.ts +177 -0
- package/src/notation/nameShortener.ts +24 -0
- package/src/notation/perspectives.ts +18 -0
- package/src/notation/renderer.ts +394 -0
- package/src/notation/traceRenderer.ts +458 -0
- package/src/notation/types.ts +79 -0
- package/src/queries/NodeContext.ts +280 -0
- package/src/queries/findCallsInFunction.ts +249 -0
- package/src/queries/findContainingFunction.ts +124 -0
- package/src/queries/index.ts +44 -0
- package/src/queries/traceDataflow.ts +838 -0
- package/src/queries/traceValues.ts +531 -0
- package/src/queries/types.ts +191 -0
- package/src/schema/GraphSchemaExtractor.ts +177 -0
- package/src/schema/InterfaceSchemaExtractor.ts +173 -0
- package/src/schema/index.ts +5 -0
- package/src/storage/backends/RFDBServerBackend.ts +895 -0
- package/src/storage/backends/typeValidation.ts +154 -0
- package/src/utils/findRfdbBinary.ts +288 -0
- package/src/utils/lazyDownload.ts +206 -0
- package/src/utils/moduleResolution.ts +271 -0
- package/src/utils/resolveNodeFile.ts +18 -0
- package/src/utils/startRfdbServer.ts +197 -0
- package/src/validation/PathValidator.ts +334 -0
- package/src/version.ts +28 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphSchemaExtractor - Extracts graph node/edge type schemas
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const extractor = new GraphSchemaExtractor(backend);
|
|
6
|
+
* const schema = await extractor.extract();
|
|
7
|
+
*
|
|
8
|
+
* When to use:
|
|
9
|
+
* - Export graph schema for contract tracking
|
|
10
|
+
* - Track node/edge type changes via checksum
|
|
11
|
+
* - Generate graph documentation
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createHash } from 'crypto';
|
|
15
|
+
import { NODE_TYPE, NAMESPACED_TYPE, EDGE_TYPE } from '@grafema/types';
|
|
16
|
+
import type { RFDBServerBackend } from '../storage/backends/RFDBServerBackend.js';
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Types
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
export interface NodeTypeSchema {
|
|
23
|
+
category: 'base' | 'namespaced';
|
|
24
|
+
namespace?: string;
|
|
25
|
+
count: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface EdgeTypeSchema {
|
|
29
|
+
count: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface GraphSchema {
|
|
33
|
+
$schema: 'grafema-graph-v1';
|
|
34
|
+
extractedAt: string;
|
|
35
|
+
nodeTypes: Record<string, NodeTypeSchema>;
|
|
36
|
+
edgeTypes: Record<string, EdgeTypeSchema>;
|
|
37
|
+
statistics: {
|
|
38
|
+
totalNodes: number;
|
|
39
|
+
totalEdges: number;
|
|
40
|
+
nodeTypeCount: number;
|
|
41
|
+
edgeTypeCount: number;
|
|
42
|
+
};
|
|
43
|
+
checksum: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Extractor
|
|
48
|
+
// ============================================================================
|
|
49
|
+
|
|
50
|
+
export interface GraphExtractOptions {
|
|
51
|
+
/** Include all defined types, not just used ones (default: false) */
|
|
52
|
+
includeAll?: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class GraphSchemaExtractor {
|
|
56
|
+
constructor(private backend: RFDBServerBackend) {}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extract graph schema from current database
|
|
60
|
+
*
|
|
61
|
+
* @param options.includeAll - If true, include all defined types even with count=0
|
|
62
|
+
*/
|
|
63
|
+
async extract(options?: GraphExtractOptions): Promise<GraphSchema> {
|
|
64
|
+
const includeAll = options?.includeAll ?? false;
|
|
65
|
+
// Get actual counts from graph
|
|
66
|
+
const nodeCounts = await this.backend.countNodesByType();
|
|
67
|
+
const edgeCounts = await this.backend.countEdgesByType();
|
|
68
|
+
|
|
69
|
+
// Build node types from definitions + counts
|
|
70
|
+
const nodeTypes: Record<string, NodeTypeSchema> = {};
|
|
71
|
+
|
|
72
|
+
// Base node types
|
|
73
|
+
for (const [_key, value] of Object.entries(NODE_TYPE)) {
|
|
74
|
+
nodeTypes[value] = {
|
|
75
|
+
category: 'base',
|
|
76
|
+
count: nodeCounts[value] || 0,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Namespaced node types
|
|
81
|
+
for (const [_key, value] of Object.entries(NAMESPACED_TYPE)) {
|
|
82
|
+
const namespace = value.split(':')[0];
|
|
83
|
+
nodeTypes[value] = {
|
|
84
|
+
category: 'namespaced',
|
|
85
|
+
namespace,
|
|
86
|
+
count: nodeCounts[value] || 0,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Add any additional types found in the graph but not in definitions
|
|
91
|
+
for (const [type, count] of Object.entries(nodeCounts)) {
|
|
92
|
+
if (!nodeTypes[type]) {
|
|
93
|
+
const namespace = type.includes(':') ? type.split(':')[0] : undefined;
|
|
94
|
+
nodeTypes[type] = {
|
|
95
|
+
category: namespace ? 'namespaced' : 'base',
|
|
96
|
+
namespace,
|
|
97
|
+
count,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Build edge types from definitions + counts
|
|
103
|
+
const edgeTypes: Record<string, EdgeTypeSchema> = {};
|
|
104
|
+
|
|
105
|
+
for (const [_key, value] of Object.entries(EDGE_TYPE)) {
|
|
106
|
+
edgeTypes[value] = {
|
|
107
|
+
count: edgeCounts[value] || 0,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Add any additional edge types found in the graph
|
|
112
|
+
for (const [type, count] of Object.entries(edgeCounts)) {
|
|
113
|
+
if (!edgeTypes[type]) {
|
|
114
|
+
edgeTypes[type] = { count };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Calculate totals
|
|
119
|
+
const totalNodes = Object.values(nodeCounts).reduce((sum, n) => sum + n, 0);
|
|
120
|
+
const totalEdges = Object.values(edgeCounts).reduce((sum, n) => sum + n, 0);
|
|
121
|
+
|
|
122
|
+
// Filter out types with count=0 unless includeAll is true
|
|
123
|
+
const filteredNodeTypes: Record<string, NodeTypeSchema> = {};
|
|
124
|
+
for (const [type, info] of Object.entries(nodeTypes)) {
|
|
125
|
+
if (includeAll || info.count > 0) {
|
|
126
|
+
filteredNodeTypes[type] = info;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const filteredEdgeTypes: Record<string, EdgeTypeSchema> = {};
|
|
131
|
+
for (const [type, info] of Object.entries(edgeTypes)) {
|
|
132
|
+
if (includeAll || info.count > 0) {
|
|
133
|
+
filteredEdgeTypes[type] = info;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Sort for deterministic output
|
|
138
|
+
const sortedNodeTypes = this.sortObject(filteredNodeTypes);
|
|
139
|
+
const sortedEdgeTypes = this.sortObject(filteredEdgeTypes);
|
|
140
|
+
|
|
141
|
+
// Compute checksum from normalized content (based on filtered types)
|
|
142
|
+
const checksumContent = {
|
|
143
|
+
nodeTypes: Object.keys(sortedNodeTypes).sort(),
|
|
144
|
+
edgeTypes: Object.keys(sortedEdgeTypes).sort(),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const checksum = createHash('sha256')
|
|
148
|
+
.update(JSON.stringify(checksumContent))
|
|
149
|
+
.digest('hex');
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
$schema: 'grafema-graph-v1',
|
|
153
|
+
extractedAt: new Date().toISOString(),
|
|
154
|
+
nodeTypes: sortedNodeTypes,
|
|
155
|
+
edgeTypes: sortedEdgeTypes,
|
|
156
|
+
statistics: {
|
|
157
|
+
totalNodes,
|
|
158
|
+
totalEdges,
|
|
159
|
+
nodeTypeCount: Object.keys(sortedNodeTypes).length,
|
|
160
|
+
edgeTypeCount: Object.keys(sortedEdgeTypes).length,
|
|
161
|
+
},
|
|
162
|
+
checksum: `sha256:${checksum}`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Sort object keys alphabetically for deterministic output
|
|
168
|
+
*/
|
|
169
|
+
private sortObject<T>(obj: Record<string, T>): Record<string, T> {
|
|
170
|
+
const sorted: Record<string, T> = {};
|
|
171
|
+
const keys = Object.keys(obj).sort();
|
|
172
|
+
for (const key of keys) {
|
|
173
|
+
sorted[key] = obj[key];
|
|
174
|
+
}
|
|
175
|
+
return sorted;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InterfaceSchemaExtractor - Extracts interface schemas from graph
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const extractor = new InterfaceSchemaExtractor(backend);
|
|
6
|
+
* const schema = await extractor.extract('ConfigSchema');
|
|
7
|
+
*
|
|
8
|
+
* When to use:
|
|
9
|
+
* - Export interface contracts for documentation
|
|
10
|
+
* - Track interface changes via checksum
|
|
11
|
+
* - Generate API documentation from graph
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createHash } from 'crypto';
|
|
15
|
+
import type { RFDBServerBackend } from '../storage/backends/RFDBServerBackend.js';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Types
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
export interface PropertySchema {
|
|
22
|
+
type: string;
|
|
23
|
+
required: boolean;
|
|
24
|
+
readonly: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface InterfaceSchema {
|
|
28
|
+
$schema: 'grafema-interface-v1';
|
|
29
|
+
name: string;
|
|
30
|
+
source: {
|
|
31
|
+
file: string;
|
|
32
|
+
line: number;
|
|
33
|
+
column: number;
|
|
34
|
+
};
|
|
35
|
+
typeParameters?: string[];
|
|
36
|
+
properties: Record<string, PropertySchema>;
|
|
37
|
+
extends: string[];
|
|
38
|
+
checksum: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ExtractOptions {
|
|
42
|
+
/** Specific file path if multiple interfaces have same name */
|
|
43
|
+
file?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface InterfaceNodeRecord {
|
|
47
|
+
id: string;
|
|
48
|
+
type: 'INTERFACE';
|
|
49
|
+
name: string;
|
|
50
|
+
file: string;
|
|
51
|
+
line: number;
|
|
52
|
+
column: number;
|
|
53
|
+
extends: string[];
|
|
54
|
+
properties: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
type?: string;
|
|
57
|
+
optional?: boolean;
|
|
58
|
+
readonly?: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
typeParameters?: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Extractor
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
export class InterfaceSchemaExtractor {
|
|
68
|
+
constructor(private backend: RFDBServerBackend) {}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Extract schema for interface by name
|
|
72
|
+
*
|
|
73
|
+
* @param interfaceName - Name of the interface (e.g., 'ConfigSchema')
|
|
74
|
+
* @param options - Optional filters
|
|
75
|
+
* @returns InterfaceSchema or null if not found
|
|
76
|
+
* @throws Error if multiple interfaces match and no file specified
|
|
77
|
+
*/
|
|
78
|
+
async extract(interfaceName: string, options?: ExtractOptions): Promise<InterfaceSchema | null> {
|
|
79
|
+
const interfaces = await this.findInterfaces(interfaceName);
|
|
80
|
+
|
|
81
|
+
if (interfaces.length === 0) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Filter by file if specified
|
|
86
|
+
let match: InterfaceNodeRecord;
|
|
87
|
+
if (options?.file) {
|
|
88
|
+
const fileFilter = options.file;
|
|
89
|
+
const filtered = interfaces.filter(i => i.file === fileFilter || i.file.endsWith(fileFilter));
|
|
90
|
+
if (filtered.length === 0) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
match = filtered[0];
|
|
94
|
+
} else if (interfaces.length > 1) {
|
|
95
|
+
const locations = interfaces.map(i => ` - ${i.file}:${i.line}`).join('\n');
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Multiple interfaces named "${interfaceName}" found:\n${locations}\n` +
|
|
98
|
+
`Use --file option to specify which one.`
|
|
99
|
+
);
|
|
100
|
+
} else {
|
|
101
|
+
match = interfaces[0];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return this.buildSchema(match);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Find all interfaces with given name
|
|
109
|
+
*/
|
|
110
|
+
async findInterfaces(name: string): Promise<InterfaceNodeRecord[]> {
|
|
111
|
+
const result: InterfaceNodeRecord[] = [];
|
|
112
|
+
|
|
113
|
+
for await (const node of this.backend.queryNodes({ nodeType: 'INTERFACE' })) {
|
|
114
|
+
if (node.name === name) {
|
|
115
|
+
result.push(node as unknown as InterfaceNodeRecord);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Build InterfaceSchema from node record
|
|
124
|
+
*/
|
|
125
|
+
private buildSchema(node: InterfaceNodeRecord): InterfaceSchema {
|
|
126
|
+
// Sort properties alphabetically for deterministic output
|
|
127
|
+
const sortedProperties = [...(node.properties || [])].sort((a, b) =>
|
|
128
|
+
a.name.localeCompare(b.name)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const properties: Record<string, PropertySchema> = {};
|
|
132
|
+
for (const prop of sortedProperties) {
|
|
133
|
+
properties[prop.name] = {
|
|
134
|
+
type: prop.type || 'unknown',
|
|
135
|
+
required: !prop.optional,
|
|
136
|
+
readonly: prop.readonly || false
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Compute checksum from normalized content
|
|
141
|
+
const checksumContent = {
|
|
142
|
+
name: node.name,
|
|
143
|
+
properties: sortedProperties.map(p => ({
|
|
144
|
+
name: p.name,
|
|
145
|
+
type: p.type,
|
|
146
|
+
optional: p.optional,
|
|
147
|
+
readonly: p.readonly
|
|
148
|
+
})),
|
|
149
|
+
extends: [...(node.extends || [])].sort(),
|
|
150
|
+
typeParameters: node.typeParameters
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const checksum = createHash('sha256')
|
|
154
|
+
.update(JSON.stringify(checksumContent))
|
|
155
|
+
.digest('hex');
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
$schema: 'grafema-interface-v1',
|
|
159
|
+
name: node.name,
|
|
160
|
+
source: {
|
|
161
|
+
file: node.file,
|
|
162
|
+
line: node.line,
|
|
163
|
+
column: node.column
|
|
164
|
+
},
|
|
165
|
+
...(node.typeParameters && node.typeParameters.length > 0 && {
|
|
166
|
+
typeParameters: node.typeParameters
|
|
167
|
+
}),
|
|
168
|
+
properties,
|
|
169
|
+
extends: node.extends || [],
|
|
170
|
+
checksum: `sha256:${checksum}`
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { InterfaceSchemaExtractor } from './InterfaceSchemaExtractor.js';
|
|
2
|
+
export type { InterfaceSchema, PropertySchema, ExtractOptions } from './InterfaceSchemaExtractor.js';
|
|
3
|
+
|
|
4
|
+
export { GraphSchemaExtractor } from './GraphSchemaExtractor.js';
|
|
5
|
+
export type { GraphSchema, NodeTypeSchema, EdgeTypeSchema, GraphExtractOptions } from './GraphSchemaExtractor.js';
|