@grafema/api 0.2.5-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/README.md +219 -0
- package/dist/context.d.ts +22 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +18 -0
- package/dist/context.js.map +1 -0
- package/dist/dataloaders/index.d.ts +18 -0
- package/dist/dataloaders/index.d.ts.map +1 -0
- package/dist/dataloaders/index.js +17 -0
- package/dist/dataloaders/index.js.map +1 -0
- package/dist/dataloaders/nodeLoader.d.ts +19 -0
- package/dist/dataloaders/nodeLoader.d.ts.map +1 -0
- package/dist/dataloaders/nodeLoader.js +31 -0
- package/dist/dataloaders/nodeLoader.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/pagination.d.ts +50 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +71 -0
- package/dist/pagination.js.map +1 -0
- package/dist/resolvers/edge.d.ts +22 -0
- package/dist/resolvers/edge.d.ts.map +1 -0
- package/dist/resolvers/edge.js +36 -0
- package/dist/resolvers/edge.js.map +1 -0
- package/dist/resolvers/index.d.ts +159 -0
- package/dist/resolvers/index.d.ts.map +1 -0
- package/dist/resolvers/index.js +21 -0
- package/dist/resolvers/index.js.map +1 -0
- package/dist/resolvers/mutation.d.ts +69 -0
- package/dist/resolvers/mutation.d.ts.map +1 -0
- package/dist/resolvers/mutation.js +82 -0
- package/dist/resolvers/mutation.js.map +1 -0
- package/dist/resolvers/node.d.ts +50 -0
- package/dist/resolvers/node.d.ts.map +1 -0
- package/dist/resolvers/node.js +69 -0
- package/dist/resolvers/node.js.map +1 -0
- package/dist/resolvers/query.d.ts +169 -0
- package/dist/resolvers/query.d.ts.map +1 -0
- package/dist/resolvers/query.js +188 -0
- package/dist/resolvers/query.js.map +1 -0
- package/dist/schema/enums.graphql +27 -0
- package/dist/schema/mutations.graphql +53 -0
- package/dist/schema/queries.graphql +213 -0
- package/dist/schema/scalars.graphql +2 -0
- package/dist/schema/subscriptions.graphql +84 -0
- package/dist/schema/types.graphql +440 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +109 -0
- package/dist/server.js.map +1 -0
- package/package.json +51 -0
- package/src/context.ts +33 -0
- package/src/dataloaders/index.ts +24 -0
- package/src/dataloaders/nodeLoader.ts +41 -0
- package/src/index.ts +11 -0
- package/src/pagination.ts +109 -0
- package/src/resolvers/edge.ts +39 -0
- package/src/resolvers/index.ts +24 -0
- package/src/resolvers/mutation.ts +108 -0
- package/src/resolvers/node.ts +118 -0
- package/src/resolvers/query.ts +307 -0
- package/src/schema/enums.graphql +27 -0
- package/src/schema/mutations.graphql +53 -0
- package/src/schema/queries.graphql +213 -0
- package/src/schema/scalars.graphql +2 -0
- package/src/schema/subscriptions.graphql +84 -0
- package/src/schema/types.graphql +440 -0
- package/src/server.ts +140 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
type Subscription {
|
|
2
|
+
"""
|
|
3
|
+
Stream nodes matching filter as they're found.
|
|
4
|
+
Useful for UI visualization of large datasets.
|
|
5
|
+
"""
|
|
6
|
+
nodesStream(
|
|
7
|
+
"""Filter criteria"""
|
|
8
|
+
filter: NodeFilter
|
|
9
|
+
|
|
10
|
+
"""Batch size for streaming (default: 100)"""
|
|
11
|
+
batchSize: Int
|
|
12
|
+
): NodeBatch!
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
Stream BFS traversal results level by level.
|
|
16
|
+
Each batch contains all nodes at one depth level.
|
|
17
|
+
"""
|
|
18
|
+
bfsStream(
|
|
19
|
+
"""Starting node IDs"""
|
|
20
|
+
startIds: [ID!]!
|
|
21
|
+
|
|
22
|
+
"""Maximum traversal depth"""
|
|
23
|
+
maxDepth: Int!
|
|
24
|
+
|
|
25
|
+
"""Edge types to traverse"""
|
|
26
|
+
edgeTypes: [String!]!
|
|
27
|
+
): TraversalBatch!
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
Stream analysis progress events.
|
|
31
|
+
"""
|
|
32
|
+
analysisProgress(
|
|
33
|
+
"""Optional: filter to specific service"""
|
|
34
|
+
service: String
|
|
35
|
+
): AnalysisEvent!
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
Batch of nodes for streaming responses.
|
|
40
|
+
"""
|
|
41
|
+
type NodeBatch {
|
|
42
|
+
"""Nodes in this batch"""
|
|
43
|
+
nodes: [Node!]!
|
|
44
|
+
|
|
45
|
+
"""Progress from 0.0 to 1.0"""
|
|
46
|
+
progress: Float!
|
|
47
|
+
|
|
48
|
+
"""Whether streaming is complete"""
|
|
49
|
+
done: Boolean!
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
Batch of traversal results at a specific depth.
|
|
54
|
+
"""
|
|
55
|
+
type TraversalBatch {
|
|
56
|
+
"""Current depth level"""
|
|
57
|
+
depth: Int!
|
|
58
|
+
|
|
59
|
+
"""Node IDs at this depth"""
|
|
60
|
+
nodeIds: [ID!]!
|
|
61
|
+
|
|
62
|
+
"""Whether traversal is complete"""
|
|
63
|
+
done: Boolean!
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
Analysis progress event.
|
|
68
|
+
"""
|
|
69
|
+
type AnalysisEvent {
|
|
70
|
+
"""Current phase name"""
|
|
71
|
+
phase: String!
|
|
72
|
+
|
|
73
|
+
"""Human-readable message"""
|
|
74
|
+
message: String!
|
|
75
|
+
|
|
76
|
+
"""Progress from 0.0 to 1.0"""
|
|
77
|
+
progress: Float!
|
|
78
|
+
|
|
79
|
+
"""Number of services completed"""
|
|
80
|
+
servicesCompleted: Int!
|
|
81
|
+
|
|
82
|
+
"""Total number of services"""
|
|
83
|
+
servicesTotal: Int!
|
|
84
|
+
}
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A node in the code graph representing a code entity.
|
|
3
|
+
"""
|
|
4
|
+
type Node {
|
|
5
|
+
"""Unique identifier for the node (e.g., "fn:src/api.ts:login:42")"""
|
|
6
|
+
id: ID!
|
|
7
|
+
|
|
8
|
+
"""Node type (e.g., FUNCTION, CLASS, MODULE, http:route)"""
|
|
9
|
+
type: String!
|
|
10
|
+
|
|
11
|
+
"""Human-readable name"""
|
|
12
|
+
name: String!
|
|
13
|
+
|
|
14
|
+
"""Source file path (relative to project root)"""
|
|
15
|
+
file: String
|
|
16
|
+
|
|
17
|
+
"""Line number in source file (1-indexed)"""
|
|
18
|
+
line: Int
|
|
19
|
+
|
|
20
|
+
"""Column number in source file (1-indexed)"""
|
|
21
|
+
column: Int
|
|
22
|
+
|
|
23
|
+
"""Whether this entity is exported from its module"""
|
|
24
|
+
exported: Boolean
|
|
25
|
+
|
|
26
|
+
"""Arbitrary metadata as JSON object"""
|
|
27
|
+
metadata: JSON
|
|
28
|
+
|
|
29
|
+
# Relationship fields
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
Outgoing edges from this node.
|
|
33
|
+
Optional filter by edge types.
|
|
34
|
+
"""
|
|
35
|
+
outgoingEdges(
|
|
36
|
+
types: [String!]
|
|
37
|
+
first: Int
|
|
38
|
+
after: String
|
|
39
|
+
): GraphEdgeConnection!
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
Incoming edges to this node.
|
|
43
|
+
Optional filter by edge types.
|
|
44
|
+
"""
|
|
45
|
+
incomingEdges(
|
|
46
|
+
types: [String!]
|
|
47
|
+
first: Int
|
|
48
|
+
after: String
|
|
49
|
+
): GraphEdgeConnection!
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
Child nodes (via CONTAINS edges).
|
|
53
|
+
For hierarchical traversal: SERVICE -> MODULE -> FUNCTION -> SCOPE
|
|
54
|
+
"""
|
|
55
|
+
children(first: Int, after: String): NodeConnection!
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
Parent node (via incoming CONTAINS edge).
|
|
59
|
+
Returns null for root nodes (SERVICE, PROJECT).
|
|
60
|
+
"""
|
|
61
|
+
parent: Node
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
An edge in the code graph representing a relationship between nodes.
|
|
66
|
+
"""
|
|
67
|
+
type Edge {
|
|
68
|
+
"""Source node"""
|
|
69
|
+
src: Node!
|
|
70
|
+
|
|
71
|
+
"""Destination node"""
|
|
72
|
+
dst: Node!
|
|
73
|
+
|
|
74
|
+
"""Edge type (e.g., CALLS, CONTAINS, IMPORTS)"""
|
|
75
|
+
type: String!
|
|
76
|
+
|
|
77
|
+
"""Ordering index for ordered relationships"""
|
|
78
|
+
index: Int
|
|
79
|
+
|
|
80
|
+
"""Arbitrary metadata as JSON object"""
|
|
81
|
+
metadata: JSON
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# ============================================================================
|
|
85
|
+
# Pagination Types (Relay Connection Spec)
|
|
86
|
+
# ============================================================================
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
Connection type for paginated node results (Relay spec).
|
|
90
|
+
"""
|
|
91
|
+
type NodeConnection {
|
|
92
|
+
"""Edges containing nodes and cursors"""
|
|
93
|
+
edges: [NodeEdge!]!
|
|
94
|
+
|
|
95
|
+
"""Pagination info"""
|
|
96
|
+
pageInfo: PageInfo!
|
|
97
|
+
|
|
98
|
+
"""Total count of matching nodes"""
|
|
99
|
+
totalCount: Int!
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
Edge wrapper for cursor-based pagination.
|
|
104
|
+
"""
|
|
105
|
+
type NodeEdge {
|
|
106
|
+
"""The node"""
|
|
107
|
+
node: Node!
|
|
108
|
+
|
|
109
|
+
"""Cursor for this node (use with after/before args)"""
|
|
110
|
+
cursor: String!
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
Connection type for paginated graph edge results.
|
|
115
|
+
"""
|
|
116
|
+
type GraphEdgeConnection {
|
|
117
|
+
"""Edges containing graph edges and cursors"""
|
|
118
|
+
edges: [GraphEdgeEdge!]!
|
|
119
|
+
|
|
120
|
+
"""Pagination info"""
|
|
121
|
+
pageInfo: PageInfo!
|
|
122
|
+
|
|
123
|
+
"""Total count of matching edges"""
|
|
124
|
+
totalCount: Int!
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
"""
|
|
128
|
+
Edge wrapper for graph edges.
|
|
129
|
+
"""
|
|
130
|
+
type GraphEdgeEdge {
|
|
131
|
+
"""The graph edge"""
|
|
132
|
+
node: Edge!
|
|
133
|
+
|
|
134
|
+
"""Cursor for this edge"""
|
|
135
|
+
cursor: String!
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
"""
|
|
139
|
+
Pagination info (Relay spec).
|
|
140
|
+
"""
|
|
141
|
+
type PageInfo {
|
|
142
|
+
"""Has more items after endCursor"""
|
|
143
|
+
hasNextPage: Boolean!
|
|
144
|
+
|
|
145
|
+
"""Has more items before startCursor"""
|
|
146
|
+
hasPreviousPage: Boolean!
|
|
147
|
+
|
|
148
|
+
"""Cursor of first item in current page"""
|
|
149
|
+
startCursor: String
|
|
150
|
+
|
|
151
|
+
"""Cursor of last item in current page"""
|
|
152
|
+
endCursor: String
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# ============================================================================
|
|
156
|
+
# Query Result Types
|
|
157
|
+
# ============================================================================
|
|
158
|
+
|
|
159
|
+
"""
|
|
160
|
+
Result of a Datalog query.
|
|
161
|
+
"""
|
|
162
|
+
type DatalogResult {
|
|
163
|
+
"""Whether the query executed successfully"""
|
|
164
|
+
success: Boolean!
|
|
165
|
+
|
|
166
|
+
"""Number of results"""
|
|
167
|
+
count: Int!
|
|
168
|
+
|
|
169
|
+
"""Query results with variable bindings"""
|
|
170
|
+
results: [DatalogBinding!]!
|
|
171
|
+
|
|
172
|
+
"""Error message if query failed"""
|
|
173
|
+
error: String
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
Variable bindings from a Datalog query result.
|
|
178
|
+
"""
|
|
179
|
+
type DatalogBinding {
|
|
180
|
+
"""Map of variable names to values"""
|
|
181
|
+
bindings: JSON!
|
|
182
|
+
|
|
183
|
+
"""Enriched node data if X binding is a node ID"""
|
|
184
|
+
node: Node
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
"""
|
|
188
|
+
Function details including call graph information.
|
|
189
|
+
"""
|
|
190
|
+
type FunctionDetails {
|
|
191
|
+
"""The function node"""
|
|
192
|
+
function: Node!
|
|
193
|
+
|
|
194
|
+
"""Functions/methods this function calls"""
|
|
195
|
+
calls: [CallInfo!]!
|
|
196
|
+
|
|
197
|
+
"""Functions that call this function"""
|
|
198
|
+
calledBy: [CallerInfo!]!
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
"""
|
|
202
|
+
Information about a call made by a function.
|
|
203
|
+
"""
|
|
204
|
+
type CallInfo {
|
|
205
|
+
"""The CALL node"""
|
|
206
|
+
call: Node!
|
|
207
|
+
|
|
208
|
+
"""Name of the called function/method"""
|
|
209
|
+
name: String!
|
|
210
|
+
|
|
211
|
+
"""Object name for method calls (e.g., "console" in console.log)"""
|
|
212
|
+
object: String
|
|
213
|
+
|
|
214
|
+
"""Whether the target was resolved"""
|
|
215
|
+
resolved: Boolean!
|
|
216
|
+
|
|
217
|
+
"""Target function if resolved"""
|
|
218
|
+
target: Node
|
|
219
|
+
|
|
220
|
+
"""Call type: CALL or METHOD_CALL"""
|
|
221
|
+
callType: String!
|
|
222
|
+
|
|
223
|
+
"""Depth in transitive call chain (0 = direct)"""
|
|
224
|
+
depth: Int!
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
"""
|
|
228
|
+
Information about a function that calls another function.
|
|
229
|
+
"""
|
|
230
|
+
type CallerInfo {
|
|
231
|
+
"""The calling function"""
|
|
232
|
+
function: Node!
|
|
233
|
+
|
|
234
|
+
"""File containing the caller"""
|
|
235
|
+
file: String!
|
|
236
|
+
|
|
237
|
+
"""Line number of the call"""
|
|
238
|
+
line: Int!
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
"""
|
|
242
|
+
Guard (conditional scope) protecting a node.
|
|
243
|
+
"""
|
|
244
|
+
type GuardInfo {
|
|
245
|
+
"""The SCOPE node ID"""
|
|
246
|
+
scopeId: ID!
|
|
247
|
+
|
|
248
|
+
"""Type of conditional (if_statement, else_statement, etc.)"""
|
|
249
|
+
scopeType: String!
|
|
250
|
+
|
|
251
|
+
"""Raw condition text"""
|
|
252
|
+
condition: String
|
|
253
|
+
|
|
254
|
+
"""Parsed constraints as JSON"""
|
|
255
|
+
constraints: JSON
|
|
256
|
+
|
|
257
|
+
"""Source file"""
|
|
258
|
+
file: String!
|
|
259
|
+
|
|
260
|
+
"""Line number"""
|
|
261
|
+
line: Int!
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
"""
|
|
265
|
+
Guarantee definition.
|
|
266
|
+
"""
|
|
267
|
+
type Guarantee {
|
|
268
|
+
"""Unique identifier"""
|
|
269
|
+
id: ID!
|
|
270
|
+
|
|
271
|
+
"""Human-readable name"""
|
|
272
|
+
name: String!
|
|
273
|
+
|
|
274
|
+
"""Datalog rule or contract condition"""
|
|
275
|
+
rule: String
|
|
276
|
+
|
|
277
|
+
"""Severity level"""
|
|
278
|
+
severity: String
|
|
279
|
+
|
|
280
|
+
"""Guarantee type for contract-based"""
|
|
281
|
+
type: String
|
|
282
|
+
|
|
283
|
+
"""Priority level"""
|
|
284
|
+
priority: String
|
|
285
|
+
|
|
286
|
+
"""Lifecycle status"""
|
|
287
|
+
status: String
|
|
288
|
+
|
|
289
|
+
"""Description"""
|
|
290
|
+
description: String
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
"""
|
|
294
|
+
Result of checking guarantees.
|
|
295
|
+
"""
|
|
296
|
+
type GuaranteeCheckResult {
|
|
297
|
+
"""Total guarantees checked"""
|
|
298
|
+
total: Int!
|
|
299
|
+
|
|
300
|
+
"""Number that passed"""
|
|
301
|
+
passed: Int!
|
|
302
|
+
|
|
303
|
+
"""Number that failed"""
|
|
304
|
+
failed: Int!
|
|
305
|
+
|
|
306
|
+
"""Individual results"""
|
|
307
|
+
results: [GuaranteeResult!]!
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
"""
|
|
311
|
+
Result of checking a single guarantee.
|
|
312
|
+
"""
|
|
313
|
+
type GuaranteeResult {
|
|
314
|
+
"""Guarantee ID"""
|
|
315
|
+
guaranteeId: ID!
|
|
316
|
+
|
|
317
|
+
"""Whether the guarantee passed"""
|
|
318
|
+
passed: Boolean!
|
|
319
|
+
|
|
320
|
+
"""Number of violations (for Datalog guarantees)"""
|
|
321
|
+
violationCount: Int
|
|
322
|
+
|
|
323
|
+
"""Sample violations"""
|
|
324
|
+
violations: [Violation!]
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
"""
|
|
328
|
+
A violation of a guarantee.
|
|
329
|
+
"""
|
|
330
|
+
type Violation {
|
|
331
|
+
"""Node that violated the guarantee"""
|
|
332
|
+
node: Node
|
|
333
|
+
|
|
334
|
+
"""File containing the violation"""
|
|
335
|
+
file: String
|
|
336
|
+
|
|
337
|
+
"""Line number"""
|
|
338
|
+
line: Int
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
"""
|
|
342
|
+
Graph statistics.
|
|
343
|
+
"""
|
|
344
|
+
type GraphStats {
|
|
345
|
+
"""Total node count"""
|
|
346
|
+
nodeCount: Int!
|
|
347
|
+
|
|
348
|
+
"""Total edge count"""
|
|
349
|
+
edgeCount: Int!
|
|
350
|
+
|
|
351
|
+
"""Nodes grouped by type"""
|
|
352
|
+
nodesByType: JSON!
|
|
353
|
+
|
|
354
|
+
"""Edges grouped by type"""
|
|
355
|
+
edgesByType: JSON!
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
"""
|
|
359
|
+
Analysis status.
|
|
360
|
+
"""
|
|
361
|
+
type AnalysisStatus {
|
|
362
|
+
"""Whether analysis is currently running"""
|
|
363
|
+
running: Boolean!
|
|
364
|
+
|
|
365
|
+
"""Current phase"""
|
|
366
|
+
phase: String
|
|
367
|
+
|
|
368
|
+
"""Status message"""
|
|
369
|
+
message: String
|
|
370
|
+
|
|
371
|
+
"""Number of services discovered"""
|
|
372
|
+
servicesDiscovered: Int!
|
|
373
|
+
|
|
374
|
+
"""Number of services analyzed"""
|
|
375
|
+
servicesAnalyzed: Int!
|
|
376
|
+
|
|
377
|
+
"""Error message if analysis failed"""
|
|
378
|
+
error: String
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
"""
|
|
382
|
+
Result of analyze mutation.
|
|
383
|
+
"""
|
|
384
|
+
type AnalysisResult {
|
|
385
|
+
"""Whether analysis succeeded"""
|
|
386
|
+
success: Boolean!
|
|
387
|
+
|
|
388
|
+
"""Status after analysis"""
|
|
389
|
+
status: AnalysisStatus!
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
# ============================================================================
|
|
393
|
+
# Input Types
|
|
394
|
+
# ============================================================================
|
|
395
|
+
|
|
396
|
+
"""
|
|
397
|
+
Filter for node queries.
|
|
398
|
+
"""
|
|
399
|
+
input NodeFilter {
|
|
400
|
+
"""Filter by node type"""
|
|
401
|
+
type: String
|
|
402
|
+
|
|
403
|
+
"""Filter by name (exact match)"""
|
|
404
|
+
name: String
|
|
405
|
+
|
|
406
|
+
"""Filter by file path (partial match)"""
|
|
407
|
+
file: String
|
|
408
|
+
|
|
409
|
+
"""Filter by exported status"""
|
|
410
|
+
exported: Boolean
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
"""
|
|
414
|
+
Input for creating a guarantee.
|
|
415
|
+
"""
|
|
416
|
+
input CreateGuaranteeInput {
|
|
417
|
+
"""Unique name"""
|
|
418
|
+
name: String!
|
|
419
|
+
|
|
420
|
+
"""Datalog rule defining violation/1"""
|
|
421
|
+
rule: String
|
|
422
|
+
|
|
423
|
+
"""Severity: error, warning, info"""
|
|
424
|
+
severity: Severity
|
|
425
|
+
|
|
426
|
+
"""Type: guarantee:queue, guarantee:api, guarantee:permission"""
|
|
427
|
+
type: String
|
|
428
|
+
|
|
429
|
+
"""Priority: critical, important, observed, tracked"""
|
|
430
|
+
priority: Priority
|
|
431
|
+
|
|
432
|
+
"""Description"""
|
|
433
|
+
description: String
|
|
434
|
+
|
|
435
|
+
"""Owner (team or person)"""
|
|
436
|
+
owner: String
|
|
437
|
+
|
|
438
|
+
"""Node IDs this guarantee governs"""
|
|
439
|
+
governs: [String!]
|
|
440
|
+
}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL API Server using graphql-yoga
|
|
3
|
+
*
|
|
4
|
+
* Provides a GraphQL endpoint on top of Grafema's graph database.
|
|
5
|
+
* Supports cursor-based pagination and query complexity limiting.
|
|
6
|
+
*/
|
|
7
|
+
import { createServer } from 'node:http';
|
|
8
|
+
import type { RFDBServerBackend } from '@grafema/core';
|
|
9
|
+
export interface GraphQLServerOptions {
|
|
10
|
+
/** Graph backend (RFDBServerBackend) */
|
|
11
|
+
backend: RFDBServerBackend;
|
|
12
|
+
/** Port to listen on (default: 4000) */
|
|
13
|
+
port?: number;
|
|
14
|
+
/** Hostname to bind to (default: localhost) */
|
|
15
|
+
hostname?: string;
|
|
16
|
+
/** Maximum query depth (default: 10) */
|
|
17
|
+
maxDepth?: number;
|
|
18
|
+
/** Maximum query complexity cost (default: 1000) */
|
|
19
|
+
maxComplexity?: number;
|
|
20
|
+
/** Request timeout in ms (default: 30000) */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function createGraphQLServer(options: GraphQLServerOptions): import("graphql-yoga").YogaServerInstance<{}, import("./context.js").GraphQLContext>;
|
|
24
|
+
/**
|
|
25
|
+
* Start a standalone GraphQL server.
|
|
26
|
+
*
|
|
27
|
+
* @param options Server options
|
|
28
|
+
* @returns HTTP server instance
|
|
29
|
+
*/
|
|
30
|
+
export declare function startServer(options: GraphQLServerOptions): ReturnType<typeof createServer>;
|
|
31
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAwB,MAAM,WAAW,CAAC;AAQ/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AA6BvD,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,wFAuDhE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,oBAAoB,GAC5B,UAAU,CAAC,OAAO,YAAY,CAAC,CAejC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL API Server using graphql-yoga
|
|
3
|
+
*
|
|
4
|
+
* Provides a GraphQL endpoint on top of Grafema's graph database.
|
|
5
|
+
* Supports cursor-based pagination and query complexity limiting.
|
|
6
|
+
*/
|
|
7
|
+
import { createServer } from 'node:http';
|
|
8
|
+
import { createYoga, createSchema } from 'graphql-yoga';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { join, dirname } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { resolvers } from './resolvers/index.js';
|
|
13
|
+
import { createContext } from './context.js';
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
// Load schema files
|
|
16
|
+
function loadTypeDefs() {
|
|
17
|
+
const schemaDir = join(__dirname, 'schema');
|
|
18
|
+
const files = [
|
|
19
|
+
'scalars.graphql',
|
|
20
|
+
'enums.graphql',
|
|
21
|
+
'types.graphql',
|
|
22
|
+
'queries.graphql',
|
|
23
|
+
'mutations.graphql',
|
|
24
|
+
'subscriptions.graphql',
|
|
25
|
+
];
|
|
26
|
+
return files
|
|
27
|
+
.map((file) => {
|
|
28
|
+
try {
|
|
29
|
+
return readFileSync(join(schemaDir, file), 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// File might not exist in dist yet, try src
|
|
33
|
+
const srcPath = join(__dirname, '..', 'src', 'schema', file);
|
|
34
|
+
return readFileSync(srcPath, 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
.join('\n');
|
|
38
|
+
}
|
|
39
|
+
export function createGraphQLServer(options) {
|
|
40
|
+
const { backend } = options;
|
|
41
|
+
const typeDefs = loadTypeDefs();
|
|
42
|
+
const schema = createSchema({
|
|
43
|
+
typeDefs,
|
|
44
|
+
resolvers,
|
|
45
|
+
});
|
|
46
|
+
const yoga = createYoga({
|
|
47
|
+
schema,
|
|
48
|
+
context: ({ request }) => {
|
|
49
|
+
// Create a minimal request object for context
|
|
50
|
+
const req = {
|
|
51
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
52
|
+
};
|
|
53
|
+
return createContext(backend, req);
|
|
54
|
+
},
|
|
55
|
+
graphiql: {
|
|
56
|
+
title: 'Grafema GraphQL API',
|
|
57
|
+
defaultQuery: `# Welcome to Grafema GraphQL API
|
|
58
|
+
#
|
|
59
|
+
# Example queries:
|
|
60
|
+
#
|
|
61
|
+
# Get all functions:
|
|
62
|
+
# query { nodes(filter: {type: "FUNCTION"}, first: 10) {
|
|
63
|
+
# edges { node { id name file line } }
|
|
64
|
+
# pageInfo { hasNextPage endCursor }
|
|
65
|
+
# totalCount
|
|
66
|
+
# }}
|
|
67
|
+
#
|
|
68
|
+
# Find a specific node:
|
|
69
|
+
# query { node(id: "your-node-id") { id name type file } }
|
|
70
|
+
#
|
|
71
|
+
# Execute Datalog:
|
|
72
|
+
# query { datalog(query: "violation(X) :- node(X, \\"FUNCTION\\").") {
|
|
73
|
+
# count
|
|
74
|
+
# results { node { name } }
|
|
75
|
+
# }}
|
|
76
|
+
|
|
77
|
+
query Stats {
|
|
78
|
+
stats {
|
|
79
|
+
nodeCount
|
|
80
|
+
edgeCount
|
|
81
|
+
nodesByType
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
`,
|
|
85
|
+
},
|
|
86
|
+
// Subscriptions enabled for streaming
|
|
87
|
+
// (graphql-yoga uses SSE by default)
|
|
88
|
+
});
|
|
89
|
+
return yoga;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Start a standalone GraphQL server.
|
|
93
|
+
*
|
|
94
|
+
* @param options Server options
|
|
95
|
+
* @returns HTTP server instance
|
|
96
|
+
*/
|
|
97
|
+
export function startServer(options) {
|
|
98
|
+
const { port = 4000, hostname = 'localhost' } = options;
|
|
99
|
+
const yoga = createGraphQLServer(options);
|
|
100
|
+
const server = createServer((req, res) => {
|
|
101
|
+
yoga(req, res);
|
|
102
|
+
});
|
|
103
|
+
server.listen(port, hostname, () => {
|
|
104
|
+
console.log(`Grafema GraphQL API running at http://${hostname}:${port}/graphql`);
|
|
105
|
+
console.log(`GraphiQL IDE available at http://${hostname}:${port}/graphql`);
|
|
106
|
+
});
|
|
107
|
+
return server;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|