@hypercerts-org/sdk-core 0.4.0-beta.0 → 0.5.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/.turbo/turbo-build.log +13 -301
- package/.turbo/turbo-test.log +15 -14
- package/CHANGELOG.md +42 -2
- package/README.md +459 -79
- package/dist/index.cjs +124 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -9
- package/dist/index.mjs +124 -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 +2 -2
- package/src/core/types.ts +3 -2
- package/src/repository/BlobOperationsImpl.ts +1 -1
- package/src/repository/CollaboratorOperationsImpl.ts +71 -25
- package/src/repository/HypercertOperationsImpl.ts +3 -3
- package/src/repository/OrganizationOperationsImpl.ts +67 -19
- package/src/repository/interfaces.ts +16 -4
- package/src/repository/types.ts +1 -1
- package/tests/repository/BlobOperationsImpl.test.ts +10 -9
- package/tests/repository/CollaboratorOperationsImpl.test.ts +15 -15
- package/tests/repository/OrganizationOperationsImpl.test.ts +17 -19
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,26 @@ class CollaboratorOperationsImpl {
|
|
|
3118
3118
|
return "editor";
|
|
3119
3119
|
return "viewer";
|
|
3120
3120
|
}
|
|
3121
|
+
/**
|
|
3122
|
+
* Converts a permission string array to a permissions object.
|
|
3123
|
+
*
|
|
3124
|
+
* The SDS API returns permissions as an array of strings (e.g., ["read", "create"]).
|
|
3125
|
+
* This method converts them to the boolean flag format used by the SDK.
|
|
3126
|
+
*
|
|
3127
|
+
* @param permissionArray - Array of permission strings from SDS API
|
|
3128
|
+
* @returns Permission flags object
|
|
3129
|
+
* @internal
|
|
3130
|
+
*/
|
|
3131
|
+
parsePermissions(permissionArray) {
|
|
3132
|
+
return {
|
|
3133
|
+
read: permissionArray.includes("read"),
|
|
3134
|
+
create: permissionArray.includes("create"),
|
|
3135
|
+
update: permissionArray.includes("update"),
|
|
3136
|
+
delete: permissionArray.includes("delete"),
|
|
3137
|
+
admin: permissionArray.includes("admin"),
|
|
3138
|
+
owner: permissionArray.includes("owner"),
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3121
3141
|
/**
|
|
3122
3142
|
* Grants repository access to a user.
|
|
3123
3143
|
*
|
|
@@ -3194,7 +3214,10 @@ class CollaboratorOperationsImpl {
|
|
|
3194
3214
|
/**
|
|
3195
3215
|
* Lists all collaborators on the repository.
|
|
3196
3216
|
*
|
|
3197
|
-
* @
|
|
3217
|
+
* @param params - Optional pagination parameters
|
|
3218
|
+
* @param params.limit - Maximum number of results (1-100, default 50)
|
|
3219
|
+
* @param params.cursor - Pagination cursor from previous response
|
|
3220
|
+
* @returns Promise resolving to collaborators and optional cursor
|
|
3198
3221
|
* @throws {@link NetworkError} if the list operation fails
|
|
3199
3222
|
*
|
|
3200
3223
|
* @remarks
|
|
@@ -3203,34 +3226,49 @@ class CollaboratorOperationsImpl {
|
|
|
3203
3226
|
*
|
|
3204
3227
|
* @example
|
|
3205
3228
|
* ```typescript
|
|
3206
|
-
*
|
|
3229
|
+
* // Get first page
|
|
3230
|
+
* const page1 = await repo.collaborators.list({ limit: 10 });
|
|
3231
|
+
* console.log(`Found ${page1.collaborators.length} collaborators`);
|
|
3232
|
+
*
|
|
3233
|
+
* // Get next page if available
|
|
3234
|
+
* if (page1.cursor) {
|
|
3235
|
+
* const page2 = await repo.collaborators.list({ limit: 10, cursor: page1.cursor });
|
|
3236
|
+
* }
|
|
3207
3237
|
*
|
|
3208
3238
|
* // 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
|
-
* };
|
|
3239
|
+
* const active = page1.collaborators.filter(c => !c.revokedAt);
|
|
3218
3240
|
* ```
|
|
3219
3241
|
*/
|
|
3220
|
-
async list() {
|
|
3221
|
-
const
|
|
3242
|
+
async list(params) {
|
|
3243
|
+
const queryParams = new URLSearchParams({
|
|
3244
|
+
repo: this.repoDid,
|
|
3245
|
+
});
|
|
3246
|
+
if (params?.limit !== undefined) {
|
|
3247
|
+
queryParams.set("limit", params.limit.toString());
|
|
3248
|
+
}
|
|
3249
|
+
if (params?.cursor) {
|
|
3250
|
+
queryParams.set("cursor", params.cursor);
|
|
3251
|
+
}
|
|
3252
|
+
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.listCollaborators?${queryParams.toString()}`, { method: "GET" });
|
|
3222
3253
|
if (!response.ok) {
|
|
3223
3254
|
throw new NetworkError(`Failed to list collaborators: ${response.statusText}`);
|
|
3224
3255
|
}
|
|
3225
3256
|
const data = await response.json();
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3257
|
+
const collaborators = (data.collaborators || []).map((c) => {
|
|
3258
|
+
const permissions = this.parsePermissions(c.permissions);
|
|
3259
|
+
return {
|
|
3260
|
+
userDid: c.userDid,
|
|
3261
|
+
role: this.permissionsToRole(permissions),
|
|
3262
|
+
permissions: permissions,
|
|
3263
|
+
grantedBy: c.grantedBy,
|
|
3264
|
+
grantedAt: c.grantedAt,
|
|
3265
|
+
revokedAt: c.revokedAt,
|
|
3266
|
+
};
|
|
3267
|
+
});
|
|
3268
|
+
return {
|
|
3269
|
+
collaborators,
|
|
3270
|
+
cursor: data.cursor,
|
|
3271
|
+
};
|
|
3234
3272
|
}
|
|
3235
3273
|
/**
|
|
3236
3274
|
* Checks if a user has any access to the repository.
|
|
@@ -3253,7 +3291,7 @@ class CollaboratorOperationsImpl {
|
|
|
3253
3291
|
*/
|
|
3254
3292
|
async hasAccess(userDid) {
|
|
3255
3293
|
try {
|
|
3256
|
-
const collaborators = await this.list();
|
|
3294
|
+
const { collaborators } = await this.list();
|
|
3257
3295
|
return collaborators.some((c) => c.userDid === userDid && !c.revokedAt);
|
|
3258
3296
|
}
|
|
3259
3297
|
catch {
|
|
@@ -3275,7 +3313,7 @@ class CollaboratorOperationsImpl {
|
|
|
3275
3313
|
* ```
|
|
3276
3314
|
*/
|
|
3277
3315
|
async getRole(userDid) {
|
|
3278
|
-
const collaborators = await this.list();
|
|
3316
|
+
const { collaborators } = await this.list();
|
|
3279
3317
|
const collab = collaborators.find((c) => c.userDid === userDid && !c.revokedAt);
|
|
3280
3318
|
return collab?.role ?? null;
|
|
3281
3319
|
}
|
|
@@ -3482,10 +3520,17 @@ class OrganizationOperationsImpl {
|
|
|
3482
3520
|
* ```
|
|
3483
3521
|
*/
|
|
3484
3522
|
async create(params) {
|
|
3523
|
+
const userDid = this.session.did || this.session.sub;
|
|
3524
|
+
if (!userDid) {
|
|
3525
|
+
throw new NetworkError("No authenticated user found");
|
|
3526
|
+
}
|
|
3485
3527
|
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.create`, {
|
|
3486
3528
|
method: "POST",
|
|
3487
3529
|
headers: { "Content-Type": "application/json" },
|
|
3488
|
-
body: JSON.stringify(
|
|
3530
|
+
body: JSON.stringify({
|
|
3531
|
+
...params,
|
|
3532
|
+
creatorDid: userDid,
|
|
3533
|
+
}),
|
|
3489
3534
|
});
|
|
3490
3535
|
if (!response.ok) {
|
|
3491
3536
|
throw new NetworkError(`Failed to create organization: ${response.statusText}`);
|
|
@@ -3497,8 +3542,15 @@ class OrganizationOperationsImpl {
|
|
|
3497
3542
|
name: data.name,
|
|
3498
3543
|
description: data.description,
|
|
3499
3544
|
createdAt: data.createdAt || new Date().toISOString(),
|
|
3500
|
-
accessType: "owner",
|
|
3501
|
-
permissions:
|
|
3545
|
+
accessType: data.accessType || "owner",
|
|
3546
|
+
permissions: data.permissions || {
|
|
3547
|
+
read: true,
|
|
3548
|
+
create: true,
|
|
3549
|
+
update: true,
|
|
3550
|
+
delete: true,
|
|
3551
|
+
admin: true,
|
|
3552
|
+
owner: true,
|
|
3553
|
+
},
|
|
3502
3554
|
};
|
|
3503
3555
|
}
|
|
3504
3556
|
/**
|
|
@@ -3525,8 +3577,8 @@ class OrganizationOperationsImpl {
|
|
|
3525
3577
|
*/
|
|
3526
3578
|
async get(did) {
|
|
3527
3579
|
try {
|
|
3528
|
-
const
|
|
3529
|
-
return
|
|
3580
|
+
const { organizations } = await this.list();
|
|
3581
|
+
return organizations.find((o) => o.did === did) ?? null;
|
|
3530
3582
|
}
|
|
3531
3583
|
catch {
|
|
3532
3584
|
return null;
|
|
@@ -3535,7 +3587,10 @@ class OrganizationOperationsImpl {
|
|
|
3535
3587
|
/**
|
|
3536
3588
|
* Lists organizations the current user has access to.
|
|
3537
3589
|
*
|
|
3538
|
-
* @
|
|
3590
|
+
* @param params - Optional pagination parameters
|
|
3591
|
+
* @param params.limit - Maximum number of results (1-100, default 50)
|
|
3592
|
+
* @param params.cursor - Pagination cursor from previous response
|
|
3593
|
+
* @returns Promise resolving to organizations and optional cursor
|
|
3539
3594
|
* @throws {@link NetworkError} if the list operation fails
|
|
3540
3595
|
*
|
|
3541
3596
|
* @remarks
|
|
@@ -3547,21 +3602,25 @@ class OrganizationOperationsImpl {
|
|
|
3547
3602
|
*
|
|
3548
3603
|
* @example
|
|
3549
3604
|
* ```typescript
|
|
3550
|
-
*
|
|
3605
|
+
* // Get first page
|
|
3606
|
+
* const page1 = await repo.organizations.list({ limit: 20 });
|
|
3607
|
+
* console.log(`Found ${page1.organizations.length} organizations`);
|
|
3551
3608
|
*
|
|
3552
|
-
* //
|
|
3553
|
-
*
|
|
3554
|
-
*
|
|
3609
|
+
* // Get next page if available
|
|
3610
|
+
* if (page1.cursor) {
|
|
3611
|
+
* const page2 = await repo.organizations.list({ limit: 20, cursor: page1.cursor });
|
|
3612
|
+
* }
|
|
3555
3613
|
*
|
|
3556
|
-
*
|
|
3557
|
-
*
|
|
3614
|
+
* // Filter by access type
|
|
3615
|
+
* const owned = page1.organizations.filter(o => o.accessType === "owner");
|
|
3616
|
+
* const shared = page1.organizations.filter(o => o.accessType === "shared");
|
|
3558
3617
|
* ```
|
|
3559
3618
|
*
|
|
3560
3619
|
* @example Display organization details
|
|
3561
3620
|
* ```typescript
|
|
3562
|
-
* const
|
|
3621
|
+
* const { organizations } = await repo.organizations.list();
|
|
3563
3622
|
*
|
|
3564
|
-
* for (const org of
|
|
3623
|
+
* for (const org of organizations) {
|
|
3565
3624
|
* console.log(`${org.name} (@${org.handle})`);
|
|
3566
3625
|
* console.log(` DID: ${org.did}`);
|
|
3567
3626
|
* console.log(` Access: ${org.accessType}`);
|
|
@@ -3571,21 +3630,38 @@ class OrganizationOperationsImpl {
|
|
|
3571
3630
|
* }
|
|
3572
3631
|
* ```
|
|
3573
3632
|
*/
|
|
3574
|
-
async list() {
|
|
3575
|
-
const
|
|
3633
|
+
async list(params) {
|
|
3634
|
+
const userDid = this.session.did || this.session.sub;
|
|
3635
|
+
if (!userDid) {
|
|
3636
|
+
throw new NetworkError("No authenticated user found");
|
|
3637
|
+
}
|
|
3638
|
+
const queryParams = new URLSearchParams({
|
|
3639
|
+
userDid,
|
|
3640
|
+
});
|
|
3641
|
+
if (params?.limit !== undefined) {
|
|
3642
|
+
queryParams.set("limit", params.limit.toString());
|
|
3643
|
+
}
|
|
3644
|
+
if (params?.cursor) {
|
|
3645
|
+
queryParams.set("cursor", params.cursor);
|
|
3646
|
+
}
|
|
3647
|
+
const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.list?${queryParams.toString()}`, { method: "GET" });
|
|
3576
3648
|
if (!response.ok) {
|
|
3577
3649
|
throw new NetworkError(`Failed to list organizations: ${response.statusText}`);
|
|
3578
3650
|
}
|
|
3579
3651
|
const data = await response.json();
|
|
3580
|
-
|
|
3652
|
+
const organizations = (data.organizations || []).map((r) => ({
|
|
3581
3653
|
did: r.did,
|
|
3582
3654
|
handle: r.handle,
|
|
3583
3655
|
name: r.name,
|
|
3584
3656
|
description: r.description,
|
|
3585
|
-
createdAt: new Date().toISOString(),
|
|
3657
|
+
createdAt: r.createdAt || new Date().toISOString(),
|
|
3586
3658
|
accessType: r.accessType,
|
|
3587
3659
|
permissions: r.permissions,
|
|
3588
3660
|
}));
|
|
3661
|
+
return {
|
|
3662
|
+
organizations,
|
|
3663
|
+
cursor: data.cursor,
|
|
3664
|
+
};
|
|
3589
3665
|
}
|
|
3590
3666
|
}
|
|
3591
3667
|
|
|
@@ -4508,9 +4584,10 @@ const OrganizationSchema = zod.z.object({
|
|
|
4508
4584
|
/**
|
|
4509
4585
|
* How the current user relates to this organization.
|
|
4510
4586
|
* - `"owner"`: User created or owns the organization
|
|
4511
|
-
* - `"
|
|
4587
|
+
* - `"shared"`: User was invited to collaborate (has permissions)
|
|
4588
|
+
* - `"none"`: User has no access to this organization
|
|
4512
4589
|
*/
|
|
4513
|
-
accessType: zod.z.enum(["owner", "
|
|
4590
|
+
accessType: zod.z.enum(["owner", "shared", "none"]),
|
|
4514
4591
|
});
|
|
4515
4592
|
/**
|
|
4516
4593
|
* Zod schema for collaborator data.
|