@hypercerts-org/sdk-core 0.4.0-beta.0 → 0.6.0-beta.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 (62) hide show
  1. package/README.md +459 -79
  2. package/dist/index.cjs +128 -47
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +28 -9
  5. package/dist/index.mjs +128 -47
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/types.cjs +3 -2
  8. package/dist/types.cjs.map +1 -1
  9. package/dist/types.d.ts +28 -9
  10. package/dist/types.mjs +3 -2
  11. package/dist/types.mjs.map +1 -1
  12. package/package.json +9 -5
  13. package/.turbo/turbo-build.log +0 -328
  14. package/.turbo/turbo-test.log +0 -118
  15. package/CHANGELOG.md +0 -22
  16. package/eslint.config.mjs +0 -22
  17. package/rollup.config.js +0 -75
  18. package/src/auth/OAuthClient.ts +0 -497
  19. package/src/core/SDK.ts +0 -410
  20. package/src/core/config.ts +0 -243
  21. package/src/core/errors.ts +0 -257
  22. package/src/core/interfaces.ts +0 -324
  23. package/src/core/types.ts +0 -281
  24. package/src/errors.ts +0 -57
  25. package/src/index.ts +0 -107
  26. package/src/lexicons.ts +0 -64
  27. package/src/repository/BlobOperationsImpl.ts +0 -199
  28. package/src/repository/CollaboratorOperationsImpl.ts +0 -396
  29. package/src/repository/HypercertOperationsImpl.ts +0 -1146
  30. package/src/repository/LexiconRegistry.ts +0 -332
  31. package/src/repository/OrganizationOperationsImpl.ts +0 -234
  32. package/src/repository/ProfileOperationsImpl.ts +0 -281
  33. package/src/repository/RecordOperationsImpl.ts +0 -340
  34. package/src/repository/Repository.ts +0 -482
  35. package/src/repository/interfaces.ts +0 -897
  36. package/src/repository/types.ts +0 -111
  37. package/src/services/hypercerts/types.ts +0 -87
  38. package/src/storage/InMemorySessionStore.ts +0 -127
  39. package/src/storage/InMemoryStateStore.ts +0 -146
  40. package/src/storage.ts +0 -63
  41. package/src/testing/index.ts +0 -67
  42. package/src/testing/mocks.ts +0 -142
  43. package/src/testing/stores.ts +0 -285
  44. package/src/testing.ts +0 -64
  45. package/src/types.ts +0 -86
  46. package/tests/auth/OAuthClient.test.ts +0 -164
  47. package/tests/core/SDK.test.ts +0 -176
  48. package/tests/core/errors.test.ts +0 -81
  49. package/tests/repository/BlobOperationsImpl.test.ts +0 -154
  50. package/tests/repository/CollaboratorOperationsImpl.test.ts +0 -438
  51. package/tests/repository/HypercertOperationsImpl.test.ts +0 -652
  52. package/tests/repository/LexiconRegistry.test.ts +0 -192
  53. package/tests/repository/OrganizationOperationsImpl.test.ts +0 -242
  54. package/tests/repository/ProfileOperationsImpl.test.ts +0 -254
  55. package/tests/repository/RecordOperationsImpl.test.ts +0 -375
  56. package/tests/repository/Repository.test.ts +0 -149
  57. package/tests/utils/fixtures.ts +0 -117
  58. package/tests/utils/mocks.ts +0 -109
  59. package/tests/utils/repository-fixtures.ts +0 -78
  60. package/tsconfig.json +0 -11
  61. package/tsconfig.tsbuildinfo +0 -1
  62. package/vitest.config.ts +0 -30
