@arke-institute/sdk 0.1.2 → 0.1.3
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/dist/content/index.cjs +95 -10
- package/dist/content/index.cjs.map +1 -1
- package/dist/content/index.d.cts +128 -15
- package/dist/content/index.d.ts +128 -15
- package/dist/content/index.js +95 -10
- package/dist/content/index.js.map +1 -1
- package/dist/edit/index.cjs +590 -116
- package/dist/edit/index.cjs.map +1 -1
- package/dist/edit/index.d.cts +2 -2
- package/dist/edit/index.d.ts +2 -2
- package/dist/edit/index.js +580 -116
- package/dist/edit/index.js.map +1 -1
- package/dist/errors-CT7yzKkU.d.cts +874 -0
- package/dist/errors-CT7yzKkU.d.ts +874 -0
- package/dist/graph/index.cjs +52 -58
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +84 -55
- package/dist/graph/index.d.ts +84 -55
- package/dist/graph/index.js +52 -58
- package/dist/graph/index.js.map +1 -1
- package/dist/index.cjs +796 -196
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +796 -196
- package/dist/index.js.map +1 -1
- package/dist/query/index.cjs +67 -0
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +96 -1
- package/dist/query/index.d.ts +96 -1
- package/dist/query/index.js +67 -0
- package/dist/query/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/errors-B82BMmRP.d.cts +0 -343
- package/dist/errors-B82BMmRP.d.ts +0 -343
package/dist/content/index.cjs
CHANGED
|
@@ -40,8 +40,8 @@ var ContentError = class extends Error {
|
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
var EntityNotFoundError = class extends ContentError {
|
|
43
|
-
constructor(
|
|
44
|
-
super(`Entity not found: ${
|
|
43
|
+
constructor(id) {
|
|
44
|
+
super(`Entity not found: ${id}`, "ENTITY_NOT_FOUND", { id });
|
|
45
45
|
this.name = "EntityNotFoundError";
|
|
46
46
|
}
|
|
47
47
|
};
|
|
@@ -52,21 +52,21 @@ var ContentNotFoundError = class extends ContentError {
|
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
54
|
var ComponentNotFoundError = class extends ContentError {
|
|
55
|
-
constructor(
|
|
55
|
+
constructor(id, componentName) {
|
|
56
56
|
super(
|
|
57
|
-
`Component '${componentName}' not found on entity ${
|
|
57
|
+
`Component '${componentName}' not found on entity ${id}`,
|
|
58
58
|
"COMPONENT_NOT_FOUND",
|
|
59
|
-
{
|
|
59
|
+
{ id, componentName }
|
|
60
60
|
);
|
|
61
61
|
this.name = "ComponentNotFoundError";
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
var VersionNotFoundError = class extends ContentError {
|
|
65
|
-
constructor(
|
|
65
|
+
constructor(id, selector) {
|
|
66
66
|
super(
|
|
67
|
-
`Version not found: ${selector} for entity ${
|
|
67
|
+
`Version not found: ${selector} for entity ${id}`,
|
|
68
68
|
"VERSION_NOT_FOUND",
|
|
69
|
-
{
|
|
69
|
+
{ id, selector }
|
|
70
70
|
);
|
|
71
71
|
this.name = "VersionNotFoundError";
|
|
72
72
|
}
|
|
@@ -446,6 +446,45 @@ var ContentClient = class {
|
|
|
446
446
|
}
|
|
447
447
|
return response.body;
|
|
448
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Download a DAG node (JSON) by CID.
|
|
451
|
+
*
|
|
452
|
+
* Use this to fetch JSON components like properties and relationships.
|
|
453
|
+
*
|
|
454
|
+
* @param cid - Content Identifier of the DAG node
|
|
455
|
+
* @returns Parsed JSON object
|
|
456
|
+
* @throws ContentNotFoundError if the content doesn't exist
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```typescript
|
|
460
|
+
* const relationships = await content.getDag<RelationshipsComponent>(
|
|
461
|
+
* entity.components.relationships
|
|
462
|
+
* );
|
|
463
|
+
* console.log('Relationships:', relationships.relationships);
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
async getDag(cid) {
|
|
467
|
+
const url = this.buildUrl(`/api/dag/${encodeURIComponent(cid)}`);
|
|
468
|
+
let response;
|
|
469
|
+
try {
|
|
470
|
+
response = await this.fetchImpl(url);
|
|
471
|
+
} catch (err) {
|
|
472
|
+
throw new NetworkError(
|
|
473
|
+
err instanceof Error ? err.message : "Network request failed"
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
if (!response.ok) {
|
|
477
|
+
if (response.status === 404) {
|
|
478
|
+
throw new ContentNotFoundError(cid);
|
|
479
|
+
}
|
|
480
|
+
throw new ContentError(
|
|
481
|
+
`Failed to fetch DAG node: ${response.status}`,
|
|
482
|
+
"DAG_ERROR",
|
|
483
|
+
{ status: response.status }
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
return await response.json();
|
|
487
|
+
}
|
|
449
488
|
// ---------------------------------------------------------------------------
|
|
450
489
|
// Component Helpers
|
|
451
490
|
// ---------------------------------------------------------------------------
|
|
@@ -466,7 +505,7 @@ var ContentClient = class {
|
|
|
466
505
|
async getComponent(entity, componentName) {
|
|
467
506
|
const cid = entity.components[componentName];
|
|
468
507
|
if (!cid) {
|
|
469
|
-
throw new ComponentNotFoundError(entity.
|
|
508
|
+
throw new ComponentNotFoundError(entity.id, componentName);
|
|
470
509
|
}
|
|
471
510
|
return this.download(cid);
|
|
472
511
|
}
|
|
@@ -488,10 +527,56 @@ var ContentClient = class {
|
|
|
488
527
|
getComponentUrl(entity, componentName) {
|
|
489
528
|
const cid = entity.components[componentName];
|
|
490
529
|
if (!cid) {
|
|
491
|
-
throw new ComponentNotFoundError(entity.
|
|
530
|
+
throw new ComponentNotFoundError(entity.id, componentName);
|
|
492
531
|
}
|
|
493
532
|
return this.getUrl(cid);
|
|
494
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* Get the properties component for an entity.
|
|
536
|
+
*
|
|
537
|
+
* @param entity - Entity containing the properties component
|
|
538
|
+
* @returns Properties object, or null if no properties component exists
|
|
539
|
+
*
|
|
540
|
+
* @example
|
|
541
|
+
* ```typescript
|
|
542
|
+
* const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
|
|
543
|
+
* const props = await content.getProperties(entity);
|
|
544
|
+
* if (props) {
|
|
545
|
+
* console.log('Title:', props.title);
|
|
546
|
+
* }
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
async getProperties(entity) {
|
|
550
|
+
const cid = entity.components.properties;
|
|
551
|
+
if (!cid) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
return this.getDag(cid);
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Get the relationships component for an entity.
|
|
558
|
+
*
|
|
559
|
+
* @param entity - Entity containing the relationships component
|
|
560
|
+
* @returns Relationships component, or null if no relationships exist
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* ```typescript
|
|
564
|
+
* const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
|
|
565
|
+
* const rels = await content.getRelationships(entity);
|
|
566
|
+
* if (rels) {
|
|
567
|
+
* rels.relationships.forEach(r => {
|
|
568
|
+
* console.log(`${r.predicate} -> ${r.target_label}`);
|
|
569
|
+
* });
|
|
570
|
+
* }
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
async getRelationships(entity) {
|
|
574
|
+
const cid = entity.components.relationships;
|
|
575
|
+
if (!cid) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
return this.getDag(cid);
|
|
579
|
+
}
|
|
495
580
|
};
|
|
496
581
|
// Annotate the CommonJS export names for ESM import in node:
|
|
497
582
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/content/index.ts","../../src/content/errors.ts","../../src/content/client.ts"],"sourcesContent":["/**\n * Content package for the Arke SDK\n *\n * Provides read-only access to entities and content from the IPFS Wrapper service.\n *\n * @example\n * ```typescript\n * import { ContentClient } from '@arke-institute/sdk/content';\n *\n * const content = new ContentClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get an entity\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // List entities\n * const { entities, next_cursor } = await content.list({ limit: 20 });\n *\n * // Download content\n * const blob = await content.download(entity.components.source);\n * ```\n */\n\nexport { ContentClient, type ContentClientConfig } from './client.js';\nexport * from './types.js';\nexport * from './errors.js';\n","/**\n * Content package error classes for the Arke SDK\n */\n\n/**\n * Base error class for content operations\n */\nexport class ContentError extends Error {\n constructor(\n message: string,\n public code: string = 'CONTENT_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'ContentError';\n }\n}\n\n/**\n * Thrown when an entity is not found by PI\n */\nexport class EntityNotFoundError extends ContentError {\n constructor(pi: string) {\n super(`Entity not found: ${pi}`, 'ENTITY_NOT_FOUND', { pi });\n this.name = 'EntityNotFoundError';\n }\n}\n\n/**\n * Thrown when content is not found by CID\n */\nexport class ContentNotFoundError extends ContentError {\n constructor(cid: string) {\n super(`Content not found: ${cid}`, 'CONTENT_NOT_FOUND', { cid });\n this.name = 'ContentNotFoundError';\n }\n}\n\n/**\n * Thrown when a component is not found on an entity\n */\nexport class ComponentNotFoundError extends ContentError {\n constructor(pi: string, componentName: string) {\n super(\n `Component '${componentName}' not found on entity ${pi}`,\n 'COMPONENT_NOT_FOUND',\n { pi, componentName }\n );\n this.name = 'ComponentNotFoundError';\n }\n}\n\n/**\n * Thrown when a version is not found\n */\nexport class VersionNotFoundError extends ContentError {\n constructor(pi: string, selector: string) {\n super(\n `Version not found: ${selector} for entity ${pi}`,\n 'VERSION_NOT_FOUND',\n { pi, selector }\n );\n this.name = 'VersionNotFoundError';\n }\n}\n\n/**\n * Thrown when a network error occurs\n */\nexport class NetworkError extends ContentError {\n constructor(message: string, public statusCode?: number) {\n super(message, 'NETWORK_ERROR', { statusCode });\n this.name = 'NetworkError';\n }\n}\n","import {\n ContentError,\n EntityNotFoundError,\n ContentNotFoundError,\n ComponentNotFoundError,\n NetworkError,\n} from './errors.js';\nimport type {\n Entity,\n EntityVersion,\n ListOptions,\n ListResponse,\n VersionsOptions,\n VersionsResponse,\n ResolveResponse,\n} from './types.js';\n\n/**\n * Configuration for ContentClient\n */\nexport interface ContentClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /api/* endpoints for IPFS Wrapper.\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 accessing entities and content from the Arke archive.\n *\n * All endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const content = new ContentClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get an entity\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // Download content by CID\n * const blob = await content.download('bafybeihkoviema7g3gxyt6la7vd5ho32jywf7b4c4z3qtwcabpjqxwsumu');\n *\n * // Get component content\n * const pinax = await content.getComponent(entity, 'pinax');\n * ```\n */\nexport class ContentClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: ContentClientConfig) {\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 const errorCode = (body as JsonBody)?.error;\n if (errorCode === 'NOT_FOUND' || errorCode === 'ENTITY_NOT_FOUND') {\n throw new ContentError(\n (body as JsonBody)?.message as string || 'Not found',\n 'NOT_FOUND',\n body\n );\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 ContentError(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 Persistent Identifier (PI).\n *\n * @param pi - Persistent Identifier (ULID or test PI with II prefix)\n * @returns Full entity manifest\n * @throws EntityNotFoundError if the entity doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Version:', entity.ver);\n * console.log('Components:', Object.keys(entity.components));\n * ```\n */\n async get(pi: string): Promise<Entity> {\n try {\n return await this.request<Entity>(`/api/entities/${encodeURIComponent(pi)}`);\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * List entities with pagination.\n *\n * @param options - Pagination and metadata options\n * @returns Paginated list of entity summaries\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await content.list({ limit: 20, include_metadata: true });\n *\n * // Get next page\n * if (page1.next_cursor) {\n * const page2 = await content.list({ cursor: page1.next_cursor });\n * }\n * ```\n */\n async list(options: ListOptions = {}): Promise<ListResponse> {\n return this.request<ListResponse>('/api/entities', {\n query: {\n limit: options.limit,\n cursor: options.cursor,\n include_metadata: options.include_metadata,\n },\n });\n }\n\n /**\n * Get version history for an entity.\n *\n * @param pi - Persistent Identifier\n * @param options - Pagination options\n * @returns Version history (newest first)\n *\n * @example\n * ```typescript\n * const history = await content.versions('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Total versions:', history.items.length);\n * history.items.forEach(v => {\n * console.log(`v${v.ver}: ${v.ts} - ${v.note || 'no note'}`);\n * });\n * ```\n */\n async versions(pi: string, options: VersionsOptions = {}): Promise<VersionsResponse> {\n try {\n return await this.request<VersionsResponse>(\n `/api/entities/${encodeURIComponent(pi)}/versions`,\n {\n query: {\n limit: options.limit,\n cursor: options.cursor,\n },\n }\n );\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Get a specific version of an entity.\n *\n * @param pi - Persistent Identifier\n * @param selector - Version selector: 'ver:N' for version number or 'cid:...' for CID\n * @returns Entity manifest for the specified version\n *\n * @example\n * ```typescript\n * // Get version 2\n * const v2 = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'ver:2');\n *\n * // Get by CID\n * const vByCid = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'cid:bafybeih...');\n * ```\n */\n async getVersion(pi: string, selector: string): Promise<Entity> {\n try {\n return await this.request<Entity>(\n `/api/entities/${encodeURIComponent(pi)}/versions/${encodeURIComponent(selector)}`\n );\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Resolve a PI to its tip CID (fast lookup without fetching manifest).\n *\n * @param pi - Persistent Identifier\n * @returns PI and tip CID\n *\n * @example\n * ```typescript\n * const { tip } = await content.resolve('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Latest manifest CID:', tip);\n * ```\n */\n async resolve(pi: string): Promise<ResolveResponse> {\n try {\n return await this.request<ResolveResponse>(`/api/resolve/${encodeURIComponent(pi)}`);\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Get the list of child PIs for an entity (fast, returns only PIs).\n *\n * @param pi - Persistent Identifier of parent entity\n * @returns Array of child PIs\n *\n * @example\n * ```typescript\n * const childPis = await content.children('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Children:', childPis);\n * ```\n */\n async children(pi: string): Promise<string[]> {\n const entity = await this.get(pi);\n return entity.children_pi || [];\n }\n\n /**\n * Get all child entities for a parent (fetches full entity for each child).\n *\n * @param pi - Persistent Identifier of parent entity\n * @returns Array of child entities\n *\n * @example\n * ```typescript\n * const childEntities = await content.childrenEntities('01K75HQQXNTDG7BBP7PS9AWYAN');\n * childEntities.forEach(child => {\n * console.log(`${child.pi}: v${child.ver}`);\n * });\n * ```\n */\n async childrenEntities(pi: string): Promise<Entity[]> {\n const childPis = await this.children(pi);\n if (childPis.length === 0) {\n return [];\n }\n\n // Fetch all children in parallel\n const results = await Promise.allSettled(\n childPis.map(childPi => this.get(childPi))\n );\n\n // Return only successful fetches\n return results\n .filter((r): r is PromiseFulfilledResult<Entity> => r.status === 'fulfilled')\n .map(r => r.value);\n }\n\n /**\n * Get the Arke origin block (root of the archive tree).\n *\n * @returns Arke origin entity\n *\n * @example\n * ```typescript\n * const origin = await content.arke();\n * console.log('Arke origin:', origin.pi);\n * ```\n */\n async arke(): Promise<Entity> {\n return this.request<Entity>('/api/arke');\n }\n\n // ---------------------------------------------------------------------------\n // Content Download\n // ---------------------------------------------------------------------------\n\n /**\n * Download content by CID.\n *\n * Returns Blob in browser environments, Buffer in Node.js.\n *\n * @param cid - Content Identifier\n * @returns Content as Blob (browser) or Buffer (Node)\n * @throws ContentNotFoundError if the content doesn't exist\n *\n * @example\n * ```typescript\n * const content = await client.download('bafybeih...');\n *\n * // In browser\n * const url = URL.createObjectURL(content as Blob);\n *\n * // In Node.js\n * fs.writeFileSync('output.bin', content as Buffer);\n * ```\n */\n async download(cid: string): Promise<Blob | Buffer> {\n const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url);\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new ContentNotFoundError(cid);\n }\n throw new ContentError(\n `Failed to download content: ${response.status}`,\n 'DOWNLOAD_ERROR',\n { status: response.status }\n );\n }\n\n // Platform-aware response handling\n if (typeof window !== 'undefined') {\n // Browser environment\n return response.blob();\n } else {\n // Node.js environment\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n }\n\n /**\n * Get a direct URL for content by CID.\n *\n * This is useful for embedding in img tags or for direct downloads.\n *\n * @param cid - Content Identifier\n * @returns URL string\n *\n * @example\n * ```typescript\n * const url = content.getUrl('bafybeih...');\n * // Use in img tag: <img src={url} />\n * ```\n */\n getUrl(cid: string): string {\n return `${this.baseUrl}/api/cat/${encodeURIComponent(cid)}`;\n }\n\n /**\n * Stream content by CID.\n *\n * @param cid - Content Identifier\n * @returns ReadableStream of the content\n * @throws ContentNotFoundError if the content doesn't exist\n *\n * @example\n * ```typescript\n * const stream = await content.stream('bafybeih...');\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * // Process chunk\n * }\n * ```\n */\n async stream(cid: string): Promise<ReadableStream<Uint8Array>> {\n const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url);\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new ContentNotFoundError(cid);\n }\n throw new ContentError(\n `Failed to stream content: ${response.status}`,\n 'STREAM_ERROR',\n { status: response.status }\n );\n }\n\n if (!response.body) {\n throw new ContentError('Response body is not available', 'STREAM_ERROR');\n }\n\n return response.body;\n }\n\n // ---------------------------------------------------------------------------\n // Component Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Download a component from an entity.\n *\n * @param entity - Entity containing the component\n * @param componentName - Name of the component (e.g., 'pinax', 'description', 'source')\n * @returns Component content as Blob (browser) or Buffer (Node)\n * @throws ComponentNotFoundError if the component doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const pinax = await content.getComponent(entity, 'pinax');\n * ```\n */\n async getComponent(entity: Entity, componentName: string): Promise<Blob | Buffer> {\n const cid = entity.components[componentName];\n if (!cid) {\n throw new ComponentNotFoundError(entity.pi, componentName);\n }\n return this.download(cid);\n }\n\n /**\n * Get the URL for a component from an entity.\n *\n * @param entity - Entity containing the component\n * @param componentName - Name of the component\n * @returns URL string\n * @throws ComponentNotFoundError if the component doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const imageUrl = content.getComponentUrl(entity, 'source');\n * // Use in img tag: <img src={imageUrl} />\n * ```\n */\n getComponentUrl(entity: Entity, componentName: string): string {\n const cid = entity.components[componentName];\n if (!cid) {\n throw new ComponentNotFoundError(entity.pi, componentName);\n }\n return this.getUrl(cid);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/content/index.ts","../../src/content/errors.ts","../../src/content/client.ts"],"sourcesContent":["/**\n * Content package for the Arke SDK\n *\n * Provides read-only access to entities and content from the IPFS Wrapper service.\n *\n * @example\n * ```typescript\n * import { ContentClient } from '@arke-institute/sdk/content';\n *\n * const content = new ContentClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get an entity\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // List entities\n * const { entities, next_cursor } = await content.list({ limit: 20 });\n *\n * // Download content\n * const blob = await content.download(entity.components.source);\n * ```\n */\n\nexport { ContentClient, type ContentClientConfig } from './client.js';\nexport * from './types.js';\nexport * from './errors.js';\n","/**\n * Content package error classes for the Arke SDK\n */\n\n/**\n * Base error class for content operations\n */\nexport class ContentError extends Error {\n constructor(\n message: string,\n public code: string = 'CONTENT_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'ContentError';\n }\n}\n\n/**\n * Thrown when an entity is not found by ID\n */\nexport class EntityNotFoundError extends ContentError {\n constructor(id: string) {\n super(`Entity not found: ${id}`, 'ENTITY_NOT_FOUND', { id });\n this.name = 'EntityNotFoundError';\n }\n}\n\n/**\n * Thrown when content is not found by CID\n */\nexport class ContentNotFoundError extends ContentError {\n constructor(cid: string) {\n super(`Content not found: ${cid}`, 'CONTENT_NOT_FOUND', { cid });\n this.name = 'ContentNotFoundError';\n }\n}\n\n/**\n * Thrown when a component is not found on an entity\n */\nexport class ComponentNotFoundError extends ContentError {\n constructor(id: string, componentName: string) {\n super(\n `Component '${componentName}' not found on entity ${id}`,\n 'COMPONENT_NOT_FOUND',\n { id, componentName }\n );\n this.name = 'ComponentNotFoundError';\n }\n}\n\n/**\n * Thrown when a version is not found\n */\nexport class VersionNotFoundError extends ContentError {\n constructor(id: string, selector: string) {\n super(\n `Version not found: ${selector} for entity ${id}`,\n 'VERSION_NOT_FOUND',\n { id, selector }\n );\n this.name = 'VersionNotFoundError';\n }\n}\n\n/**\n * Thrown when a network error occurs\n */\nexport class NetworkError extends ContentError {\n constructor(message: string, public statusCode?: number) {\n super(message, 'NETWORK_ERROR', { statusCode });\n this.name = 'NetworkError';\n }\n}\n","import {\n ContentError,\n EntityNotFoundError,\n ContentNotFoundError,\n ComponentNotFoundError,\n NetworkError,\n} from './errors.js';\nimport type {\n Entity,\n EntityVersion,\n ListOptions,\n ListResponse,\n VersionsOptions,\n VersionsResponse,\n ResolveResponse,\n RelationshipsComponent,\n PropertiesComponent,\n} from './types.js';\n\n/**\n * Configuration for ContentClient\n */\nexport interface ContentClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /api/* endpoints for IPFS Wrapper.\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 accessing entities and content from the Arke archive.\n *\n * All endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const content = new ContentClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Get an entity\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n *\n * // Download content by CID\n * const blob = await content.download('bafybeihkoviema7g3gxyt6la7vd5ho32jywf7b4c4z3qtwcabpjqxwsumu');\n *\n * // Get component content\n * const pinax = await content.getComponent(entity, 'pinax');\n * ```\n */\nexport class ContentClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: ContentClientConfig) {\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 const errorCode = (body as JsonBody)?.error;\n if (errorCode === 'NOT_FOUND' || errorCode === 'ENTITY_NOT_FOUND') {\n throw new ContentError(\n (body as JsonBody)?.message as string || 'Not found',\n 'NOT_FOUND',\n body\n );\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 ContentError(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 Persistent Identifier (PI).\n *\n * @param pi - Persistent Identifier (ULID or test PI with II prefix)\n * @returns Full entity manifest\n * @throws EntityNotFoundError if the entity doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Version:', entity.ver);\n * console.log('Components:', Object.keys(entity.components));\n * ```\n */\n async get(pi: string): Promise<Entity> {\n try {\n return await this.request<Entity>(`/api/entities/${encodeURIComponent(pi)}`);\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * List entities with pagination.\n *\n * @param options - Pagination and metadata options\n * @returns Paginated list of entity summaries\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await content.list({ limit: 20, include_metadata: true });\n *\n * // Get next page\n * if (page1.next_cursor) {\n * const page2 = await content.list({ cursor: page1.next_cursor });\n * }\n * ```\n */\n async list(options: ListOptions = {}): Promise<ListResponse> {\n return this.request<ListResponse>('/api/entities', {\n query: {\n limit: options.limit,\n cursor: options.cursor,\n include_metadata: options.include_metadata,\n },\n });\n }\n\n /**\n * Get version history for an entity.\n *\n * @param pi - Persistent Identifier\n * @param options - Pagination options\n * @returns Version history (newest first)\n *\n * @example\n * ```typescript\n * const history = await content.versions('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Total versions:', history.items.length);\n * history.items.forEach(v => {\n * console.log(`v${v.ver}: ${v.ts} - ${v.note || 'no note'}`);\n * });\n * ```\n */\n async versions(pi: string, options: VersionsOptions = {}): Promise<VersionsResponse> {\n try {\n return await this.request<VersionsResponse>(\n `/api/entities/${encodeURIComponent(pi)}/versions`,\n {\n query: {\n limit: options.limit,\n cursor: options.cursor,\n },\n }\n );\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Get a specific version of an entity.\n *\n * @param pi - Persistent Identifier\n * @param selector - Version selector: 'ver:N' for version number or 'cid:...' for CID\n * @returns Entity manifest for the specified version\n *\n * @example\n * ```typescript\n * // Get version 2\n * const v2 = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'ver:2');\n *\n * // Get by CID\n * const vByCid = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'cid:bafybeih...');\n * ```\n */\n async getVersion(pi: string, selector: string): Promise<Entity> {\n try {\n return await this.request<Entity>(\n `/api/entities/${encodeURIComponent(pi)}/versions/${encodeURIComponent(selector)}`\n );\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Resolve a PI to its tip CID (fast lookup without fetching manifest).\n *\n * @param pi - Persistent Identifier\n * @returns PI and tip CID\n *\n * @example\n * ```typescript\n * const { tip } = await content.resolve('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Latest manifest CID:', tip);\n * ```\n */\n async resolve(pi: string): Promise<ResolveResponse> {\n try {\n return await this.request<ResolveResponse>(`/api/resolve/${encodeURIComponent(pi)}`);\n } catch (err) {\n if (err instanceof ContentError && err.code === 'NOT_FOUND') {\n throw new EntityNotFoundError(pi);\n }\n throw err;\n }\n }\n\n /**\n * Get the list of child PIs for an entity (fast, returns only PIs).\n *\n * @param pi - Persistent Identifier of parent entity\n * @returns Array of child PIs\n *\n * @example\n * ```typescript\n * const childPis = await content.children('01K75HQQXNTDG7BBP7PS9AWYAN');\n * console.log('Children:', childPis);\n * ```\n */\n async children(pi: string): Promise<string[]> {\n const entity = await this.get(pi);\n return entity.children_pi || [];\n }\n\n /**\n * Get all child entities for a parent (fetches full entity for each child).\n *\n * @param pi - Persistent Identifier of parent entity\n * @returns Array of child entities\n *\n * @example\n * ```typescript\n * const childEntities = await content.childrenEntities('01K75HQQXNTDG7BBP7PS9AWYAN');\n * childEntities.forEach(child => {\n * console.log(`${child.pi}: v${child.ver}`);\n * });\n * ```\n */\n async childrenEntities(pi: string): Promise<Entity[]> {\n const childPis = await this.children(pi);\n if (childPis.length === 0) {\n return [];\n }\n\n // Fetch all children in parallel\n const results = await Promise.allSettled(\n childPis.map(childPi => this.get(childPi))\n );\n\n // Return only successful fetches\n return results\n .filter((r): r is PromiseFulfilledResult<Entity> => r.status === 'fulfilled')\n .map(r => r.value);\n }\n\n /**\n * Get the Arke origin block (root of the archive tree).\n *\n * @returns Arke origin entity\n *\n * @example\n * ```typescript\n * const origin = await content.arke();\n * console.log('Arke origin:', origin.pi);\n * ```\n */\n async arke(): Promise<Entity> {\n return this.request<Entity>('/api/arke');\n }\n\n // ---------------------------------------------------------------------------\n // Content Download\n // ---------------------------------------------------------------------------\n\n /**\n * Download content by CID.\n *\n * Returns Blob in browser environments, Buffer in Node.js.\n *\n * @param cid - Content Identifier\n * @returns Content as Blob (browser) or Buffer (Node)\n * @throws ContentNotFoundError if the content doesn't exist\n *\n * @example\n * ```typescript\n * const content = await client.download('bafybeih...');\n *\n * // In browser\n * const url = URL.createObjectURL(content as Blob);\n *\n * // In Node.js\n * fs.writeFileSync('output.bin', content as Buffer);\n * ```\n */\n async download(cid: string): Promise<Blob | Buffer> {\n const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url);\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new ContentNotFoundError(cid);\n }\n throw new ContentError(\n `Failed to download content: ${response.status}`,\n 'DOWNLOAD_ERROR',\n { status: response.status }\n );\n }\n\n // Platform-aware response handling\n if (typeof window !== 'undefined') {\n // Browser environment\n return response.blob();\n } else {\n // Node.js environment\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n }\n\n /**\n * Get a direct URL for content by CID.\n *\n * This is useful for embedding in img tags or for direct downloads.\n *\n * @param cid - Content Identifier\n * @returns URL string\n *\n * @example\n * ```typescript\n * const url = content.getUrl('bafybeih...');\n * // Use in img tag: <img src={url} />\n * ```\n */\n getUrl(cid: string): string {\n return `${this.baseUrl}/api/cat/${encodeURIComponent(cid)}`;\n }\n\n /**\n * Stream content by CID.\n *\n * @param cid - Content Identifier\n * @returns ReadableStream of the content\n * @throws ContentNotFoundError if the content doesn't exist\n *\n * @example\n * ```typescript\n * const stream = await content.stream('bafybeih...');\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * // Process chunk\n * }\n * ```\n */\n async stream(cid: string): Promise<ReadableStream<Uint8Array>> {\n const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url);\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new ContentNotFoundError(cid);\n }\n throw new ContentError(\n `Failed to stream content: ${response.status}`,\n 'STREAM_ERROR',\n { status: response.status }\n );\n }\n\n if (!response.body) {\n throw new ContentError('Response body is not available', 'STREAM_ERROR');\n }\n\n return response.body;\n }\n\n /**\n * Download a DAG node (JSON) by CID.\n *\n * Use this to fetch JSON components like properties and relationships.\n *\n * @param cid - Content Identifier of the DAG node\n * @returns Parsed JSON object\n * @throws ContentNotFoundError if the content doesn't exist\n *\n * @example\n * ```typescript\n * const relationships = await content.getDag<RelationshipsComponent>(\n * entity.components.relationships\n * );\n * console.log('Relationships:', relationships.relationships);\n * ```\n */\n async getDag<T = unknown>(cid: string): Promise<T> {\n const url = this.buildUrl(`/api/dag/${encodeURIComponent(cid)}`);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url);\n } catch (err) {\n throw new NetworkError(\n err instanceof Error ? err.message : 'Network request failed'\n );\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new ContentNotFoundError(cid);\n }\n throw new ContentError(\n `Failed to fetch DAG node: ${response.status}`,\n 'DAG_ERROR',\n { status: response.status }\n );\n }\n\n return (await response.json()) as T;\n }\n\n // ---------------------------------------------------------------------------\n // Component Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Download a component from an entity.\n *\n * @param entity - Entity containing the component\n * @param componentName - Name of the component (e.g., 'pinax', 'description', 'source')\n * @returns Component content as Blob (browser) or Buffer (Node)\n * @throws ComponentNotFoundError if the component doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const pinax = await content.getComponent(entity, 'pinax');\n * ```\n */\n async getComponent(entity: Entity, componentName: string): Promise<Blob | Buffer> {\n const cid = entity.components[componentName];\n if (!cid) {\n throw new ComponentNotFoundError(entity.id, componentName);\n }\n return this.download(cid);\n }\n\n /**\n * Get the URL for a component from an entity.\n *\n * @param entity - Entity containing the component\n * @param componentName - Name of the component\n * @returns URL string\n * @throws ComponentNotFoundError if the component doesn't exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const imageUrl = content.getComponentUrl(entity, 'source');\n * // Use in img tag: <img src={imageUrl} />\n * ```\n */\n getComponentUrl(entity: Entity, componentName: string): string {\n const cid = entity.components[componentName];\n if (!cid) {\n throw new ComponentNotFoundError(entity.id, componentName);\n }\n return this.getUrl(cid);\n }\n\n /**\n * Get the properties component for an entity.\n *\n * @param entity - Entity containing the properties component\n * @returns Properties object, or null if no properties component exists\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const props = await content.getProperties(entity);\n * if (props) {\n * console.log('Title:', props.title);\n * }\n * ```\n */\n async getProperties(entity: Entity): Promise<PropertiesComponent | null> {\n const cid = entity.components.properties;\n if (!cid) {\n return null;\n }\n return this.getDag<PropertiesComponent>(cid);\n }\n\n /**\n * Get the relationships component for an entity.\n *\n * @param entity - Entity containing the relationships component\n * @returns Relationships component, or null if no relationships exist\n *\n * @example\n * ```typescript\n * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');\n * const rels = await content.getRelationships(entity);\n * if (rels) {\n * rels.relationships.forEach(r => {\n * console.log(`${r.predicate} -> ${r.target_label}`);\n * });\n * }\n * ```\n */\n async getRelationships(entity: Entity): Promise<RelationshipsComponent | null> {\n const cid = entity.components.relationships;\n if (!cid) {\n return null;\n }\n return this.getDag<RelationshipsComponent>(cid);\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/content/index.d.cts
CHANGED
|
@@ -2,27 +2,40 @@
|
|
|
2
2
|
* Content package types for the Arke SDK
|
|
3
3
|
*
|
|
4
4
|
* Types for interacting with entities and content from the IPFS Wrapper service.
|
|
5
|
+
* Based on the arke/eidos@v1 schema.
|
|
5
6
|
*/
|
|
6
7
|
/**
|
|
7
8
|
* Full entity manifest from IPFS Wrapper
|
|
8
9
|
*/
|
|
9
10
|
interface Entity {
|
|
10
|
-
/**
|
|
11
|
-
|
|
11
|
+
/** Entity identifier (ULID or test ID with II prefix) */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Entity type (e.g., "PI", "person", "place", "concept", "document") */
|
|
14
|
+
type: string;
|
|
15
|
+
/** Creation timestamp (immutable, set at v1) */
|
|
16
|
+
created_at: string;
|
|
17
|
+
/** Display name */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Human-readable description */
|
|
20
|
+
description?: string;
|
|
12
21
|
/** Version number */
|
|
13
22
|
ver: number;
|
|
14
23
|
/** Timestamp when this version was created */
|
|
15
24
|
ts: string;
|
|
16
25
|
/** CID of this manifest */
|
|
17
26
|
manifest_cid: string;
|
|
18
|
-
/** CID of the previous version (
|
|
19
|
-
prev_cid
|
|
27
|
+
/** CID of the previous version (null for version 1) */
|
|
28
|
+
prev_cid: string | null;
|
|
20
29
|
/** Map of component names to their CIDs */
|
|
21
30
|
components: Record<string, string>;
|
|
22
|
-
/**
|
|
31
|
+
/** IDs of child entities */
|
|
23
32
|
children_pi?: string[];
|
|
24
|
-
/**
|
|
33
|
+
/** ID of parent entity */
|
|
25
34
|
parent_pi?: string;
|
|
35
|
+
/** Provenance: which PI extracted this entity */
|
|
36
|
+
source_pi?: string;
|
|
37
|
+
/** IDs of entities that have been merged into this one */
|
|
38
|
+
merged_entities?: string[];
|
|
26
39
|
/** Change note for this version */
|
|
27
40
|
note?: string;
|
|
28
41
|
}
|
|
@@ -30,10 +43,14 @@ interface Entity {
|
|
|
30
43
|
* Summary entity info returned when listing entities
|
|
31
44
|
*/
|
|
32
45
|
interface EntitySummary {
|
|
33
|
-
/**
|
|
34
|
-
|
|
46
|
+
/** Entity identifier */
|
|
47
|
+
id: string;
|
|
35
48
|
/** Tip CID (latest manifest) */
|
|
36
49
|
tip: string;
|
|
50
|
+
/** Entity type (if include_metadata=true) */
|
|
51
|
+
type?: string;
|
|
52
|
+
/** Display name (if include_metadata=true) */
|
|
53
|
+
label?: string;
|
|
37
54
|
/** Version number (if include_metadata=true) */
|
|
38
55
|
ver?: number;
|
|
39
56
|
/** Timestamp (if include_metadata=true) */
|
|
@@ -102,11 +119,55 @@ interface VersionsResponse {
|
|
|
102
119
|
* Response from resolving a PI
|
|
103
120
|
*/
|
|
104
121
|
interface ResolveResponse {
|
|
105
|
-
/**
|
|
106
|
-
|
|
122
|
+
/** Entity identifier */
|
|
123
|
+
id: string;
|
|
107
124
|
/** Tip CID (latest manifest) */
|
|
108
125
|
tip: string;
|
|
109
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* A single relationship edge in the semantic graph.
|
|
129
|
+
*
|
|
130
|
+
* Represents a typed, directional relationship from the source entity
|
|
131
|
+
* to a target entity or PI.
|
|
132
|
+
*/
|
|
133
|
+
interface Relationship {
|
|
134
|
+
/** Relationship predicate (e.g., "authored_by", "mentions", "located_in") */
|
|
135
|
+
predicate: string;
|
|
136
|
+
/** Type of target */
|
|
137
|
+
target_type: 'pi' | 'entity';
|
|
138
|
+
/** Target entity identifier */
|
|
139
|
+
target_id: string;
|
|
140
|
+
/** Display label for the target (e.g., "Alice Austen") */
|
|
141
|
+
target_label: string;
|
|
142
|
+
/** Target entity type (e.g., "person", "place") - only if target is entity */
|
|
143
|
+
target_entity_type?: string;
|
|
144
|
+
/** Optional metadata on the relationship edge */
|
|
145
|
+
properties?: Record<string, unknown>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Relationships component stored in IPFS (arke/relationships@v1 schema).
|
|
149
|
+
*
|
|
150
|
+
* Contains the semantic graph relationships for an entity.
|
|
151
|
+
*/
|
|
152
|
+
interface RelationshipsComponent {
|
|
153
|
+
/** Schema identifier */
|
|
154
|
+
schema: 'arke/relationships@v1';
|
|
155
|
+
/** Array of relationships */
|
|
156
|
+
relationships: Relationship[];
|
|
157
|
+
/** ISO 8601 timestamp when this component was created/updated */
|
|
158
|
+
timestamp: string;
|
|
159
|
+
/** Optional note about changes */
|
|
160
|
+
note?: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Properties component stored in IPFS.
|
|
164
|
+
*
|
|
165
|
+
* Contains arbitrary metadata properties for an entity.
|
|
166
|
+
*/
|
|
167
|
+
interface PropertiesComponent {
|
|
168
|
+
/** Arbitrary key-value properties */
|
|
169
|
+
[key: string]: unknown;
|
|
170
|
+
}
|
|
110
171
|
|
|
111
172
|
/**
|
|
112
173
|
* Configuration for ContentClient
|
|
@@ -324,6 +385,24 @@ declare class ContentClient {
|
|
|
324
385
|
* ```
|
|
325
386
|
*/
|
|
326
387
|
stream(cid: string): Promise<ReadableStream<Uint8Array>>;
|
|
388
|
+
/**
|
|
389
|
+
* Download a DAG node (JSON) by CID.
|
|
390
|
+
*
|
|
391
|
+
* Use this to fetch JSON components like properties and relationships.
|
|
392
|
+
*
|
|
393
|
+
* @param cid - Content Identifier of the DAG node
|
|
394
|
+
* @returns Parsed JSON object
|
|
395
|
+
* @throws ContentNotFoundError if the content doesn't exist
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```typescript
|
|
399
|
+
* const relationships = await content.getDag<RelationshipsComponent>(
|
|
400
|
+
* entity.components.relationships
|
|
401
|
+
* );
|
|
402
|
+
* console.log('Relationships:', relationships.relationships);
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
getDag<T = unknown>(cid: string): Promise<T>;
|
|
327
406
|
/**
|
|
328
407
|
* Download a component from an entity.
|
|
329
408
|
*
|
|
@@ -355,6 +434,40 @@ declare class ContentClient {
|
|
|
355
434
|
* ```
|
|
356
435
|
*/
|
|
357
436
|
getComponentUrl(entity: Entity, componentName: string): string;
|
|
437
|
+
/**
|
|
438
|
+
* Get the properties component for an entity.
|
|
439
|
+
*
|
|
440
|
+
* @param entity - Entity containing the properties component
|
|
441
|
+
* @returns Properties object, or null if no properties component exists
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
|
|
446
|
+
* const props = await content.getProperties(entity);
|
|
447
|
+
* if (props) {
|
|
448
|
+
* console.log('Title:', props.title);
|
|
449
|
+
* }
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
getProperties(entity: Entity): Promise<PropertiesComponent | null>;
|
|
453
|
+
/**
|
|
454
|
+
* Get the relationships component for an entity.
|
|
455
|
+
*
|
|
456
|
+
* @param entity - Entity containing the relationships component
|
|
457
|
+
* @returns Relationships component, or null if no relationships exist
|
|
458
|
+
*
|
|
459
|
+
* @example
|
|
460
|
+
* ```typescript
|
|
461
|
+
* const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
|
|
462
|
+
* const rels = await content.getRelationships(entity);
|
|
463
|
+
* if (rels) {
|
|
464
|
+
* rels.relationships.forEach(r => {
|
|
465
|
+
* console.log(`${r.predicate} -> ${r.target_label}`);
|
|
466
|
+
* });
|
|
467
|
+
* }
|
|
468
|
+
* ```
|
|
469
|
+
*/
|
|
470
|
+
getRelationships(entity: Entity): Promise<RelationshipsComponent | null>;
|
|
358
471
|
}
|
|
359
472
|
|
|
360
473
|
/**
|
|
@@ -369,10 +482,10 @@ declare class ContentError extends Error {
|
|
|
369
482
|
constructor(message: string, code?: string, details?: unknown | undefined);
|
|
370
483
|
}
|
|
371
484
|
/**
|
|
372
|
-
* Thrown when an entity is not found by
|
|
485
|
+
* Thrown when an entity is not found by ID
|
|
373
486
|
*/
|
|
374
487
|
declare class EntityNotFoundError extends ContentError {
|
|
375
|
-
constructor(
|
|
488
|
+
constructor(id: string);
|
|
376
489
|
}
|
|
377
490
|
/**
|
|
378
491
|
* Thrown when content is not found by CID
|
|
@@ -384,13 +497,13 @@ declare class ContentNotFoundError extends ContentError {
|
|
|
384
497
|
* Thrown when a component is not found on an entity
|
|
385
498
|
*/
|
|
386
499
|
declare class ComponentNotFoundError extends ContentError {
|
|
387
|
-
constructor(
|
|
500
|
+
constructor(id: string, componentName: string);
|
|
388
501
|
}
|
|
389
502
|
/**
|
|
390
503
|
* Thrown when a version is not found
|
|
391
504
|
*/
|
|
392
505
|
declare class VersionNotFoundError extends ContentError {
|
|
393
|
-
constructor(
|
|
506
|
+
constructor(id: string, selector: string);
|
|
394
507
|
}
|
|
395
508
|
/**
|
|
396
509
|
* Thrown when a network error occurs
|
|
@@ -400,4 +513,4 @@ declare class NetworkError extends ContentError {
|
|
|
400
513
|
constructor(message: string, statusCode?: number | undefined);
|
|
401
514
|
}
|
|
402
515
|
|
|
403
|
-
export { ComponentNotFoundError, ContentClient, type ContentClientConfig, ContentError, ContentNotFoundError, type Entity, EntityNotFoundError, type EntitySummary, type EntityVersion, type ListOptions, type ListResponse, NetworkError, type ResolveResponse, VersionNotFoundError, type VersionsOptions, type VersionsResponse };
|
|
516
|
+
export { ComponentNotFoundError, ContentClient, type ContentClientConfig, ContentError, ContentNotFoundError, type Entity, EntityNotFoundError, type EntitySummary, type EntityVersion, type ListOptions, type ListResponse, NetworkError, type PropertiesComponent, type Relationship, type RelationshipsComponent, type ResolveResponse, VersionNotFoundError, type VersionsOptions, type VersionsResponse };
|