@arke-institute/sdk 0.1.0 → 0.1.2

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.
Files changed (53) hide show
  1. package/dist/{index.d.mts → client-dAk3E64p.d.cts} +1 -7
  2. package/dist/client-dAk3E64p.d.ts +183 -0
  3. package/dist/{index.mjs → collections/index.cjs} +34 -5
  4. package/dist/collections/index.cjs.map +1 -0
  5. package/dist/collections/index.d.cts +9 -0
  6. package/dist/collections/index.d.ts +9 -1
  7. package/dist/collections/index.js +5 -32
  8. package/dist/collections/index.js.map +1 -1
  9. package/dist/content/index.cjs +506 -0
  10. package/dist/content/index.cjs.map +1 -0
  11. package/dist/content/index.d.cts +403 -0
  12. package/dist/content/index.d.ts +403 -0
  13. package/dist/content/index.js +473 -0
  14. package/dist/content/index.js.map +1 -0
  15. package/dist/edit/index.cjs +1029 -0
  16. package/dist/edit/index.cjs.map +1 -0
  17. package/dist/edit/index.d.cts +78 -0
  18. package/dist/edit/index.d.ts +78 -0
  19. package/dist/edit/index.js +983 -0
  20. package/dist/edit/index.js.map +1 -0
  21. package/dist/errors-3L7IiHcr.d.cts +480 -0
  22. package/dist/errors-B82BMmRP.d.cts +343 -0
  23. package/dist/errors-B82BMmRP.d.ts +343 -0
  24. package/dist/errors-BTe8GKRQ.d.ts +480 -0
  25. package/dist/graph/index.cjs +433 -0
  26. package/dist/graph/index.cjs.map +1 -0
  27. package/dist/graph/index.d.cts +456 -0
  28. package/dist/graph/index.d.ts +456 -0
  29. package/dist/graph/index.js +402 -0
  30. package/dist/graph/index.js.map +1 -0
  31. package/dist/index.cjs +3761 -0
  32. package/dist/index.cjs.map +1 -0
  33. package/dist/index.d.cts +7 -0
  34. package/dist/index.d.ts +7 -189
  35. package/dist/index.js +3502 -30
  36. package/dist/index.js.map +1 -1
  37. package/dist/query/index.cjs +289 -0
  38. package/dist/query/index.cjs.map +1 -0
  39. package/dist/query/index.d.cts +541 -0
  40. package/dist/query/index.d.ts +541 -0
  41. package/dist/query/index.js +261 -0
  42. package/dist/query/index.js.map +1 -0
  43. package/dist/upload/index.cjs +1634 -0
  44. package/dist/upload/index.cjs.map +1 -0
  45. package/dist/upload/index.d.cts +150 -0
  46. package/dist/upload/index.d.ts +150 -0
  47. package/dist/upload/index.js +1597 -0
  48. package/dist/upload/index.js.map +1 -0
  49. package/package.json +43 -8
  50. package/dist/collections/index.d.mts +0 -1
  51. package/dist/collections/index.mjs +0 -204
  52. package/dist/collections/index.mjs.map +0 -1
  53. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,433 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/graph/index.ts
