@grafema/types 0.1.0-alpha.1
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/README.md +39 -0
- package/dist/edges.d.ts +77 -0
- package/dist/edges.d.ts.map +1 -0
- package/dist/edges.js +56 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/nodes.d.ts +162 -0
- package/dist/nodes.d.ts.map +1 -0
- package/dist/nodes.js +84 -0
- package/dist/plugins.d.ts +131 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +30 -0
- package/dist/rfdb.d.ts +183 -0
- package/dist/rfdb.d.ts.map +1 -0
- package/dist/rfdb.js +4 -0
- package/package.json +38 -0
- package/src/edges.ts +111 -0
- package/src/index.ts +15 -0
- package/src/nodes.ts +269 -0
- package/src/plugins.ts +187 -0
- package/src/rfdb.ts +279 -0
package/src/nodes.ts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node Types - graph node type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// === BASE NODE TYPES ===
|
|
6
|
+
export const NODE_TYPE = {
|
|
7
|
+
// Core code entities
|
|
8
|
+
FUNCTION: 'FUNCTION',
|
|
9
|
+
CLASS: 'CLASS',
|
|
10
|
+
METHOD: 'METHOD',
|
|
11
|
+
VARIABLE: 'VARIABLE',
|
|
12
|
+
PARAMETER: 'PARAMETER',
|
|
13
|
+
CONSTANT: 'CONSTANT',
|
|
14
|
+
LITERAL: 'LITERAL',
|
|
15
|
+
EXPRESSION: 'EXPRESSION',
|
|
16
|
+
|
|
17
|
+
// Module system
|
|
18
|
+
MODULE: 'MODULE',
|
|
19
|
+
IMPORT: 'IMPORT',
|
|
20
|
+
EXPORT: 'EXPORT',
|
|
21
|
+
|
|
22
|
+
// Call graph
|
|
23
|
+
CALL: 'CALL',
|
|
24
|
+
|
|
25
|
+
// Project structure
|
|
26
|
+
PROJECT: 'PROJECT',
|
|
27
|
+
SERVICE: 'SERVICE',
|
|
28
|
+
FILE: 'FILE',
|
|
29
|
+
SCOPE: 'SCOPE',
|
|
30
|
+
|
|
31
|
+
// External dependencies
|
|
32
|
+
EXTERNAL: 'EXTERNAL',
|
|
33
|
+
EXTERNAL_MODULE: 'EXTERNAL_MODULE',
|
|
34
|
+
|
|
35
|
+
// Generic side effects
|
|
36
|
+
SIDE_EFFECT: 'SIDE_EFFECT',
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
39
|
+
export type BaseNodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];
|
|
40
|
+
|
|
41
|
+
// === NAMESPACED NODE TYPES ===
|
|
42
|
+
export const NAMESPACED_TYPE = {
|
|
43
|
+
// HTTP (generic)
|
|
44
|
+
HTTP_ROUTE: 'http:route',
|
|
45
|
+
HTTP_REQUEST: 'http:request',
|
|
46
|
+
|
|
47
|
+
// Express.js
|
|
48
|
+
EXPRESS_ROUTER: 'express:router',
|
|
49
|
+
EXPRESS_MIDDLEWARE: 'express:middleware',
|
|
50
|
+
EXPRESS_MOUNT: 'express:mount',
|
|
51
|
+
|
|
52
|
+
// Socket.IO
|
|
53
|
+
SOCKETIO_EMIT: 'socketio:emit',
|
|
54
|
+
SOCKETIO_ON: 'socketio:on',
|
|
55
|
+
SOCKETIO_NAMESPACE: 'socketio:namespace',
|
|
56
|
+
|
|
57
|
+
// Database
|
|
58
|
+
DB_QUERY: 'db:query',
|
|
59
|
+
DB_CONNECTION: 'db:connection',
|
|
60
|
+
|
|
61
|
+
// Filesystem
|
|
62
|
+
FS_READ: 'fs:read',
|
|
63
|
+
FS_WRITE: 'fs:write',
|
|
64
|
+
FS_OPERATION: 'fs:operation',
|
|
65
|
+
|
|
66
|
+
// Network
|
|
67
|
+
NET_REQUEST: 'net:request',
|
|
68
|
+
NET_STDIO: 'net:stdio',
|
|
69
|
+
|
|
70
|
+
// Events
|
|
71
|
+
EVENT_LISTENER: 'event:listener',
|
|
72
|
+
EVENT_EMIT: 'event:emit',
|
|
73
|
+
} as const;
|
|
74
|
+
|
|
75
|
+
export type NamespacedNodeType = typeof NAMESPACED_TYPE[keyof typeof NAMESPACED_TYPE];
|
|
76
|
+
|
|
77
|
+
// Combined node type
|
|
78
|
+
export type NodeType = BaseNodeType | NamespacedNodeType | string;
|
|
79
|
+
|
|
80
|
+
// === NODE RECORD ===
|
|
81
|
+
// Base interface for all nodes
|
|
82
|
+
export interface BaseNodeRecord {
|
|
83
|
+
id: string;
|
|
84
|
+
stableId?: string;
|
|
85
|
+
type: NodeType;
|
|
86
|
+
name: string;
|
|
87
|
+
file: string;
|
|
88
|
+
line?: number; // Optional - not always available
|
|
89
|
+
column?: number;
|
|
90
|
+
metadata?: Record<string, unknown>;
|
|
91
|
+
// Allow arbitrary additional properties for flexibility
|
|
92
|
+
[key: string]: unknown;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Function node
|
|
96
|
+
export interface FunctionNodeRecord extends BaseNodeRecord {
|
|
97
|
+
type: 'FUNCTION';
|
|
98
|
+
async: boolean;
|
|
99
|
+
generator: boolean;
|
|
100
|
+
exported: boolean;
|
|
101
|
+
arrowFunction: boolean;
|
|
102
|
+
parentScopeId?: string;
|
|
103
|
+
isClassMethod?: boolean;
|
|
104
|
+
className?: string;
|
|
105
|
+
params?: string[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Class node
|
|
109
|
+
export interface ClassNodeRecord extends BaseNodeRecord {
|
|
110
|
+
type: 'CLASS';
|
|
111
|
+
exported: boolean;
|
|
112
|
+
superClass?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Method node
|
|
116
|
+
export interface MethodNodeRecord extends BaseNodeRecord {
|
|
117
|
+
type: 'METHOD';
|
|
118
|
+
className: string;
|
|
119
|
+
async: boolean;
|
|
120
|
+
static: boolean;
|
|
121
|
+
kind: 'method' | 'get' | 'set' | 'constructor';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Module node
|
|
125
|
+
export interface ModuleNodeRecord extends BaseNodeRecord {
|
|
126
|
+
type: 'MODULE';
|
|
127
|
+
relativePath: string;
|
|
128
|
+
contentHash: string;
|
|
129
|
+
language?: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Import node
|
|
133
|
+
export interface ImportNodeRecord extends BaseNodeRecord {
|
|
134
|
+
type: 'IMPORT';
|
|
135
|
+
source: string;
|
|
136
|
+
specifiers: ImportSpecifier[];
|
|
137
|
+
isDefault?: boolean;
|
|
138
|
+
isNamespace?: boolean;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface ImportSpecifier {
|
|
142
|
+
local: string;
|
|
143
|
+
imported?: string;
|
|
144
|
+
type: 'default' | 'named' | 'namespace';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Export node
|
|
148
|
+
export interface ExportNodeRecord extends BaseNodeRecord {
|
|
149
|
+
type: 'EXPORT';
|
|
150
|
+
exportedName: string;
|
|
151
|
+
localName?: string;
|
|
152
|
+
isDefault?: boolean;
|
|
153
|
+
source?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Variable declaration node
|
|
157
|
+
export interface VariableNodeRecord extends BaseNodeRecord {
|
|
158
|
+
type: 'VARIABLE';
|
|
159
|
+
kind: 'var' | 'let' | 'const';
|
|
160
|
+
exported: boolean;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Call node (unified call site)
|
|
164
|
+
export interface CallNodeRecord extends BaseNodeRecord {
|
|
165
|
+
type: 'CALL';
|
|
166
|
+
callee: string;
|
|
167
|
+
arguments?: number;
|
|
168
|
+
isMethodCall?: boolean;
|
|
169
|
+
objectName?: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Service node (project-level)
|
|
173
|
+
export interface ServiceNodeRecord extends BaseNodeRecord {
|
|
174
|
+
type: 'SERVICE';
|
|
175
|
+
projectPath: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Scope node
|
|
179
|
+
export interface ScopeNodeRecord extends BaseNodeRecord {
|
|
180
|
+
type: 'SCOPE';
|
|
181
|
+
scopeType: 'function' | 'block' | 'class' | 'module' | 'global';
|
|
182
|
+
parentScopeId?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// HTTP Route node
|
|
186
|
+
export interface HttpRouteNodeRecord extends BaseNodeRecord {
|
|
187
|
+
type: 'http:route';
|
|
188
|
+
method: string;
|
|
189
|
+
path: string;
|
|
190
|
+
handler?: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Database query node
|
|
194
|
+
export interface DbQueryNodeRecord extends BaseNodeRecord {
|
|
195
|
+
type: 'db:query';
|
|
196
|
+
query: string;
|
|
197
|
+
operation: 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'UNKNOWN';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Event listener node
|
|
201
|
+
export interface EventListenerNodeRecord extends BaseNodeRecord {
|
|
202
|
+
type: 'event:listener';
|
|
203
|
+
eventName: string;
|
|
204
|
+
objectName: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Guarantee priority levels
|
|
208
|
+
export type GuaranteePriority = 'critical' | 'important' | 'observed' | 'tracked';
|
|
209
|
+
|
|
210
|
+
// Guarantee lifecycle status
|
|
211
|
+
export type GuaranteeStatus = 'discovered' | 'reviewed' | 'active' | 'changing' | 'deprecated';
|
|
212
|
+
|
|
213
|
+
// Guarantee node (contract-based)
|
|
214
|
+
export interface GuaranteeNodeRecord extends BaseNodeRecord {
|
|
215
|
+
type: 'guarantee:queue' | 'guarantee:api' | 'guarantee:permission';
|
|
216
|
+
priority: GuaranteePriority;
|
|
217
|
+
status: GuaranteeStatus;
|
|
218
|
+
owner?: string;
|
|
219
|
+
schema?: Record<string, unknown>;
|
|
220
|
+
condition?: string;
|
|
221
|
+
description?: string;
|
|
222
|
+
createdAt?: number;
|
|
223
|
+
updatedAt?: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Union of all node types
|
|
227
|
+
export type NodeRecord =
|
|
228
|
+
| FunctionNodeRecord
|
|
229
|
+
| ClassNodeRecord
|
|
230
|
+
| MethodNodeRecord
|
|
231
|
+
| ModuleNodeRecord
|
|
232
|
+
| ImportNodeRecord
|
|
233
|
+
| ExportNodeRecord
|
|
234
|
+
| VariableNodeRecord
|
|
235
|
+
| CallNodeRecord
|
|
236
|
+
| ServiceNodeRecord
|
|
237
|
+
| ScopeNodeRecord
|
|
238
|
+
| HttpRouteNodeRecord
|
|
239
|
+
| DbQueryNodeRecord
|
|
240
|
+
| EventListenerNodeRecord
|
|
241
|
+
| GuaranteeNodeRecord
|
|
242
|
+
| BaseNodeRecord; // fallback for custom types
|
|
243
|
+
|
|
244
|
+
// === HELPER FUNCTIONS ===
|
|
245
|
+
export function isNamespacedType(nodeType: string): boolean {
|
|
246
|
+
return nodeType?.includes(':') ?? false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function getNamespace(nodeType: string): string | null {
|
|
250
|
+
if (!nodeType?.includes(':')) return null;
|
|
251
|
+
return nodeType.split(':')[0];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function getBaseName(nodeType: string): string {
|
|
255
|
+
if (!nodeType) return '';
|
|
256
|
+
if (!nodeType.includes(':')) return nodeType;
|
|
257
|
+
return nodeType.split(':').slice(1).join(':');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function isEndpointType(nodeType: string): boolean {
|
|
261
|
+
const ns = getNamespace(nodeType);
|
|
262
|
+
return ns === 'http' || ns === 'express' || ns === 'socketio';
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function isSideEffectType(nodeType: string): boolean {
|
|
266
|
+
if (nodeType === NODE_TYPE.SIDE_EFFECT) return true;
|
|
267
|
+
const ns = getNamespace(nodeType);
|
|
268
|
+
return ns === 'db' || ns === 'fs' || ns === 'net';
|
|
269
|
+
}
|
package/src/plugins.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Types - types for analysis plugins
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { NodeType, NodeRecord } from './nodes.js';
|
|
6
|
+
import type { EdgeType, EdgeRecord } from './edges.js';
|
|
7
|
+
|
|
8
|
+
// === PLUGIN PHASES ===
|
|
9
|
+
export const PLUGIN_PHASE = {
|
|
10
|
+
DISCOVERY: 'DISCOVERY',
|
|
11
|
+
INDEXING: 'INDEXING',
|
|
12
|
+
ANALYSIS: 'ANALYSIS',
|
|
13
|
+
ENRICHMENT: 'ENRICHMENT',
|
|
14
|
+
VALIDATION: 'VALIDATION',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
export type PluginPhase = typeof PLUGIN_PHASE[keyof typeof PLUGIN_PHASE];
|
|
18
|
+
|
|
19
|
+
// === PLUGIN METADATA ===
|
|
20
|
+
export interface PluginMetadata {
|
|
21
|
+
name: string;
|
|
22
|
+
phase: PluginPhase;
|
|
23
|
+
priority?: number;
|
|
24
|
+
creates?: {
|
|
25
|
+
nodes?: NodeType[];
|
|
26
|
+
edges?: EdgeType[];
|
|
27
|
+
};
|
|
28
|
+
dependencies?: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// === PLUGIN CONTEXT ===
|
|
32
|
+
// Manifest varies by phase (UnitManifest, DiscoveryManifest, or full Manifest)
|
|
33
|
+
// Using unknown to allow all manifest types
|
|
34
|
+
export interface PluginContext {
|
|
35
|
+
manifest?: unknown;
|
|
36
|
+
graph: GraphBackend;
|
|
37
|
+
config?: OrchestratorConfig;
|
|
38
|
+
phase?: PluginPhase;
|
|
39
|
+
projectPath?: string; // Available during DISCOVERY phase
|
|
40
|
+
onProgress?: (info: Record<string, unknown>) => void;
|
|
41
|
+
forceAnalysis?: boolean;
|
|
42
|
+
workerCount?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// === PLUGIN RESULT ===
|
|
46
|
+
export interface PluginResult {
|
|
47
|
+
success: boolean;
|
|
48
|
+
created: {
|
|
49
|
+
nodes: number;
|
|
50
|
+
edges: number;
|
|
51
|
+
};
|
|
52
|
+
errors: Error[];
|
|
53
|
+
warnings: string[];
|
|
54
|
+
metadata?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// === MANIFEST ===
|
|
58
|
+
export interface Manifest {
|
|
59
|
+
services: ManifestService[];
|
|
60
|
+
entrypoints: ManifestEntrypoint[];
|
|
61
|
+
projectPath: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ManifestService {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
path: string;
|
|
68
|
+
metadata?: Record<string, unknown>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ManifestEntrypoint {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
file: string;
|
|
75
|
+
type: string;
|
|
76
|
+
trigger?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// === ORCHESTRATOR CONFIG ===
|
|
80
|
+
export interface OrchestratorConfig {
|
|
81
|
+
projectPath: string;
|
|
82
|
+
plugins?: string[];
|
|
83
|
+
phases?: PluginPhase[];
|
|
84
|
+
parallel?: boolean;
|
|
85
|
+
maxWorkers?: number;
|
|
86
|
+
verbose?: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// === GRAPH BACKEND INTERFACE ===
|
|
90
|
+
// Flexible input types for graph operations
|
|
91
|
+
export interface InputNode {
|
|
92
|
+
id: string;
|
|
93
|
+
type?: string;
|
|
94
|
+
nodeType?: string;
|
|
95
|
+
name?: string;
|
|
96
|
+
file?: string;
|
|
97
|
+
line?: number;
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface InputEdge {
|
|
102
|
+
src: string;
|
|
103
|
+
dst: string;
|
|
104
|
+
type: string;
|
|
105
|
+
[key: string]: unknown;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Minimal interface for graph operations
|
|
109
|
+
export interface GraphBackend {
|
|
110
|
+
addNode(node: InputNode): Promise<void> | void;
|
|
111
|
+
addEdge(edge: InputEdge): Promise<void> | void;
|
|
112
|
+
addNodes(nodes: InputNode[]): Promise<void> | void;
|
|
113
|
+
addEdges(edges: InputEdge[]): Promise<void> | void;
|
|
114
|
+
|
|
115
|
+
getNode(id: string): Promise<NodeRecord | null>;
|
|
116
|
+
queryNodes(filter: NodeFilter): AsyncIterable<NodeRecord> | AsyncGenerator<NodeRecord>;
|
|
117
|
+
getAllNodes(filter?: NodeFilter): Promise<NodeRecord[]>;
|
|
118
|
+
|
|
119
|
+
getOutgoingEdges(nodeId: string, edgeTypes?: EdgeType[] | null): Promise<EdgeRecord[]>;
|
|
120
|
+
getIncomingEdges(nodeId: string, edgeTypes?: EdgeType[] | null): Promise<EdgeRecord[]>;
|
|
121
|
+
|
|
122
|
+
nodeCount(): Promise<number>;
|
|
123
|
+
edgeCount(): Promise<number>;
|
|
124
|
+
|
|
125
|
+
// For GUI/export - use with caution on large graphs
|
|
126
|
+
getAllEdges?(): Promise<EdgeRecord[]>;
|
|
127
|
+
|
|
128
|
+
// Extended query methods
|
|
129
|
+
countNodesByType(types?: string[] | null): Promise<Record<string, number>>;
|
|
130
|
+
countEdgesByType(types?: string[] | null): Promise<Record<string, number>>;
|
|
131
|
+
findByType?(type: string): Promise<string[]>;
|
|
132
|
+
findByAttr?(query: Record<string, unknown>): Promise<string[]>;
|
|
133
|
+
runDatalogQuery?(query: string): Promise<unknown[]>;
|
|
134
|
+
checkGuarantee?(query: string): unknown[] | Promise<unknown[]>;
|
|
135
|
+
|
|
136
|
+
// Optional delete methods
|
|
137
|
+
deleteNode?(id: string): Promise<void>;
|
|
138
|
+
deleteEdge?(src: string, dst: string, type: string): Promise<void>;
|
|
139
|
+
|
|
140
|
+
// Optional persistence
|
|
141
|
+
flush?(): Promise<void>;
|
|
142
|
+
close?(): Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface NodeFilter {
|
|
146
|
+
type?: NodeType;
|
|
147
|
+
nodeType?: NodeType; // Alias for type (backward compatibility)
|
|
148
|
+
name?: string;
|
|
149
|
+
file?: string;
|
|
150
|
+
[key: string]: unknown;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// === PLUGIN BASE CLASS TYPE ===
|
|
154
|
+
export interface IPlugin {
|
|
155
|
+
config: Record<string, unknown>;
|
|
156
|
+
metadata: PluginMetadata;
|
|
157
|
+
initialize?(context: PluginContext): Promise<void>;
|
|
158
|
+
execute(context: PluginContext): Promise<PluginResult>;
|
|
159
|
+
cleanup?(): Promise<void>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// === HELPER FUNCTIONS ===
|
|
163
|
+
export function createSuccessResult(
|
|
164
|
+
created: { nodes: number; edges: number } = { nodes: 0, edges: 0 },
|
|
165
|
+
metadata: Record<string, unknown> = {}
|
|
166
|
+
): PluginResult {
|
|
167
|
+
return {
|
|
168
|
+
success: true,
|
|
169
|
+
created,
|
|
170
|
+
errors: [],
|
|
171
|
+
warnings: [],
|
|
172
|
+
metadata,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function createErrorResult(
|
|
177
|
+
error: Error,
|
|
178
|
+
created: { nodes: number; edges: number } = { nodes: 0, edges: 0 }
|
|
179
|
+
): PluginResult {
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
created,
|
|
183
|
+
errors: [error],
|
|
184
|
+
warnings: [],
|
|
185
|
+
metadata: {},
|
|
186
|
+
};
|
|
187
|
+
}
|