@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.
- package/README.md +459 -79
- package/dist/index.cjs +128 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -9
- package/dist/index.mjs +128 -47
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +3 -2
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +28 -9
- package/dist/types.mjs +3 -2
- package/dist/types.mjs.map +1 -1
- package/package.json +9 -5
- package/.turbo/turbo-build.log +0 -328
- package/.turbo/turbo-test.log +0 -118
- package/CHANGELOG.md +0 -22
- package/eslint.config.mjs +0 -22
- package/rollup.config.js +0 -75
- package/src/auth/OAuthClient.ts +0 -497
- package/src/core/SDK.ts +0 -410
- package/src/core/config.ts +0 -243
- package/src/core/errors.ts +0 -257
- package/src/core/interfaces.ts +0 -324
- package/src/core/types.ts +0 -281
- package/src/errors.ts +0 -57
- package/src/index.ts +0 -107
- package/src/lexicons.ts +0 -64
- package/src/repository/BlobOperationsImpl.ts +0 -199
- package/src/repository/CollaboratorOperationsImpl.ts +0 -396
- package/src/repository/HypercertOperationsImpl.ts +0 -1146
- package/src/repository/LexiconRegistry.ts +0 -332
- package/src/repository/OrganizationOperationsImpl.ts +0 -234
- package/src/repository/ProfileOperationsImpl.ts +0 -281
- package/src/repository/RecordOperationsImpl.ts +0 -340
- package/src/repository/Repository.ts +0 -482
- package/src/repository/interfaces.ts +0 -897
- package/src/repository/types.ts +0 -111
- package/src/services/hypercerts/types.ts +0 -87
- package/src/storage/InMemorySessionStore.ts +0 -127
- package/src/storage/InMemoryStateStore.ts +0 -146
- package/src/storage.ts +0 -63
- package/src/testing/index.ts +0 -67
- package/src/testing/mocks.ts +0 -142
- package/src/testing/stores.ts +0 -285
- package/src/testing.ts +0 -64
- package/src/types.ts +0 -86
- package/tests/auth/OAuthClient.test.ts +0 -164
- package/tests/core/SDK.test.ts +0 -176
- package/tests/core/errors.test.ts +0 -81
- package/tests/repository/BlobOperationsImpl.test.ts +0 -154
- package/tests/repository/CollaboratorOperationsImpl.test.ts +0 -438
- package/tests/repository/HypercertOperationsImpl.test.ts +0 -652
- package/tests/repository/LexiconRegistry.test.ts +0 -192
- package/tests/repository/OrganizationOperationsImpl.test.ts +0 -242
- package/tests/repository/ProfileOperationsImpl.test.ts +0 -254
- package/tests/repository/RecordOperationsImpl.test.ts +0 -375
- package/tests/repository/Repository.test.ts +0 -149
- package/tests/utils/fixtures.ts +0 -117
- package/tests/utils/mocks.ts +0 -109
- package/tests/utils/repository-fixtures.ts +0 -78
- package/tsconfig.json +0 -11
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -30
package/dist/index.cjs
CHANGED
|
@@ -1670,7 +1670,7 @@ class BlobOperationsImpl {
|
|
|
1670
1670
|
throw new NetworkError("Failed to upload blob");
|
|
1671
1671
|
}
|
|
1672
1672
|
return {
|
|
1673
|
-
ref: result.data.blob.ref,
|
|
1673
|
+
ref: { $link: result.data.blob.ref.toString() },
|
|
1674
1674
|
mimeType: result.data.blob.mimeType,
|
|
1675
1675
|
size: result.data.blob.size,
|
|
1676
1676
|
};
|
|
@@ -2177,7 +2177,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2177
2177
|
if (uploadResult.success) {
|
|
2178
2178
|
imageBlobRef = {
|
|
2179
2179
|
$type: "blob",
|
|
2180
|
-
ref: uploadResult.data.blob.ref,
|
|
2180
|
+
ref: { $link: uploadResult.data.blob.ref.toString() },
|
|
2181
2181
|
mimeType: uploadResult.data.blob.mimeType,
|
|
2182
2182
|
size: uploadResult.data.blob.size,
|
|
2183
2183
|
};
|
|
@@ -2602,7 +2602,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2602
2602
|
if (uploadResult.success) {
|
|
2603
2603
|
locationValue = {
|
|
2604
2604
|
$type: "blob",
|
|
2605
|
-
ref: uploadResult.data.blob.ref,
|
|
2605
|
+
ref: { $link: uploadResult.data.blob.ref.toString() },
|
|
2606
2606
|
mimeType: uploadResult.data.blob.mimeType,
|
|
2607
2607
|
size: uploadResult.data.blob.size,
|
|
2608
2608
|
};
|
|
@@ -2887,7 +2887,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2887
2887
|
if (uploadResult.success) {
|
|
2888
2888
|
coverPhotoRef = {
|
|
2889
2889
|
$type: "blob",
|
|
2890
|
-
ref: uploadResult.data.blob.ref,
|
|
2890
|
+
ref: { $link: uploadResult.data.blob.ref.toString() },
|
|
2891
2891
|
mimeType: uploadResult.data.blob.mimeType,
|
|
2892
2892
|
size: uploadResult.data.blob.size,
|
|
2893
2893
|
};
|
|
@@ -3118,6 +3118,27 @@ class CollaboratorOperationsImpl {
|
|
|
3118
3118
|
return "editor";
|
|
3119
3119
|
return "viewer";
|
|
3120
3120
|
}
|
|
3121
|
+
/**
|
|
3122
|
+
* Normalizes permissions from SDS API format to SDK format.
|
|
3123
|
+
*
|
|
3124
|
+
* The SDS API returns permissions as an object with boolean flags
|
|
3125
|
+
* (e.g., `{ read: true, create: true, update: false, ... }`).
|
|
3126
|
+
* This method ensures all expected fields are present with default values.
|
|
3127
|
+
*
|
|
3128
|
+
* @param permissions - Permissions object from SDS API
|
|
3129
|
+
* @returns Normalized permission flags object
|
|
3130
|
+
* @internal
|
|
3131
|
+
*/
|
|
3132
|
+
parsePermissions(permissions) {
|
|
3133
|
+
return {
|
|
3134
|
+
read: permissions.read ?? false,
|
|
3135
|
+
create: permissions.create ?? false,
|
|
3136
|
+
update: permissions.update ?? false,
|
|
3137
|
+
delete: permissions.delete ?? false,
|
|
3138
|
+
admin: permissions.admin ?? false,
|
|
3139
|
+
owner: permissions.owner ?? false,
|
|
3140
|
+
};
|
|
3141
|
+
}
|
|
3121
3142
|
/**
|
|
3122
3143
|
* Grants repository access to a user.
|
|
3123
3144
|
*
|
|
@@ -3194,7 +3215,10 @@ class CollaboratorOperationsImpl {
|
|
|
3194
3215
|
/**
|
|
3195
3216
|
* Lists all collaborators on the repository.
|
|
3196
3217
|
*
|
|
3197
|
-
* @
|
|
3218
|
+
* @param params - Optional pagination parameters
|
|
3219
|
+
* @param params.limit - Maximum number of results (1-100, default 50)
|
|
3220
|
+
* @param params.cursor - Pagination cursor from previous response
|
|
3221
|
+
* @returns Promise resolving to collaborators and optional cursor
|
|
3198
3222
|
* @throws {@link NetworkError} if the list operation fails
|
|
3199
3223
|
*
|
|
3200
3224
|
* @remarks
|
|
@@ -3203,34 +3227,49 @@ class CollaboratorOperationsImpl {
|
|
|
3203
3227
|
*
|
|
3204
3228
|
* @example
|
|
3205
3229
|
* ```typescript
|
|
3206
|
-
*
|
|
3230
|
+
* // Get first page
|
|
3231
|
+
* const page1 = await repo.collaborators.list({ limit: 10 });
|
|
3232
|
+
* console.log(`Found ${page1.collaborators.length} collaborators`);
|
|
3233
|
+
*
|
|
3234
|
+
* // Get next page if available
|
|
3235
|
+
* if (page1.cursor) {
|
|
3236
|
+
* const page2 = await repo.collaborators.list({ limit: 10, cursor: page1.cursor });
|
|
3237
|
+
* }
|
|
3207
3238
|
*
|
|
3208
3239
|
* // Filter active collaborators
|
|
3209
|
-
* const active = collaborators.filter(c => !c.revokedAt);
|
|
3210
|
-
*
|
|
3211
|
-
* // Group by role
|
|
3212
|
-
* const byRole = {
|
|
3213
|
-
* owners: active.filter(c => c.role === "owner"),
|
|
3214
|
-
* admins: active.filter(c => c.role === "admin"),
|
|
3215
|
-
* editors: active.filter(c => c.role === "editor"),
|
|
3216
|
-
* viewers: active.filter(c => c.role === "viewer"),
|
|
3217
|
-
* };
|
|
3240
|
+
* const active = page1.collaborators.filter(c => !c.revokedAt);
|
|
3218
3241
|
* ```
|
|
3219
3242
|
*/
|
|
3220
|
-
async list() {
|
|
3221
|
-
const
|
|
3243
|
+
async list(params) {
|
|
3244
|
+
const queryParams = new URLSearchParams({
|
|
3245
|
+
repo: this.repoDid,
|
|
3246
|
+
});
|
|
3247
|
+
if (params?.limit !== undefined) {
|
|
3248
|
+
queryParams.set("limit", params.limit.toString());
|
|
3249
|
+
}
|
|
3250
|
+
if (params?.cursor) {
|
|
3251
|
+
queryParams.set("cursor", params.cursor);
|
|
3252
|
+
}
|
|
3253
|
+
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.listCollaborators?${queryParams.toString()}`, { method: "GET" });
|
|
3222
3254
|
if (!response.ok) {
|
|
3223
3255
|
throw new NetworkError(`Failed to list collaborators: ${response.statusText}`);
|
|
3224
3256
|
}
|
|
3225
3257
|
const data = await response.json();
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3258
|
+
const collaborators = (data.collaborators || []).map((c) => {
|
|
3259
|
+
const permissions = this.parsePermissions(c.permissions);
|
|
3260
|
+
return {
|
|
3261
|
+
userDid: c.userDid,
|
|
3262
|
+
role: this.permissionsToRole(permissions),
|
|
3263
|
+
permissions: permissions,
|
|
3264
|
+
grantedBy: c.grantedBy,
|
|
3265
|
+
grantedAt: c.grantedAt,
|
|
3266
|
+
revokedAt: c.revokedAt,
|
|
3267
|
+
};
|
|
3268
|
+
});
|
|
3269
|
+
return {
|
|
3270
|
+
collaborators,
|
|
3271
|
+
cursor: data.cursor,
|
|
3272
|
+
};
|
|
3234
3273
|
}
|
|
3235
3274
|
/**
|
|
3236
3275
|
* Checks if a user has any access to the repository.
|
|
@@ -3253,7 +3292,7 @@ class CollaboratorOperationsImpl {
|
|
|
3253
3292
|
*/
|
|
3254
3293
|
async hasAccess(userDid) {
|
|
3255
3294
|
try {
|
|
3256
|
-
const collaborators = await this.list();
|
|
3295
|
+
const { collaborators } = await this.list();
|
|
3257
3296
|
return collaborators.some((c) => c.userDid === userDid && !c.revokedAt);
|
|
3258
3297
|
}
|
|
3259
3298
|
catch {
|
|
@@ -3275,7 +3314,7 @@ class CollaboratorOperationsImpl {
|
|
|
3275
3314
|
* ```
|
|
3276
3315
|
*/
|
|
3277
3316
|
async getRole(userDid) {
|
|
3278
|
-
const collaborators = await this.list();
|
|
3317
|
+
const { collaborators } = await this.list();
|
|
3279
3318
|
const collab = collaborators.find((c) => c.userDid === userDid && !c.revokedAt);
|
|
3280
3319
|
return collab?.role ?? null;
|
|
3281
3320
|
}
|
|
@@ -3482,10 +3521,17 @@ class OrganizationOperationsImpl {
|
|
|
3482
3521
|
* ```
|
|
3483
3522
|
*/
|
|
3484
3523
|
async create(params) {
|
|
3524
|
+
const userDid = this.session.did || this.session.sub;
|
|
3525
|
+
if (!userDid) {
|
|
3526
|
+
throw new NetworkError("No authenticated user found");
|
|
3527
|
+
}
|
|
3485
3528
|
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.create`, {
|
|
3486
3529
|
method: "POST",
|
|
3487
3530
|
headers: { "Content-Type": "application/json" },
|
|
3488
|
-
body: JSON.stringify(
|
|
3531
|
+
body: JSON.stringify({
|
|
3532
|
+
...params,
|
|
3533
|
+
creatorDid: userDid,
|
|
3534
|
+
}),
|
|
3489
3535
|
});
|
|
3490
3536
|
if (!response.ok) {
|
|
3491
3537
|
throw new NetworkError(`Failed to create organization: ${response.statusText}`);
|
|
@@ -3497,8 +3543,15 @@ class OrganizationOperationsImpl {
|
|
|
3497
3543
|
name: data.name,
|
|
3498
3544
|
description: data.description,
|
|
3499
3545
|
createdAt: data.createdAt || new Date().toISOString(),
|
|
3500
|
-
accessType: "owner",
|
|
3501
|
-
permissions:
|
|
3546
|
+
accessType: data.accessType || "owner",
|
|
3547
|
+
permissions: data.permissions || {
|
|
3548
|
+
read: true,
|
|
3549
|
+
create: true,
|
|
3550
|
+
update: true,
|
|
3551
|
+
delete: true,
|
|
3552
|
+
admin: true,
|
|
3553
|
+
owner: true,
|
|
3554
|
+
},
|
|
3502
3555
|
};
|
|
3503
3556
|
}
|
|
3504
3557
|
/**
|
|
@@ -3525,8 +3578,8 @@ class OrganizationOperationsImpl {
|
|
|
3525
3578
|
*/
|
|
3526
3579
|
async get(did) {
|
|
3527
3580
|
try {
|
|
3528
|
-
const
|
|
3529
|
-
return
|
|
3581
|
+
const { organizations } = await this.list();
|
|
3582
|
+
return organizations.find((o) => o.did === did) ?? null;
|
|
3530
3583
|
}
|
|
3531
3584
|
catch {
|
|
3532
3585
|
return null;
|
|
@@ -3535,7 +3588,10 @@ class OrganizationOperationsImpl {
|
|
|
3535
3588
|
/**
|
|
3536
3589
|
* Lists organizations the current user has access to.
|
|
3537
3590
|
*
|
|
3538
|
-
* @
|
|
3591
|
+
* @param params - Optional pagination parameters
|
|
3592
|
+
* @param params.limit - Maximum number of results (1-100, default 50)
|
|
3593
|
+
* @param params.cursor - Pagination cursor from previous response
|
|
3594
|
+
* @returns Promise resolving to organizations and optional cursor
|
|
3539
3595
|
* @throws {@link NetworkError} if the list operation fails
|
|
3540
3596
|
*
|
|
3541
3597
|
* @remarks
|
|
@@ -3547,21 +3603,25 @@ class OrganizationOperationsImpl {
|
|
|
3547
3603
|
*
|
|
3548
3604
|
* @example
|
|
3549
3605
|
* ```typescript
|
|
3550
|
-
*
|
|
3606
|
+
* // Get first page
|
|
3607
|
+
* const page1 = await repo.organizations.list({ limit: 20 });
|
|
3608
|
+
* console.log(`Found ${page1.organizations.length} organizations`);
|
|
3551
3609
|
*
|
|
3552
|
-
* //
|
|
3553
|
-
*
|
|
3554
|
-
*
|
|
3610
|
+
* // Get next page if available
|
|
3611
|
+
* if (page1.cursor) {
|
|
3612
|
+
* const page2 = await repo.organizations.list({ limit: 20, cursor: page1.cursor });
|
|
3613
|
+
* }
|
|
3555
3614
|
*
|
|
3556
|
-
*
|
|
3557
|
-
*
|
|
3615
|
+
* // Filter by access type
|
|
3616
|
+
* const owned = page1.organizations.filter(o => o.accessType === "owner");
|
|
3617
|
+
* const shared = page1.organizations.filter(o => o.accessType === "shared");
|
|
3558
3618
|
* ```
|
|
3559
3619
|
*
|
|
3560
3620
|
* @example Display organization details
|
|
3561
3621
|
* ```typescript
|
|
3562
|
-
* const
|
|
3622
|
+
* const { organizations } = await repo.organizations.list();
|
|
3563
3623
|
*
|
|
3564
|
-
* for (const org of
|
|
3624
|
+
* for (const org of organizations) {
|
|
3565
3625
|
* console.log(`${org.name} (@${org.handle})`);
|
|
3566
3626
|
* console.log(` DID: ${org.did}`);
|
|
3567
3627
|
* console.log(` Access: ${org.accessType}`);
|
|
@@ -3571,21 +3631,38 @@ class OrganizationOperationsImpl {
|
|
|
3571
3631
|
* }
|
|
3572
3632
|
* ```
|
|
3573
3633
|
*/
|
|
3574
|
-
async list() {
|
|
3575
|
-
const
|
|
3634
|
+
async list(params) {
|
|
3635
|
+
const userDid = this.session.did || this.session.sub;
|
|
3636
|
+
if (!userDid) {
|
|
3637
|
+
throw new NetworkError("No authenticated user found");
|
|
3638
|
+
}
|
|
3639
|
+
const queryParams = new URLSearchParams({
|
|
3640
|
+
userDid,
|
|
3641
|
+
});
|
|
3642
|
+
if (params?.limit !== undefined) {
|
|
3643
|
+
queryParams.set("limit", params.limit.toString());
|
|
3644
|
+
}
|
|
3645
|
+
if (params?.cursor) {
|
|
3646
|
+
queryParams.set("cursor", params.cursor);
|
|
3647
|
+
}
|
|
3648
|
+
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.list?${queryParams.toString()}`, { method: "GET" });
|
|
3576
3649
|
if (!response.ok) {
|
|
3577
3650
|
throw new NetworkError(`Failed to list organizations: ${response.statusText}`);
|
|
3578
3651
|
}
|
|
3579
3652
|
const data = await response.json();
|
|
3580
|
-
|
|
3653
|
+
const organizations = (data.organizations || []).map((r) => ({
|
|
3581
3654
|
did: r.did,
|
|
3582
3655
|
handle: r.handle,
|
|
3583
3656
|
name: r.name,
|
|
3584
3657
|
description: r.description,
|
|
3585
|
-
createdAt: new Date().toISOString(),
|
|
3658
|
+
createdAt: r.createdAt || new Date().toISOString(),
|
|
3586
3659
|
accessType: r.accessType,
|
|
3587
3660
|
permissions: r.permissions,
|
|
3588
3661
|
}));
|
|
3662
|
+
return {
|
|
3663
|
+
organizations,
|
|
3664
|
+
cursor: data.cursor,
|
|
3665
|
+
};
|
|
3589
3666
|
}
|
|
3590
3667
|
}
|
|
3591
3668
|
|
|
@@ -3697,6 +3774,9 @@ class Repository {
|
|
|
3697
3774
|
this.logger = logger;
|
|
3698
3775
|
// Create Agent with OAuth session
|
|
3699
3776
|
this.agent = new api.Agent(session);
|
|
3777
|
+
// Configure Agent to use the specified server URL (PDS or SDS)
|
|
3778
|
+
// This ensures queries are routed to the correct server
|
|
3779
|
+
this.agent.api.xrpc.uri = new URL(serverUrl);
|
|
3700
3780
|
this.lexiconRegistry.addToAgent(this.agent);
|
|
3701
3781
|
// Register hypercert lexicons
|
|
3702
3782
|
this.lexiconRegistry.registerMany(lexicon.HYPERCERT_LEXICONS);
|
|
@@ -4508,9 +4588,10 @@ const OrganizationSchema = zod.z.object({
|
|
|
4508
4588
|
/**
|
|
4509
4589
|
* How the current user relates to this organization.
|
|
4510
4590
|
* - `"owner"`: User created or owns the organization
|
|
4511
|
-
* - `"
|
|
4591
|
+
* - `"shared"`: User was invited to collaborate (has permissions)
|
|
4592
|
+
* - `"none"`: User has no access to this organization
|
|
4512
4593
|
*/
|
|
4513
|
-
accessType: zod.z.enum(["owner", "
|
|
4594
|
+
accessType: zod.z.enum(["owner", "shared", "none"]),
|
|
4514
4595
|
});
|
|
4515
4596
|
/**
|
|
4516
4597
|
* Zod schema for collaborator data.
|