@@ -1,438 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import { CollaboratorOperationsImpl } from "../../src/repository/CollaboratorOperationsImpl.js";
3
- import { NetworkError } from "../../src/core/errors.js";
4
-
5
- describe("CollaboratorOperationsImpl", () => {
6
- let mockSession: any;
7
- let collaboratorOps: CollaboratorOperationsImpl;
8
- const repoDid = "did:plc:testdid123";
9
- const serverUrl = "https://sds.example.com";
10
-
11
- beforeEach(() => {
12
- mockSession = {
13
- did: "did:plc:user123",
14
- sub: "did:plc:user123",
15
- fetchHandler: vi.fn(),
16
- };
17
-
18
- collaboratorOps = new CollaboratorOperationsImpl(mockSession, repoDid, serverUrl);
19
- });
20
-
21
- describe("grant", () => {
22
- it("should grant viewer access", async () => {
23
- mockSession.fetchHandler.mockResolvedValue({
24
- ok: true,
25
- json: async () => ({}),
26
- });
27
-
28
- await collaboratorOps.grant({ userDid: "did:plc:newuser", role: "viewer" });
29
-
30
- expect(mockSession.fetchHandler).toHaveBeenCalledWith(
31
- `${serverUrl}/xrpc/com.sds.repo.grantAccess`,
32
- expect.objectContaining({
33
- method: "POST",
34
- body: expect.stringContaining('"read":true'),
35
- }),
36
- );
37
-
38
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
39
- expect(body.permissions.read).toBe(true);
40
- expect(body.permissions.create).toBe(false);
41
- expect(body.permissions.update).toBe(false);
42
- expect(body.permissions.delete).toBe(false);
43
- });
44
-
45
- it("should grant editor access", async () => {
46
- mockSession.fetchHandler.mockResolvedValue({
47
- ok: true,
48
- json: async () => ({}),
49
- });
50
-
51
- await collaboratorOps.grant({ userDid: "did:plc:newuser", role: "editor" });
52
-
53
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
54
- expect(body.permissions.read).toBe(true);
55
- expect(body.permissions.create).toBe(true);
56
- expect(body.permissions.update).toBe(true);
57
- expect(body.permissions.delete).toBe(false);
58
- });
59
-
60
- it("should grant admin access", async () => {
61
- mockSession.fetchHandler.mockResolvedValue({
62
- ok: true,
63
- json: async () => ({}),
64
- });
65
-
66
- await collaboratorOps.grant({ userDid: "did:plc:newuser", role: "admin" });
67
-
68
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
69
- expect(body.permissions.admin).toBe(true);
70
- expect(body.permissions.delete).toBe(true);
71
- });
72
-
73
- it("should grant owner access", async () => {
74
- mockSession.fetchHandler.mockResolvedValue({
75
- ok: true,
76
- json: async () => ({}),
77
- });
78
-
79
- await collaboratorOps.grant({ userDid: "did:plc:newuser", role: "owner" });
80
-
81
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
82
- expect(body.permissions.owner).toBe(true);
83
- });
84
-
85
- it("should throw NetworkError on failure", async () => {
86
- mockSession.fetchHandler.mockResolvedValue({
87
- ok: false,
88
- statusText: "Forbidden",
89
- });
90
-
91
- await expect(collaboratorOps.grant({ userDid: "did:plc:newuser", role: "viewer" })).rejects.toThrow(NetworkError);
92
- });
93
- });
94
-
95
- describe("revoke", () => {
96
- it("should revoke access successfully", async () => {
97
- mockSession.fetchHandler.mockResolvedValue({
98
- ok: true,
99
- json: async () => ({}),
100
- });
101
-
102
- await collaboratorOps.revoke({ userDid: "did:plc:revokeduser" });
103
-
104
- expect(mockSession.fetchHandler).toHaveBeenCalledWith(
105
- `${serverUrl}/xrpc/com.sds.repo.revokeAccess`,
106
- expect.objectContaining({
107
- method: "POST",
108
- }),
109
- );
110
-
111
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
112
- expect(body.repo).toBe(repoDid);
113
- expect(body.userDid).toBe("did:plc:revokeduser");
114
- });
115
-
116
- it("should throw NetworkError on failure", async () => {
117
- mockSession.fetchHandler.mockResolvedValue({
118
- ok: false,
119
- statusText: "Not Found",
120
- });
121
-
122
- await expect(collaboratorOps.revoke({ userDid: "did:plc:user" })).rejects.toThrow(NetworkError);
123
- });
124
- });
125
-
126
- describe("list", () => {
127
- it("should list collaborators successfully", async () => {
128
- mockSession.fetchHandler.mockResolvedValue({
129
- ok: true,
130
- json: async () => ({
131
- collaborators: [
132
- {
133
- userDid: "did:plc:user1",
134
- permissions: { read: true, create: true, update: true, delete: false, admin: false, owner: false },
135
- grantedBy: "did:plc:owner",
136
- grantedAt: "2024-01-01T00:00:00Z",
137
- },
138
- {
139
- userDid: "did:plc:user2",
140
- permissions: { read: true, create: false, update: false, delete: false, admin: false, owner: false },
141
- grantedBy: "did:plc:owner",
142
- grantedAt: "2024-01-02T00:00:00Z",
143
- },
144
- ],
145
- }),
146
- });
147
-
148
- const result = await collaboratorOps.list();
149
-
150
- expect(result).toHaveLength(2);
151
- expect(result[0].userDid).toBe("did:plc:user1");
152
- expect(result[0].role).toBe("editor");
153
- expect(result[1].role).toBe("viewer");
154
- });
155
-
156
- it("should handle empty collaborators list", async () => {
157
- mockSession.fetchHandler.mockResolvedValue({
158
- ok: true,
159
- json: async () => ({ collaborators: [] }),
160
- });
161
-
162
- const result = await collaboratorOps.list();
163
-
164
- expect(result).toHaveLength(0);
165
- });
166
-
167
- it("should correctly map permissions to roles", async () => {
168
- mockSession.fetchHandler.mockResolvedValue({
169
- ok: true,
170
- json: async () => ({
171
- collaborators: [
172
- {
173
- userDid: "did:plc:owner",
174
- permissions: { read: true, create: true, update: true, delete: true, admin: true, owner: true },
175
- grantedBy: "did:plc:system",
176
- grantedAt: "2024-01-01T00:00:00Z",
177
- },
178
- {
179
- userDid: "did:plc:admin",
180
- permissions: { read: true, create: true, update: true, delete: true, admin: true, owner: false },
181
- grantedBy: "did:plc:owner",
182
- grantedAt: "2024-01-01T00:00:00Z",
183
- },
184
- ],
185
- }),
186
- });
187
-
188
- const result = await collaboratorOps.list();
189
-
190
- expect(result[0].role).toBe("owner");
191
- expect(result[1].role).toBe("admin");
192
- });
193
-
194
- it("should throw NetworkError on failure", async () => {
195
- mockSession.fetchHandler.mockResolvedValue({
196
- ok: false,
197
- statusText: "Server Error",
198
- });
199
-
200
- await expect(collaboratorOps.list()).rejects.toThrow(NetworkError);
201
- });
202
- });
203
-
204
- describe("hasAccess", () => {
205
- it("should return true for active collaborator", async () => {
206
- mockSession.fetchHandler.mockResolvedValue({
207
- ok: true,
208
- json: async () => ({
209
- collaborators: [
210
- {
211
- userDid: "did:plc:activeuser",
212
- permissions: { read: true, create: false, update: false, delete: false, admin: false, owner: false },
213
- grantedBy: "did:plc:owner",
214
- grantedAt: "2024-01-01T00:00:00Z",
215
- },
216
- ],
217
- }),
218
- });
219
-
220
- const result = await collaboratorOps.hasAccess("did:plc:activeuser");
221
-
222
- expect(result).toBe(true);
223
- });
224
-
225
- it("should return false for unknown user", async () => {
226
- mockSession.fetchHandler.mockResolvedValue({
227
- ok: true,
228
- json: async () => ({ collaborators: [] }),
229
- });
230
-
231
- const result = await collaboratorOps.hasAccess("did:plc:unknown");
232
-
233
- expect(result).toBe(false);
234
- });
235
-
236
- it("should return false for revoked user", async () => {
237
- mockSession.fetchHandler.mockResolvedValue({
238
- ok: true,
239
- json: async () => ({
240
- collaborators: [
241
- {
242
- userDid: "did:plc:revokeduser",
243
- permissions: { read: true, create: false, update: false, delete: false, admin: false, owner: false },
244
- grantedBy: "did:plc:owner",
245
- grantedAt: "2024-01-01T00:00:00Z",
246
- revokedAt: "2024-02-01T00:00:00Z",
247
- },
248
- ],
249
- }),
250
- });
251
-
252
- const result = await collaboratorOps.hasAccess("did:plc:revokeduser");
253
-
254
- expect(result).toBe(false);
255
- });
256
-
257
- it("should return false on error", async () => {
258
- mockSession.fetchHandler.mockRejectedValue(new Error("Network error"));
259
-
260
- const result = await collaboratorOps.hasAccess("did:plc:user");
261
-
262
- expect(result).toBe(false);
263
- });
264
- });
265
-
266
- describe("getRole", () => {
267
- it("should return role for active collaborator", async () => {
268
- mockSession.fetchHandler.mockResolvedValue({
269
- ok: true,
270
- json: async () => ({
271
- collaborators: [
272
- {
273
- userDid: "did:plc:editor",
274
- permissions: { read: true, create: true, update: true, delete: false, admin: false, owner: false },
275
- grantedBy: "did:plc:owner",
276
- grantedAt: "2024-01-01T00:00:00Z",
277
- },
278
- ],
279
- }),
280
- });
281
-
282
- const result = await collaboratorOps.getRole("did:plc:editor");
283
-
284
- expect(result).toBe("editor");
285
- });
286
-
287
- it("should return null for unknown user", async () => {
288
- mockSession.fetchHandler.mockResolvedValue({
289
- ok: true,
290
- json: async () => ({ collaborators: [] }),
291
- });
292
-
293
- const result = await collaboratorOps.getRole("did:plc:unknown");
294
-
295
- expect(result).toBeNull();
296
- });
297
-
298
- it("should return null for revoked user", async () => {
299
- mockSession.fetchHandler.mockResolvedValue({
300
- ok: true,
301
- json: async () => ({
302
- collaborators: [
303
- {
304
- userDid: "did:plc:revoked",
305
- permissions: { read: true, create: true, update: true, delete: false, admin: false, owner: false },
306
- grantedBy: "did:plc:owner",
307
- grantedAt: "2024-01-01T00:00:00Z",
308
- revokedAt: "2024-02-01T00:00:00Z",
309
- },
310
- ],
311
- }),
312
- });
313
-
314
- const result = await collaboratorOps.getRole("did:plc:revoked");
315
-
316
- expect(result).toBeNull();
317
- });
318
- });
319
-
320
- describe("getPermissions", () => {
321
- it("should get current user permissions successfully", async () => {
322
- mockSession.fetchHandler.mockResolvedValue({
323
- ok: true,
324
- json: async () => ({
325
- permissions: {
326
- read: true,
327
- create: true,
328
- update: true,
329
- delete: false,
330
- admin: false,
331
- owner: false,
332
- },
333
- }),
334
- });
335
-
336
- const result = await collaboratorOps.getPermissions();
337
-
338
- expect(mockSession.fetchHandler).toHaveBeenCalledWith(
339
- `${serverUrl}/xrpc/com.sds.repo.getPermissions?repo=${encodeURIComponent(repoDid)}`,
340
- expect.objectContaining({
341
- method: "GET",
342
- }),
343
- );
344
-
345
- expect(result.read).toBe(true);
346
- expect(result.create).toBe(true);
347
- expect(result.update).toBe(true);
348
- expect(result.delete).toBe(false);
349
- expect(result.admin).toBe(false);
350
- expect(result.owner).toBe(false);
351
- });
352
-
353
- it("should handle owner permissions", async () => {
354
- mockSession.fetchHandler.mockResolvedValue({
355
- ok: true,
356
- json: async () => ({
357
- permissions: {
358
- read: true,
359
- create: true,
360
- update: true,
361
- delete: true,
362
- admin: true,
363
- owner: true,
364
- },
365
- }),
366
- });
367
-
368
- const result = await collaboratorOps.getPermissions();
369
-
370
- expect(result.owner).toBe(true);
371
- expect(result.admin).toBe(true);
372
- });
373
-
374
- it("should throw NetworkError on failure", async () => {
375
- mockSession.fetchHandler.mockResolvedValue({
376
- ok: false,
377
- statusText: "Forbidden",
378
- });
379
-
380
- await expect(collaboratorOps.getPermissions()).rejects.toThrow(NetworkError);
381
- });
382
- });
383
-
384
- describe("transferOwnership", () => {
385
- it("should transfer ownership successfully", async () => {
386
- mockSession.fetchHandler.mockResolvedValue({
387
- ok: true,
388
- json: async () => ({}),
389
- });
390
-
391
- await collaboratorOps.transferOwnership({ newOwnerDid: "did:plc:new-owner" });
392
-
393
- expect(mockSession.fetchHandler).toHaveBeenCalledWith(
394
- `${serverUrl}/xrpc/com.sds.repo.transferOwnership`,
395
- expect.objectContaining({
396
- method: "POST",
397
- }),
398
- );
399
-
400
- const body = JSON.parse(mockSession.fetchHandler.mock.calls[0][1].body);
401
- expect(body.repo).toBe(repoDid);
402
- expect(body.newOwner).toBe("did:plc:new-owner");
403
- });
404
-
405
- it("should throw NetworkError on failure", async () => {
406
- mockSession.fetchHandler.mockResolvedValue({
407
- ok: false,
408
- statusText: "Forbidden",
409
- });
410
-
411
- await expect(collaboratorOps.transferOwnership({ newOwnerDid: "did:plc:new-owner" })).rejects.toThrow(
412
- NetworkError,
413
- );
414
- });
415
-
416
- it("should throw NetworkError when not owner", async () => {
417
- mockSession.fetchHandler.mockResolvedValue({
418
- ok: false,
419
- statusText: "Forbidden: Only the owner can transfer ownership",
420
- });
421
-
422
- await expect(collaboratorOps.transferOwnership({ newOwnerDid: "did:plc:new-owner" })).rejects.toThrow(
423
- NetworkError,
424
- );
425
- });
426
-
427
- it("should throw NetworkError when new owner does not exist", async () => {
428
- mockSession.fetchHandler.mockResolvedValue({
429
- ok: false,
430
- statusText: "Not Found: New owner DID not found",
431
- });
432
-
433
- await expect(collaboratorOps.transferOwnership({ newOwnerDid: "did:plc:nonexistent" })).rejects.toThrow(
434
- NetworkError,
435
- );
436
- });
437
- });
438
- });