21
+ var graph_exports = {};
22
+ __export(graph_exports, {
23
+ GraphClient: () => GraphClient,
24
+ GraphEntityNotFoundError: () => GraphEntityNotFoundError,
25
+ GraphError: () => GraphError,
26
+ NetworkError: () => NetworkError,
27
+ NoPathFoundError: () => NoPathFoundError
28
+ });
29
+ module.exports = __toCommonJS(graph_exports);
30
+
31
+ // src/graph/errors.ts
32
+ var GraphError = class extends Error {
33
+ constructor(message, code = "GRAPH_ERROR", details) {
34
+ super(message);
35
+ this.code = code;
36
+ this.details = details;
37
+ this.name = "GraphError";
38
+ }
39
+ };
40
+ var GraphEntityNotFoundError = class extends GraphError {
41
+ constructor(canonicalId) {
42
+ super(`Graph entity not found: ${canonicalId}`, "ENTITY_NOT_FOUND", { canonicalId });
43
+ this.name = "GraphEntityNotFoundError";
44
+ }
45
+ };
46
+ var NoPathFoundError = class extends GraphError {
47
+ constructor(sourceIds, targetIds) {
48
+ super(
49
+ `No path found between sources and targets`,
50
+ "NO_PATH_FOUND",
51
+ { sourceIds, targetIds }
52
+ );
53
+ this.name = "NoPathFoundError";
54
+ }
55
+ };
56
+ var NetworkError = class extends GraphError {
57
+ constructor(message, statusCode) {
58
+ super(message, "NETWORK_ERROR", { statusCode });
59
+ this.statusCode = statusCode;
60
+ this.name = "NetworkError";
61
+ }
62
+ };
63
+
64
+ // src/graph/client.ts
65
+ var GraphClient = class {
66
+ constructor(config) {
67
+ this.baseUrl = config.gatewayUrl.replace(/\/$/, "");
68
+ this.fetchImpl = config.fetchImpl ?? fetch;
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Request helpers
72
+ // ---------------------------------------------------------------------------
73
+ buildUrl(path, query) {
74
+ const url = new URL(`${this.baseUrl}${path}`);
75
+ if (query) {
76
+ Object.entries(query).forEach(([key, value]) => {
77
+ if (value !== void 0 && value !== null) {
78
+ url.searchParams.set(key, String(value));
79
+ }
80
+ });
81
+ }
82
+ return url.toString();
83
+ }
84
+ async request(path, options = {}) {
85
+ const url = this.buildUrl(path, options.query);
86
+ const headers = new Headers({ "Content-Type": "application/json" });
87
+ if (options.headers) {
88
+ Object.entries(options.headers).forEach(([k, v]) => {
89
+ if (v !== void 0) headers.set(k, v);
90
+ });
91
+ }
92
+ let response;
93
+ try {
94
+ response = await this.fetchImpl(url, { ...options, headers });
95
+ } catch (err) {
96
+ throw new NetworkError(
97
+ err instanceof Error ? err.message : "Network request failed"
98
+ );
99
+ }
100
+ if (response.ok) {
101
+ const contentType = response.headers.get("content-type") || "";
102
+ if (contentType.includes("application/json")) {
103
+ return await response.json();
104
+ }
105
+ return await response.text();
106
+ }
107
+ let body;
108
+ const text = await response.text();
109
+ try {
110
+ body = JSON.parse(text);
111
+ } catch {
112
+ body = text;
113
+ }
114
+ if (response.status === 404) {
115
+ throw new GraphError(
116
+ body?.message || "Not found",
117
+ "NOT_FOUND",
118
+ body
119
+ );
120
+ }
121
+ const message = body?.error && typeof body.error === "string" ? body.error : body?.message && typeof body.message === "string" ? body.message : `Request failed with status ${response.status}`;
122
+ throw new GraphError(message, "HTTP_ERROR", {
123
+ status: response.status,
124
+ body
125
+ });
126
+ }
127
+ // ---------------------------------------------------------------------------
128
+ // Entity Operations
129
+ // ---------------------------------------------------------------------------
130
+ /**
131
+ * Get an entity by its canonical ID.
132
+ *
133
+ * @param canonicalId - Entity UUID
134
+ * @returns Entity data
135
+ * @throws GraphEntityNotFoundError if the entity doesn't exist
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const entity = await graph.getEntity('uuid-123');
140
+ * console.log('Entity:', entity.label, entity.type);
141
+ * ```
142
+ */
143
+ async getEntity(canonicalId) {
144
+ const response = await this.request(
145
+ `/graphdb/entity/${encodeURIComponent(canonicalId)}`
146
+ );
147
+ if (!response.found || !response.entity) {
148
+ throw new GraphEntityNotFoundError(canonicalId);
149
+ }
150
+ return response.entity;
151
+ }
152
+ /**
153
+ * Check if an entity exists by its canonical ID.
154
+ *
155
+ * @param canonicalId - Entity UUID
156
+ * @returns True if entity exists
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * if (await graph.entityExists('uuid-123')) {
161
+ * console.log('Entity exists');
162
+ * }
163
+ * ```
164
+ */
165
+ async entityExists(canonicalId) {
166
+ const response = await this.request(
167
+ `/graphdb/entity/exists/${encodeURIComponent(canonicalId)}`
168
+ );
169
+ return response.exists;
170
+ }
171
+ /**
172
+ * Query entities by code with optional type filter.
173
+ *
174
+ * @param code - Entity code to search for
175
+ * @param type - Optional entity type filter
176
+ * @returns Matching entities
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Find by code
181
+ * const entities = await graph.queryByCode('person_john');
182
+ *
183
+ * // With type filter
184
+ * const people = await graph.queryByCode('john', 'person');
185
+ * ```
186
+ */
187
+ async queryByCode(code, type) {
188
+ const response = await this.request(
189
+ "/graphdb/entity/query",
190
+ {
191
+ method: "POST",
192
+ body: JSON.stringify({ code, type })
193
+ }
194
+ );
195
+ if (!response.found || !response.entity) {
196
+ return [];
197
+ }
198
+ return [response.entity];
199
+ }
200
+ /**
201
+ * Look up entities by code across all PIs.
202
+ *
203
+ * @param code - Entity code to search for
204
+ * @param type - Optional entity type filter
205
+ * @returns Matching entities
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const entities = await graph.lookupByCode('alice_austen', 'person');
210
+ * ```
211
+ */
212
+ async lookupByCode(code, type) {
213
+ const response = await this.request(
214
+ "/graphdb/entities/lookup-by-code",
215
+ {
216
+ method: "POST",
217
+ body: JSON.stringify({ code, type })
218
+ }
219
+ );
220
+ return response.entities || [];
221
+ }
222
+ // ---------------------------------------------------------------------------
223
+ // PI-based Operations
224
+ // ---------------------------------------------------------------------------
225
+ /**
226
+ * List entities from a specific PI or multiple PIs.
227
+ *
228
+ * @param pi - Single PI or array of PIs
229
+ * @param options - Filter options
230
+ * @returns Entities from the PI(s)
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * // From single PI
235
+ * const entities = await graph.listEntitiesFromPi('01K75HQQXNTDG7BBP7PS9AWYAN');
236
+ *
237
+ * // With type filter
238
+ * const people = await graph.listEntitiesFromPi('01K75HQQXNTDG7BBP7PS9AWYAN', { type: 'person' });
239
+ *
240
+ * // From multiple PIs
241
+ * const all = await graph.listEntitiesFromPi(['pi-1', 'pi-2']);
242
+ * ```
243
+ */
244
+ async listEntitiesFromPi(pi, options = {}) {
245
+ const pis = Array.isArray(pi) ? pi : [pi];
246
+ const response = await this.request(
247
+ "/graphdb/entities/list",
248
+ {
249
+ method: "POST",
250
+ body: JSON.stringify({
251
+ pis,
252
+ type: options.type
253
+ })
254
+ }
255
+ );
256
+ return response.entities || [];
257
+ }
258
+ /**
259
+ * Get entities with their relationships from a PI.
260
+ *
261
+ * This is an optimized query that returns entities along with all their
262
+ * relationship data in a single request.
263
+ *
264
+ * @param pi - Persistent Identifier
265
+ * @param type - Optional entity type filter
266
+ * @returns Entities with relationships
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * const entities = await graph.getEntitiesWithRelationships('01K75HQQXNTDG7BBP7PS9AWYAN');
271
+ * entities.forEach(e => {
272
+ * console.log(`${e.label} has ${e.relationships.length} relationships`);
273
+ * });
274
+ * ```
275
+ */
276
+ async getEntitiesWithRelationships(pi, type) {
277
+ const response = await this.request(
278
+ "/graphdb/pi/entities-with-relationships",
279
+ {
280
+ method: "POST",
281
+ body: JSON.stringify({ pi, type })
282
+ }
283
+ );
284
+ return response.entities || [];
285
+ }
286
+ /**
287
+ * Get the lineage (ancestors and/or descendants) of a PI.
288
+ *
289
+ * @param pi - Source PI
290
+ * @param direction - 'ancestors', 'descendants', or 'both'
291
+ * @returns Lineage data
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * // Get ancestors
296
+ * const lineage = await graph.getLineage('01K75HQQXNTDG7BBP7PS9AWYAN', 'ancestors');
297
+ *
298
+ * // Get both directions
299
+ * const full = await graph.getLineage('01K75HQQXNTDG7BBP7PS9AWYAN', 'both');
300
+ * ```
301
+ */
302
+ async getLineage(pi, direction = "both", maxHops = 10) {
303
+ return this.request("/graphdb/pi/lineage", {
304
+ method: "POST",
305
+ body: JSON.stringify({ sourcePi: pi, direction, maxHops })
306
+ });
307
+ }
308
+ // ---------------------------------------------------------------------------
309
+ // Relationship Operations
310
+ // ---------------------------------------------------------------------------
311
+ /**
312
+ * Get all relationships for an entity.
313
+ *
314
+ * @param canonicalId - Entity UUID
315
+ * @returns Array of relationships
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * const relationships = await graph.getRelationships('uuid-123');
320
+ * relationships.forEach(r => {
321
+ * console.log(`${r.direction}: ${r.predicate} -> ${r.target_label}`);
322
+ * });
323
+ * ```
324
+ */
325
+ async getRelationships(canonicalId) {
326
+ const response = await this.request(`/graphdb/relationships/${encodeURIComponent(canonicalId)}`);
327
+ if (!response.found || !response.relationships) {
328
+ return [];
329
+ }
330
+ return response.relationships.map((rel) => ({
331
+ direction: rel.direction,
332
+ predicate: rel.predicate,
333
+ target_id: rel.target_id,
334
+ target_code: rel.target_code || "",
335
+ target_label: rel.target_label,
336
+ target_type: rel.target_type,
337
+ properties: rel.properties,
338
+ source_pi: rel.source_pi,
339
+ created_at: rel.created_at
340
+ }));
341
+ }
342
+ // ---------------------------------------------------------------------------
343
+ // Path Finding
344
+ // ---------------------------------------------------------------------------
345
+ /**
346
+ * Find shortest paths between sets of entities.
347
+ *
348
+ * @param sourceIds - Starting entity IDs
349
+ * @param targetIds - Target entity IDs
350
+ * @param options - Path finding options
351
+ * @returns Found paths
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * const paths = await graph.findPaths(
356
+ * ['uuid-alice'],
357
+ * ['uuid-bob'],
358
+ * { max_depth: 4, direction: 'both' }
359
+ * );
360
+ *
361
+ * paths.forEach(path => {
362
+ * console.log(`Path of length ${path.length}:`);
363
+ * path.edges.forEach(e => {
364
+ * console.log(` ${e.subject_label} -[${e.predicate}]-> ${e.object_label}`);
365
+ * });
366
+ * });
367
+ * ```
368
+ */
369
+ async findPaths(sourceIds, targetIds, options = {}) {
370
+ const response = await this.request("/graphdb/paths/between", {
371
+ method: "POST",
372
+ body: JSON.stringify({
373
+ source_ids: sourceIds,
374
+ target_ids: targetIds,
375
+ max_depth: options.max_depth,
376
+ direction: options.direction,
377
+ limit: options.limit
378
+ })
379
+ });
380
+ return response.paths || [];
381
+ }
382
+ /**
383
+ * Find entities of a specific type reachable from starting entities.
384
+ *
385
+ * @param startIds - Starting entity IDs
386
+ * @param targetType - Type of entities to find
387
+ * @param options - Search options
388
+ * @returns Reachable entities of the specified type
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * // Find all people reachable from an event
393
+ * const people = await graph.findReachable(
394
+ * ['uuid-event'],
395
+ * 'person',
396
+ * { max_depth: 3 }
397
+ * );
398
+ * ```
399
+ */
400
+ async findReachable(startIds, targetType, options = {}) {
401
+ const response = await this.request(
402
+ "/graphdb/paths/reachable",
403
+ {
404
+ method: "POST",
405
+ body: JSON.stringify({
406
+ start_ids: startIds,
407
+ target_type: targetType,
408
+ max_depth: options.max_depth,
409
+ direction: options.direction,
410
+ limit: options.limit
411
+ })
412
+ }
413
+ );
414
+ return response.entities || [];
415
+ }
416
+ /**
417
+ * Check the health of the graph service.
418
+ *
419
+ * @returns Health status
420
+ */
421
+ async health() {
422
+ return this.request("/graphdb/health", { method: "GET" });
423
+ }
424
+ };
425
+ // Annotate the CommonJS export names for ESM import in node:
426
+ 0 && (module.exports = {
427
+ GraphClient,
428
+ GraphEntityNotFoundError,
429
+ GraphError,
430
+ NetworkError,
431
+ NoPathFoundError
432
+ });
433
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/graph/index.ts","../../src/graph/errors.ts","../../src/graph/client.ts"],"sourcesContent":["/**\n * Graph package for the Arke SDK\n *\n * Provides read-only access to entity relationships from the GraphDB Gateway service.\n *\n * @example\n * ```typescript\n * import { GraphClient } from '@arke-institute/sdk/graph';\n *\n * const graph = new GraphClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get entity by ID\n * const entity = await graph.getEntity('uuid-123');\n *\n * // Get entities with relationships from a PI\n * const entities = await graph.getEntitiesWithRelationships('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // Find paths between entities\n * const paths = await graph.findPaths(['uuid-1'], ['uuid-2']);\n * ```\n */\n\nexport { GraphClient, type GraphClientConfig } from './client.js';\nexport * from './types.js';\nexport * from './errors.js';\n","/**\n * Graph package error classes for the Arke SDK\n */\n\n/**\n * Base error class for graph operations\n */\nexport class GraphError extends Error {\n constructor(\n message: string,\n public code: string = 'GRAPH_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'GraphError';\n }\n}\n\n/**\n * Thrown when an entity is not found by canonical ID\n */\nexport class GraphEntityNotFoundError extends GraphError {\n constructor(canonicalId: string) {\n super(`Graph entity not found: ${canonicalId}`, 'ENTITY_NOT_FOUND', { canonicalId });\n this.name = 'GraphEntityNotFoundError';\n }\n}\n\n/**\n * Thrown when no paths are found between entities\n */\nexport class NoPathFoundError extends GraphError {\n constructor(sourceIds: string[], targetIds: string[]) {\n super(\n `No path found between sources and targets`,\n 'NO_PATH_FOUND',\n { sourceIds, targetIds }\n );\n this.name = 'NoPathFoundError';\n }\n}\n\n/**\n * Thrown when a network error occurs\n */\nexport class NetworkError extends GraphError {\n constructor(message: string, public statusCode?: number) {\n super(message, 'NETWORK_ERROR', { statusCode });\n this.name = 'NetworkError';\n }\n}\n","import {\n GraphError,\n GraphEntityNotFoundError,\n NetworkError,\n} from './errors.js';\nimport type {\n GraphEntity,\n EntityWithRelationships,\n Relationship,\n Path,\n PathOptions,\n ReachableOptions,\n ListFromPiOptions,\n EntityQueryResponse,\n EntitiesWithRelationshipsResponse,\n PathsResponse,\n LineageResponse,\n} from './types.js';\n\n/**\n * Configuration for GraphClient\n */\nexport interface GraphClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /graphdb/* endpoints for GraphDB Gateway.\n */\n gatewayUrl: string;\n /**\n * Optional custom fetch implementation (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\n/**\n * Client for querying entity relationships from the Arke knowledge graph.\n *\n * All endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const graph = new GraphClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get entity by ID\n * const entity = await graph.getEntity('uuid-123');\n *\n * // Find entities by code\n * const results = await graph.queryByCode('person_john');\n *\n * // Get entities with relationships from a PI\n * const entities = await graph.getEntitiesWithRelationships('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // Find paths between entities\n * const paths = await graph.findPaths(['uuid-1'], ['uuid-2'], { max_depth: 4 });\n * ```\n */\nexport class GraphClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: GraphClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>) {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n return url.toString();\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n query?: Record<string, string | number | boolean | undefined>;\n } = {}\n ): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (options.headers) {\n Object.entries(options.headers).forEach(([k, v]) => {\n if (v !== undefined) headers.set(k, v as string);\n });\n }\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, { ...options, headers });\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (response.ok) {\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n }\n\n let body: unknown;\n const text = await response.text();\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n // Handle 404 specifically\n if (response.status === 404) {\n throw new GraphError(\n (body as JsonBody)?.message as string || 'Not found',\n 'NOT_FOUND',\n body\n );\n }\n\n const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : (body as JsonBody)?.message && typeof (body as JsonBody).message === 'string'\n ? ((body as JsonBody).message as string)\n : `Request failed with status ${response.status}`;\n\n throw new GraphError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Entity Operations\n // ---------------------------------------------------------------------------\n\n /**\n * Get an entity by its canonical ID.\n *\n * @param canonicalId - Entity UUID\n * @returns Entity data\n * @throws GraphEntityNotFoundError if the entity doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await graph.getEntity('uuid-123');\n * console.log('Entity:', entity.label, entity.type);\n * ```\n */\n async getEntity(canonicalId: string): Promise<GraphEntity> {\n const response = await this.request<{ found: boolean; entity?: GraphEntity }>(\n `/graphdb/entity/${encodeURIComponent(canonicalId)}`\n );\n\n if (!response.found || !response.entity) {\n throw new GraphEntityNotFoundError(canonicalId);\n }\n\n return response.entity;\n }\n\n /**\n * Check if an entity exists by its canonical ID.\n *\n * @param canonicalId - Entity UUID\n * @returns True if entity exists\n *\n * @example\n * ```typescript\n * if (await graph.entityExists('uuid-123')) {\n * console.log('Entity exists');\n * }\n * ```\n */\n async entityExists(canonicalId: string): Promise<boolean> {\n const response = await this.request<{ exists: boolean }>(\n `/graphdb/entity/exists/${encodeURIComponent(canonicalId)}`\n );\n return response.exists;\n }\n\n /**\n * Query entities by code with optional type filter.\n *\n * @param code - Entity code to search for\n * @param type - Optional entity type filter\n * @returns Matching entities\n *\n * @example\n * ```typescript\n * // Find by code\n * const entities = await graph.queryByCode('person_john');\n *\n * // With type filter\n * const people = await graph.queryByCode('john', 'person');\n * ```\n */\n async queryByCode(code: string, type?: string): Promise<GraphEntity[]> {\n const response = await this.request<EntityQueryResponse>(\n '/graphdb/entity/query',\n {\n method: 'POST',\n body: JSON.stringify({ code, type }),\n }\n );\n\n if (!response.found || !response.entity) {\n return [];\n }\n\n return [response.entity];\n }\n\n /**\n * Look up entities by code across all PIs.\n *\n * @param code - Entity code to search for\n * @param type - Optional entity type filter\n * @returns Matching entities\n *\n * @example\n * ```typescript\n * const entities = await graph.lookupByCode('alice_austen', 'person');\n * ```\n */\n async lookupByCode(code: string, type?: string): Promise<GraphEntity[]> {\n const response = await this.request<{ entities: GraphEntity[] }>(\n '/graphdb/entities/lookup-by-code',\n {\n method: 'POST',\n body: JSON.stringify({ code, type }),\n }\n );\n return response.entities || [];\n }\n\n // ---------------------------------------------------------------------------\n // PI-based Operations\n // ---------------------------------------------------------------------------\n\n /**\n * List entities from a specific PI or multiple PIs.\n *\n * @param pi - Single PI or array of PIs\n * @param options - Filter options\n * @returns Entities from the PI(s)\n *\n * @example\n * ```typescript\n * // From single PI\n * const entities = await graph.listEntitiesFromPi('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // With type filter\n * const people = await graph.listEntitiesFromPi('01K75HQQXNTDG7BBP7PS9AWYAN', { type: 'person' });\n *\n * // From multiple PIs\n * const all = await graph.listEntitiesFromPi(['pi-1', 'pi-2']);\n * ```\n */\n async listEntitiesFromPi(\n pi: string | string[],\n options: ListFromPiOptions = {}\n ): Promise<GraphEntity[]> {\n const pis = Array.isArray(pi) ? pi : [pi];\n const response = await this.request<{ entities: GraphEntity[] }>(\n '/graphdb/entities/list',\n {\n method: 'POST',\n body: JSON.stringify({\n pis,\n type: options.type,\n }),\n }\n );\n return response.entities || [];\n }\n\n /**\n * Get entities with their relationships from a PI.\n *\n * This is an optimized query that returns entities along with all their\n * relationship data in a single request.\n *\n * @param pi - Persistent Identifier\n * @param type - Optional entity type filter\n * @returns Entities with relationships\n *\n * @example\n * ```typescript\n * const entities = await graph.getEntitiesWithRelationships('01K75HQQXNTDG7BBP7PS9AWYAN');\n * entities.forEach(e => {\n * console.log(`${e.label} has ${e.relationships.length} relationships`);\n * });\n * ```\n */\n async getEntitiesWithRelationships(\n pi: string,\n type?: string\n ): Promise<EntityWithRelationships[]> {\n const response = await this.request<EntitiesWithRelationshipsResponse>(\n '/graphdb/pi/entities-with-relationships',\n {\n method: 'POST',\n body: JSON.stringify({ pi, type }),\n }\n );\n return response.entities || [];\n }\n\n /**\n * Get the lineage (ancestors and/or descendants) of a PI.\n *\n * @param pi - Source PI\n * @param direction - 'ancestors', 'descendants', or 'both'\n * @returns Lineage data\n *\n * @example\n * ```typescript\n * // Get ancestors\n * const lineage = await graph.getLineage('01K75HQQXNTDG7BBP7PS9AWYAN', 'ancestors');\n *\n * // Get both directions\n * const full = await graph.getLineage('01K75HQQXNTDG7BBP7PS9AWYAN', 'both');\n * ```\n */\n async getLineage(\n pi: string,\n direction: 'ancestors' | 'descendants' | 'both' = 'both',\n maxHops: number = 10\n ): Promise<LineageResponse> {\n return this.request<LineageResponse>('/graphdb/pi/lineage', {\n method: 'POST',\n body: JSON.stringify({ sourcePi: pi, direction, maxHops }),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Relationship Operations\n // ---------------------------------------------------------------------------\n\n /**\n * Get all relationships for an entity.\n *\n * @param canonicalId - Entity UUID\n * @returns Array of relationships\n *\n * @example\n * ```typescript\n * const relationships = await graph.getRelationships('uuid-123');\n * relationships.forEach(r => {\n * console.log(`${r.direction}: ${r.predicate} -> ${r.target_label}`);\n * });\n * ```\n */\n async getRelationships(canonicalId: string): Promise<Relationship[]> {\n const response = await this.request<{\n found: boolean;\n canonical_id?: string;\n relationships?: Array<{\n direction: 'outgoing' | 'incoming';\n predicate: string;\n target_id: string;\n target_code?: string;\n target_label: string;\n target_type: string;\n properties?: Record<string, unknown>;\n source_pi?: string;\n created_at?: string;\n }>;\n }>(`/graphdb/relationships/${encodeURIComponent(canonicalId)}`);\n\n if (!response.found || !response.relationships) {\n return [];\n }\n\n return response.relationships.map(rel => ({\n direction: rel.direction,\n predicate: rel.predicate,\n target_id: rel.target_id,\n target_code: rel.target_code || '',\n target_label: rel.target_label,\n target_type: rel.target_type,\n properties: rel.properties,\n source_pi: rel.source_pi,\n created_at: rel.created_at,\n }));\n }\n\n // ---------------------------------------------------------------------------\n // Path Finding\n // ---------------------------------------------------------------------------\n\n /**\n * Find shortest paths between sets of entities.\n *\n * @param sourceIds - Starting entity IDs\n * @param targetIds - Target entity IDs\n * @param options - Path finding options\n * @returns Found paths\n *\n * @example\n * ```typescript\n * const paths = await graph.findPaths(\n * ['uuid-alice'],\n * ['uuid-bob'],\n * { max_depth: 4, direction: 'both' }\n * );\n *\n * paths.forEach(path => {\n * console.log(`Path of length ${path.length}:`);\n * path.edges.forEach(e => {\n * console.log(` ${e.subject_label} -[${e.predicate}]-> ${e.object_label}`);\n * });\n * });\n * ```\n */\n async findPaths(\n sourceIds: string[],\n targetIds: string[],\n options: PathOptions = {}\n ): Promise<Path[]> {\n const response = await this.request<PathsResponse>('/graphdb/paths/between', {\n method: 'POST',\n body: JSON.stringify({\n source_ids: sourceIds,\n target_ids: targetIds,\n max_depth: options.max_depth,\n direction: options.direction,\n limit: options.limit,\n }),\n });\n return response.paths || [];\n }\n\n /**\n * Find entities of a specific type reachable from starting entities.\n *\n * @param startIds - Starting entity IDs\n * @param targetType - Type of entities to find\n * @param options - Search options\n * @returns Reachable entities of the specified type\n *\n * @example\n * ```typescript\n * // Find all people reachable from an event\n * const people = await graph.findReachable(\n * ['uuid-event'],\n * 'person',\n * { max_depth: 3 }\n * );\n * ```\n */\n async findReachable(\n startIds: string[],\n targetType: string,\n options: ReachableOptions = {}\n ): Promise<GraphEntity[]> {\n const response = await this.request<{ entities: GraphEntity[] }>(\n '/graphdb/paths/reachable',\n {\n method: 'POST',\n body: JSON.stringify({\n start_ids: startIds,\n target_type: targetType,\n max_depth: options.max_depth,\n direction: options.direction,\n limit: options.limit,\n }),\n }\n );\n return response.entities || [];\n }\n\n /**\n * Check the health of the graph service.\n *\n * @returns Health status\n */\n async health(): Promise<{ status: string; service: string; version: string }> {\n return this.request('/graphdb/health', { method: 'GET' });\n }\n}\n"],"mappings":"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","names":[]}