@arke-institute/sdk 0.1.3 → 2.0.0

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 (64) hide show
  1. package/README.md +126 -184
  2. package/dist/generated/index.cjs +19 -0
  3. package/dist/generated/index.cjs.map +1 -0
  4. package/dist/generated/index.d.cts +6192 -0
  5. package/dist/generated/index.d.ts +6192 -0
  6. package/dist/generated/index.js +1 -0
  7. package/dist/generated/index.js.map +1 -0
  8. package/dist/index-BrXke2kI.d.ts +302 -0
  9. package/dist/index-FHcLPBSV.d.cts +302 -0
  10. package/dist/index.cjs +188 -4254
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +62 -7
  13. package/dist/index.d.ts +62 -7
  14. package/dist/index.js +168 -4226
  15. package/dist/index.js.map +1 -1
  16. package/dist/operations/index.cjs +113 -0
  17. package/dist/operations/index.cjs.map +1 -0
  18. package/dist/operations/index.d.cts +3 -0
  19. package/dist/operations/index.d.ts +3 -0
  20. package/dist/operations/index.js +84 -0
  21. package/dist/operations/index.js.map +1 -0
  22. package/package.json +44 -53
  23. package/dist/client-dAk3E64p.d.cts +0 -183
  24. package/dist/client-dAk3E64p.d.ts +0 -183
  25. package/dist/collections/index.cjs +0 -233
  26. package/dist/collections/index.cjs.map +0 -1
  27. package/dist/collections/index.d.cts +0 -9
  28. package/dist/collections/index.d.ts +0 -9
  29. package/dist/collections/index.js +0 -205
  30. package/dist/collections/index.js.map +0 -1
  31. package/dist/content/index.cjs +0 -591
  32. package/dist/content/index.cjs.map +0 -1
  33. package/dist/content/index.d.cts +0 -516
  34. package/dist/content/index.d.ts +0 -516
  35. package/dist/content/index.js +0 -558
  36. package/dist/content/index.js.map +0 -1
  37. package/dist/edit/index.cjs +0 -1503
  38. package/dist/edit/index.cjs.map +0 -1
  39. package/dist/edit/index.d.cts +0 -78
  40. package/dist/edit/index.d.ts +0 -78
  41. package/dist/edit/index.js +0 -1447
  42. package/dist/edit/index.js.map +0 -1
  43. package/dist/errors-3L7IiHcr.d.cts +0 -480
  44. package/dist/errors-BTe8GKRQ.d.ts +0 -480
  45. package/dist/errors-CT7yzKkU.d.cts +0 -874
  46. package/dist/errors-CT7yzKkU.d.ts +0 -874
  47. package/dist/graph/index.cjs +0 -427
  48. package/dist/graph/index.cjs.map +0 -1
  49. package/dist/graph/index.d.cts +0 -485
  50. package/dist/graph/index.d.ts +0 -485
  51. package/dist/graph/index.js +0 -396
  52. package/dist/graph/index.js.map +0 -1
  53. package/dist/query/index.cjs +0 -356
  54. package/dist/query/index.cjs.map +0 -1
  55. package/dist/query/index.d.cts +0 -636
  56. package/dist/query/index.d.ts +0 -636
  57. package/dist/query/index.js +0 -328
  58. package/dist/query/index.js.map +0 -1
  59. package/dist/upload/index.cjs +0 -1634
  60. package/dist/upload/index.cjs.map +0 -1
  61. package/dist/upload/index.d.cts +0 -150
  62. package/dist/upload/index.d.ts +0 -150
  63. package/dist/upload/index.js +0 -1597
  64. package/dist/upload/index.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/collections/errors.ts","../../src/collections/client.ts"],"sourcesContent":["export class CollectionsError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'CollectionsError';\n }\n}\n","import { CollectionsError } from './errors';\nimport type {\n ChangeRootPayload,\n ChangeRootResponse,\n Collection,\n CollectionDetails,\n CollectionRole,\n CreateCollectionPayload,\n Invitation,\n InvitationsResponse,\n Member,\n MembersResponse,\n MyAccessResponse,\n MyCollectionsResponse,\n PaginatedCollections,\n PiPermissions,\n RegisterRootPayload,\n RootResponse,\n SuccessResponse,\n UpdateCollectionPayload,\n} from './types';\n\nexport interface CollectionsClientConfig {\n /**\n * Gateway base URL (e.g., https://api.arke.institute).\n * Must already point at the Arke gateway that proxies /collections/*.\n */\n gatewayUrl: string;\n /**\n * Optional bearer token for authenticated routes.\n * Public routes will still include it if provided.\n */\n authToken?: string;\n /**\n * Optional custom fetch (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\nexport class CollectionsClient {\n private baseUrl: string;\n private authToken?: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: CollectionsClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.authToken = config.authToken;\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n setAuthToken(token?: string) {\n this.authToken = token;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | number | 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 getHeaders(authRequired: boolean): HeadersInit {\n const headers: HeadersInit = { 'Content-Type': 'application/json' };\n if (authRequired || this.authToken) {\n if (!this.authToken && authRequired) {\n throw new CollectionsError('Authentication required for this operation', 'AUTH_REQUIRED');\n }\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n }\n return headers;\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n authRequired?: boolean;\n query?: Record<string, string | number | undefined>;\n } = {}\n ): Promise<T> {\n const authRequired = options.authRequired ?? false;\n const url = this.buildUrl(path, options.query);\n const headers = new Headers(this.getHeaders(authRequired));\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 const response = await this.fetchImpl(url, { ...options, headers });\n\n if (response.ok) {\n if (response.status === 204) {\n return undefined as T;\n }\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 const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : `Request failed with status ${response.status}`;\n\n throw new CollectionsError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Collections\n // ---------------------------------------------------------------------------\n\n async listCollections(params?: { limit?: number; offset?: number }): Promise<PaginatedCollections> {\n return this.request('/collections', {\n method: 'GET',\n query: { limit: params?.limit, offset: params?.offset },\n });\n }\n\n async getCollection(id: string): Promise<CollectionDetails> {\n return this.request(`/collections/${id}`, { method: 'GET' });\n }\n\n async getCollectionRoot(id: string): Promise<RootResponse> {\n return this.request(`/collections/${id}/root`, { method: 'GET' });\n }\n\n async getMyAccess(id: string): Promise<MyAccessResponse> {\n return this.request(`/collections/${id}/my-access`, { method: 'GET', authRequired: true });\n }\n\n async createCollection(payload: CreateCollectionPayload): Promise<Collection> {\n return this.request('/collections', {\n method: 'POST',\n authRequired: true,\n body: JSON.stringify(payload),\n });\n }\n\n async registerRoot(payload: RegisterRootPayload): Promise<Collection & { rootPi: string }> {\n return this.request('/collections/register-root', {\n method: 'POST',\n authRequired: true,\n body: JSON.stringify(payload),\n });\n }\n\n async updateCollection(id: string, payload: UpdateCollectionPayload): Promise<Collection> {\n return this.request(`/collections/${id}`, {\n method: 'PATCH',\n authRequired: true,\n body: JSON.stringify(payload),\n });\n }\n\n async changeRoot(id: string, payload: ChangeRootPayload): Promise<ChangeRootResponse> {\n return this.request(`/collections/${id}/change-root`, {\n method: 'PATCH',\n authRequired: true,\n body: JSON.stringify(payload),\n });\n }\n\n async deleteCollection(id: string): Promise<SuccessResponse> {\n return this.request(`/collections/${id}`, {\n method: 'DELETE',\n authRequired: true,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Members\n // ---------------------------------------------------------------------------\n\n async listMembers(collectionId: string): Promise<MembersResponse> {\n return this.request(`/collections/${collectionId}/members`, { method: 'GET' });\n }\n\n async updateMemberRole(\n collectionId: string,\n userId: string,\n role: CollectionRole\n ): Promise<{ success: true; role: CollectionRole }> {\n return this.request(`/collections/${collectionId}/members/${userId}`, {\n method: 'PATCH',\n authRequired: true,\n body: JSON.stringify({ role }),\n });\n }\n\n async removeMember(collectionId: string, userId: string): Promise<SuccessResponse> {\n return this.request(`/collections/${collectionId}/members/${userId}`, {\n method: 'DELETE',\n authRequired: true,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Invitations\n // ---------------------------------------------------------------------------\n\n async createInvitation(collectionId: string, email: string, role: CollectionRole): Promise<Invitation> {\n return this.request(`/collections/${collectionId}/invitations`, {\n method: 'POST',\n authRequired: true,\n body: JSON.stringify({ email, role }),\n });\n }\n\n async listInvitations(collectionId: string): Promise<InvitationsResponse> {\n return this.request(`/collections/${collectionId}/invitations`, {\n method: 'GET',\n authRequired: true,\n });\n }\n\n async acceptInvitation(invitationId: string): Promise<{ success: true; role: CollectionRole }> {\n return this.request(`/invitations/${invitationId}/accept`, {\n method: 'POST',\n authRequired: true,\n });\n }\n\n async declineInvitation(invitationId: string): Promise<SuccessResponse> {\n return this.request(`/invitations/${invitationId}/decline`, {\n method: 'POST',\n authRequired: true,\n });\n }\n\n async revokeInvitation(invitationId: string): Promise<SuccessResponse> {\n return this.request(`/invitations/${invitationId}`, {\n method: 'DELETE',\n authRequired: true,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Current user\n // ---------------------------------------------------------------------------\n\n async getMyCollections(): Promise<MyCollectionsResponse> {\n return this.request('/me/collections', { method: 'GET', authRequired: true });\n }\n\n async getMyInvitations(): Promise<InvitationsResponse> {\n return this.request('/me/invitations', { method: 'GET', authRequired: true });\n }\n\n // ---------------------------------------------------------------------------\n // PI permissions\n // ---------------------------------------------------------------------------\n\n async getPiPermissions(pi: string): Promise<PiPermissions> {\n return this.request(`/pi/${pi}/permissions`, { method: 'GET' });\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,591 +0,0 @@
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/content/index.ts
21
- var content_exports = {};
22
- __export(content_exports, {
23
- ComponentNotFoundError: () => ComponentNotFoundError,
24
- ContentClient: () => ContentClient,
25
- ContentError: () => ContentError,
26
- ContentNotFoundError: () => ContentNotFoundError,
27
- EntityNotFoundError: () => EntityNotFoundError,
28
- NetworkError: () => NetworkError,
29
- VersionNotFoundError: () => VersionNotFoundError
30
- });
31
- module.exports = __toCommonJS(content_exports);
32
-
33
- // src/content/errors.ts
34
- var ContentError = class extends Error {
35
- constructor(message, code = "CONTENT_ERROR", details) {
36
- super(message);
37
- this.code = code;
38
- this.details = details;
39
- this.name = "ContentError";
40
- }
41
- };
42
- var EntityNotFoundError = class extends ContentError {
43
- constructor(id) {
44
- super(`Entity not found: ${id}`, "ENTITY_NOT_FOUND", { id });
45
- this.name = "EntityNotFoundError";
46
- }
47
- };
48
- var ContentNotFoundError = class extends ContentError {
49
- constructor(cid) {
50
- super(`Content not found: ${cid}`, "CONTENT_NOT_FOUND", { cid });
51
- this.name = "ContentNotFoundError";
52
- }
53
- };
54
- var ComponentNotFoundError = class extends ContentError {
55
- constructor(id, componentName) {
56
- super(
57
- `Component '${componentName}' not found on entity ${id}`,
58
- "COMPONENT_NOT_FOUND",
59
- { id, componentName }
60
- );
61
- this.name = "ComponentNotFoundError";
62
- }
63
- };
64
- var VersionNotFoundError = class extends ContentError {
65
- constructor(id, selector) {
66
- super(
67
- `Version not found: ${selector} for entity ${id}`,
68
- "VERSION_NOT_FOUND",
69
- { id, selector }
70
- );
71
- this.name = "VersionNotFoundError";
72
- }
73
- };
74
- var NetworkError = class extends ContentError {
75
- constructor(message, statusCode) {
76
- super(message, "NETWORK_ERROR", { statusCode });
77
- this.statusCode = statusCode;
78
- this.name = "NetworkError";
79
- }
80
- };
81
-
82
- // src/content/client.ts
83
- var ContentClient = class {
84
- constructor(config) {
85
- this.baseUrl = config.gatewayUrl.replace(/\/$/, "");
86
- this.fetchImpl = config.fetchImpl ?? fetch;
87
- }
88
- // ---------------------------------------------------------------------------
89
- // Request helpers
90
- // ---------------------------------------------------------------------------
91
- buildUrl(path, query) {
92
- const url = new URL(`${this.baseUrl}${path}`);
93
- if (query) {
94
- Object.entries(query).forEach(([key, value]) => {
95
- if (value !== void 0 && value !== null) {
96
- url.searchParams.set(key, String(value));
97
- }
98
- });
99
- }
100
- return url.toString();
101
- }
102
- async request(path, options = {}) {
103
- const url = this.buildUrl(path, options.query);
104
- const headers = new Headers({ "Content-Type": "application/json" });
105
- if (options.headers) {
106
- Object.entries(options.headers).forEach(([k, v]) => {
107
- if (v !== void 0) headers.set(k, v);
108
- });
109
- }
110
- let response;
111
- try {
112
- response = await this.fetchImpl(url, { ...options, headers });
113
- } catch (err) {
114
- throw new NetworkError(
115
- err instanceof Error ? err.message : "Network request failed"
116
- );
117
- }
118
- if (response.ok) {
119
- const contentType = response.headers.get("content-type") || "";
120
- if (contentType.includes("application/json")) {
121
- return await response.json();
122
- }
123
- return await response.text();
124
- }
125
- let body;
126
- const text = await response.text();
127
- try {
128
- body = JSON.parse(text);
129
- } catch {
130
- body = text;
131
- }
132
- if (response.status === 404) {
133
- const errorCode = body?.error;
134
- if (errorCode === "NOT_FOUND" || errorCode === "ENTITY_NOT_FOUND") {
135
- throw new ContentError(
136
- body?.message || "Not found",
137
- "NOT_FOUND",
138
- body
139
- );
140
- }
141
- }
142
- const message = body?.error && typeof body.error === "string" ? body.error : body?.message && typeof body.message === "string" ? body.message : `Request failed with status ${response.status}`;
143
- throw new ContentError(message, "HTTP_ERROR", {
144
- status: response.status,
145
- body
146
- });
147
- }
148
- // ---------------------------------------------------------------------------
149
- // Entity Operations
150
- // ---------------------------------------------------------------------------
151
- /**
152
- * Get an entity by its Persistent Identifier (PI).
153
- *
154
- * @param pi - Persistent Identifier (ULID or test PI with II prefix)
155
- * @returns Full entity manifest
156
- * @throws EntityNotFoundError if the entity doesn't exist
157
- *
158
- * @example
159
- * ```typescript
160
- * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
161
- * console.log('Version:', entity.ver);
162
- * console.log('Components:', Object.keys(entity.components));
163
- * ```
164
- */
165
- async get(pi) {
166
- try {
167
- return await this.request(`/api/entities/${encodeURIComponent(pi)}`);
168
- } catch (err) {
169
- if (err instanceof ContentError && err.code === "NOT_FOUND") {
170
- throw new EntityNotFoundError(pi);
171
- }
172
- throw err;
173
- }
174
- }
175
- /**
176
- * List entities with pagination.
177
- *
178
- * @param options - Pagination and metadata options
179
- * @returns Paginated list of entity summaries
180
- *
181
- * @example
182
- * ```typescript
183
- * // Get first page
184
- * const page1 = await content.list({ limit: 20, include_metadata: true });
185
- *
186
- * // Get next page
187
- * if (page1.next_cursor) {
188
- * const page2 = await content.list({ cursor: page1.next_cursor });
189
- * }
190
- * ```
191
- */
192
- async list(options = {}) {
193
- return this.request("/api/entities", {
194
- query: {
195
- limit: options.limit,
196
- cursor: options.cursor,
197
- include_metadata: options.include_metadata
198
- }
199
- });
200
- }
201
- /**
202
- * Get version history for an entity.
203
- *
204
- * @param pi - Persistent Identifier
205
- * @param options - Pagination options
206
- * @returns Version history (newest first)
207
- *
208
- * @example
209
- * ```typescript
210
- * const history = await content.versions('01K75HQQXNTDG7BBP7PS9AWYAN');
211
- * console.log('Total versions:', history.items.length);
212
- * history.items.forEach(v => {
213
- * console.log(`v${v.ver}: ${v.ts} - ${v.note || 'no note'}`);
214
- * });
215
- * ```
216
- */
217
- async versions(pi, options = {}) {
218
- try {
219
- return await this.request(
220
- `/api/entities/${encodeURIComponent(pi)}/versions`,
221
- {
222
- query: {
223
- limit: options.limit,
224
- cursor: options.cursor
225
- }
226
- }
227
- );
228
- } catch (err) {
229
- if (err instanceof ContentError && err.code === "NOT_FOUND") {
230
- throw new EntityNotFoundError(pi);
231
- }
232
- throw err;
233
- }
234
- }
235
- /**
236
- * Get a specific version of an entity.
237
- *
238
- * @param pi - Persistent Identifier
239
- * @param selector - Version selector: 'ver:N' for version number or 'cid:...' for CID
240
- * @returns Entity manifest for the specified version
241
- *
242
- * @example
243
- * ```typescript
244
- * // Get version 2
245
- * const v2 = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'ver:2');
246
- *
247
- * // Get by CID
248
- * const vByCid = await content.getVersion('01K75HQQXNTDG7BBP7PS9AWYAN', 'cid:bafybeih...');
249
- * ```
250
- */
251
- async getVersion(pi, selector) {
252
- try {
253
- return await this.request(
254
- `/api/entities/${encodeURIComponent(pi)}/versions/${encodeURIComponent(selector)}`
255
- );
256
- } catch (err) {
257
- if (err instanceof ContentError && err.code === "NOT_FOUND") {
258
- throw new EntityNotFoundError(pi);
259
- }
260
- throw err;
261
- }
262
- }
263
- /**
264
- * Resolve a PI to its tip CID (fast lookup without fetching manifest).
265
- *
266
- * @param pi - Persistent Identifier
267
- * @returns PI and tip CID
268
- *
269
- * @example
270
- * ```typescript
271
- * const { tip } = await content.resolve('01K75HQQXNTDG7BBP7PS9AWYAN');
272
- * console.log('Latest manifest CID:', tip);
273
- * ```
274
- */
275
- async resolve(pi) {
276
- try {
277
- return await this.request(`/api/resolve/${encodeURIComponent(pi)}`);
278
- } catch (err) {
279
- if (err instanceof ContentError && err.code === "NOT_FOUND") {
280
- throw new EntityNotFoundError(pi);
281
- }
282
- throw err;
283
- }
284
- }
285
- /**
286
- * Get the list of child PIs for an entity (fast, returns only PIs).
287
- *
288
- * @param pi - Persistent Identifier of parent entity
289
- * @returns Array of child PIs
290
- *
291
- * @example
292
- * ```typescript
293
- * const childPis = await content.children('01K75HQQXNTDG7BBP7PS9AWYAN');
294
- * console.log('Children:', childPis);
295
- * ```
296
- */
297
- async children(pi) {
298
- const entity = await this.get(pi);
299
- return entity.children_pi || [];
300
- }
301
- /**
302
- * Get all child entities for a parent (fetches full entity for each child).
303
- *
304
- * @param pi - Persistent Identifier of parent entity
305
- * @returns Array of child entities
306
- *
307
- * @example
308
- * ```typescript
309
- * const childEntities = await content.childrenEntities('01K75HQQXNTDG7BBP7PS9AWYAN');
310
- * childEntities.forEach(child => {
311
- * console.log(`${child.pi}: v${child.ver}`);
312
- * });
313
- * ```
314
- */
315
- async childrenEntities(pi) {
316
- const childPis = await this.children(pi);
317
- if (childPis.length === 0) {
318
- return [];
319
- }
320
- const results = await Promise.allSettled(
321
- childPis.map((childPi) => this.get(childPi))
322
- );
323
- return results.filter((r) => r.status === "fulfilled").map((r) => r.value);
324
- }
325
- /**
326
- * Get the Arke origin block (root of the archive tree).
327
- *
328
- * @returns Arke origin entity
329
- *
330
- * @example
331
- * ```typescript
332
- * const origin = await content.arke();
333
- * console.log('Arke origin:', origin.pi);
334
- * ```
335
- */
336
- async arke() {
337
- return this.request("/api/arke");
338
- }
339
- // ---------------------------------------------------------------------------
340
- // Content Download
341
- // ---------------------------------------------------------------------------
342
- /**
343
- * Download content by CID.
344
- *
345
- * Returns Blob in browser environments, Buffer in Node.js.
346
- *
347
- * @param cid - Content Identifier
348
- * @returns Content as Blob (browser) or Buffer (Node)
349
- * @throws ContentNotFoundError if the content doesn't exist
350
- *
351
- * @example
352
- * ```typescript
353
- * const content = await client.download('bafybeih...');
354
- *
355
- * // In browser
356
- * const url = URL.createObjectURL(content as Blob);
357
- *
358
- * // In Node.js
359
- * fs.writeFileSync('output.bin', content as Buffer);
360
- * ```
361
- */
362
- async download(cid) {
363
- const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);
364
- let response;
365
- try {
366
- response = await this.fetchImpl(url);
367
- } catch (err) {
368
- throw new NetworkError(
369
- err instanceof Error ? err.message : "Network request failed"
370
- );
371
- }
372
- if (!response.ok) {
373
- if (response.status === 404) {
374
- throw new ContentNotFoundError(cid);
375
- }
376
- throw new ContentError(
377
- `Failed to download content: ${response.status}`,
378
- "DOWNLOAD_ERROR",
379
- { status: response.status }
380
- );
381
- }
382
- if (typeof window !== "undefined") {
383
- return response.blob();
384
- } else {
385
- const arrayBuffer = await response.arrayBuffer();
386
- return Buffer.from(arrayBuffer);
387
- }
388
- }
389
- /**
390
- * Get a direct URL for content by CID.
391
- *
392
- * This is useful for embedding in img tags or for direct downloads.
393
- *
394
- * @param cid - Content Identifier
395
- * @returns URL string
396
- *
397
- * @example
398
- * ```typescript
399
- * const url = content.getUrl('bafybeih...');
400
- * // Use in img tag: <img src={url} />
401
- * ```
402
- */
403
- getUrl(cid) {
404
- return `${this.baseUrl}/api/cat/${encodeURIComponent(cid)}`;
405
- }
406
- /**
407
- * Stream content by CID.
408
- *
409
- * @param cid - Content Identifier
410
- * @returns ReadableStream of the content
411
- * @throws ContentNotFoundError if the content doesn't exist
412
- *
413
- * @example
414
- * ```typescript
415
- * const stream = await content.stream('bafybeih...');
416
- * const reader = stream.getReader();
417
- * while (true) {
418
- * const { done, value } = await reader.read();
419
- * if (done) break;
420
- * // Process chunk
421
- * }
422
- * ```
423
- */
424
- async stream(cid) {
425
- const url = this.buildUrl(`/api/cat/${encodeURIComponent(cid)}`);
426
- let response;
427
- try {
428
- response = await this.fetchImpl(url);
429
- } catch (err) {
430
- throw new NetworkError(
431
- err instanceof Error ? err.message : "Network request failed"
432
- );
433
- }
434
- if (!response.ok) {
435
- if (response.status === 404) {
436
- throw new ContentNotFoundError(cid);
437
- }
438
- throw new ContentError(
439
- `Failed to stream content: ${response.status}`,
440
- "STREAM_ERROR",
441
- { status: response.status }
442
- );
443
- }
444
- if (!response.body) {
445
- throw new ContentError("Response body is not available", "STREAM_ERROR");
446
- }
447
- return response.body;
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
- }
488
- // ---------------------------------------------------------------------------
489
- // Component Helpers
490
- // ---------------------------------------------------------------------------
491
- /**
492
- * Download a component from an entity.
493
- *
494
- * @param entity - Entity containing the component
495
- * @param componentName - Name of the component (e.g., 'pinax', 'description', 'source')
496
- * @returns Component content as Blob (browser) or Buffer (Node)
497
- * @throws ComponentNotFoundError if the component doesn't exist
498
- *
499
- * @example
500
- * ```typescript
501
- * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
502
- * const pinax = await content.getComponent(entity, 'pinax');
503
- * ```
504
- */
505
- async getComponent(entity, componentName) {
506
- const cid = entity.components[componentName];
507
- if (!cid) {
508
- throw new ComponentNotFoundError(entity.id, componentName);
509
- }
510
- return this.download(cid);
511
- }
512
- /**
513
- * Get the URL for a component from an entity.
514
- *
515
- * @param entity - Entity containing the component
516
- * @param componentName - Name of the component
517
- * @returns URL string
518
- * @throws ComponentNotFoundError if the component doesn't exist
519
- *
520
- * @example
521
- * ```typescript
522
- * const entity = await content.get('01K75HQQXNTDG7BBP7PS9AWYAN');
523
- * const imageUrl = content.getComponentUrl(entity, 'source');
524
- * // Use in img tag: <img src={imageUrl} />
525
- * ```
526
- */
527
- getComponentUrl(entity, componentName) {
528
- const cid = entity.components[componentName];
529
- if (!cid) {
530
- throw new ComponentNotFoundError(entity.id, componentName);
531
- }
532
- return this.getUrl(cid);
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
- }
580
- };
581
- // Annotate the CommonJS export names for ESM import in node:
582
- 0 && (module.exports = {
583
- ComponentNotFoundError,
584
- ContentClient,
585
- ContentError,
586
- ContentNotFoundError,
587
- EntityNotFoundError,
588
- NetworkError,
589
- VersionNotFoundError
590
- });
591
- //# sourceMappingURL=index.cjs.map