@hypercerts-org/sdk-core 0.5.0-beta.0 → 0.7.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 (57) hide show
  1. package/README.md +130 -8
  2. package/dist/index.cjs +93 -15
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +64 -1
  5. package/dist/index.mjs +93 -16
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +9 -5
  8. package/.turbo/turbo-build.log +0 -40
  9. package/.turbo/turbo-test.log +0 -119
  10. package/CHANGELOG.md +0 -62
  11. package/eslint.config.mjs +0 -22
  12. package/rollup.config.js +0 -75
  13. package/src/auth/OAuthClient.ts +0 -497
  14. package/src/core/SDK.ts +0 -410
  15. package/src/core/config.ts +0 -243
  16. package/src/core/errors.ts +0 -257
  17. package/src/core/interfaces.ts +0 -324
  18. package/src/core/types.ts +0 -282
  19. package/src/errors.ts +0 -57
  20. package/src/index.ts +0 -107
  21. package/src/lexicons.ts +0 -64
  22. package/src/repository/BlobOperationsImpl.ts +0 -199
  23. package/src/repository/CollaboratorOperationsImpl.ts +0 -442
  24. package/src/repository/HypercertOperationsImpl.ts +0 -1146
  25. package/src/repository/LexiconRegistry.ts +0 -332
  26. package/src/repository/OrganizationOperationsImpl.ts +0 -282
  27. package/src/repository/ProfileOperationsImpl.ts +0 -281
  28. package/src/repository/RecordOperationsImpl.ts +0 -340
  29. package/src/repository/Repository.ts +0 -482
  30. package/src/repository/interfaces.ts +0 -909
  31. package/src/repository/types.ts +0 -111
  32. package/src/services/hypercerts/types.ts +0 -87
  33. package/src/storage/InMemorySessionStore.ts +0 -127
  34. package/src/storage/InMemoryStateStore.ts +0 -146
  35. package/src/storage.ts +0 -63
  36. package/src/testing/index.ts +0 -67
  37. package/src/testing/mocks.ts +0 -142
  38. package/src/testing/stores.ts +0 -285
  39. package/src/testing.ts +0 -64
  40. package/src/types.ts +0 -86
  41. package/tests/auth/OAuthClient.test.ts +0 -164
  42. package/tests/core/SDK.test.ts +0 -176
  43. package/tests/core/errors.test.ts +0 -81
  44. package/tests/repository/BlobOperationsImpl.test.ts +0 -155
  45. package/tests/repository/CollaboratorOperationsImpl.test.ts +0 -438
  46. package/tests/repository/HypercertOperationsImpl.test.ts +0 -652
  47. package/tests/repository/LexiconRegistry.test.ts +0 -192
  48. package/tests/repository/OrganizationOperationsImpl.test.ts +0 -240
  49. package/tests/repository/ProfileOperationsImpl.test.ts +0 -254
  50. package/tests/repository/RecordOperationsImpl.test.ts +0 -375
  51. package/tests/repository/Repository.test.ts +0 -149
  52. package/tests/utils/fixtures.ts +0 -117
  53. package/tests/utils/mocks.ts +0 -109
  54. package/tests/utils/repository-fixtures.ts +0 -78
  55. package/tsconfig.json +0 -11
  56. package/tsconfig.tsbuildinfo +0 -1
  57. 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", "create", "update"],
135
- grantedBy: "did:plc:owner",
136
- grantedAt: "2024-01-01T00:00:00Z",
137
- },
138
- {
139
- userDid: "did:plc:user2",
140
- permissions: ["read"],
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.collaborators).toHaveLength(2);
151
- expect(result.collaborators[0].userDid).toBe("did:plc:user1");
152
- expect(result.collaborators[0].role).toBe("editor");
153
- expect(result.collaborators[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.collaborators).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", "create", "update", "delete", "admin", "owner"],
175
- grantedBy: "did:plc:system",
176
- grantedAt: "2024-01-01T00:00:00Z",
177
- },
178
- {
179
- userDid: "did:plc:admin",
180
- permissions: ["read", "create", "update", "delete", "admin"],
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.collaborators[0].role).toBe("owner");
191
- expect(result.collaborators[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"],
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"],
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", "create", "update"],
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", "create", "update"],
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
- });