@@ -411,7 +411,130 @@ const measurement = await repo.hypercerts.addMeasurement({
411411});
412412```
413413
414- ### 5. Blob Operations (Images & Files)
414+ ### 5. Collections and Projects
415+
416+ Collections organize multiple hypercerts into logical groupings. Projects are a special type of collection with
417+ ` type="project" ` .
418+
419+ #### Creating a Collection
420+
421+ ``` typescript
422+ // Create a collection with weighted items
423+ const collection = await repo .hypercerts .createCollection ({
424+ title: " Climate Projects 2024" ,
425+ shortDescription: " Our climate impact portfolio" ,
426+ description: " A curated collection of climate-related hypercerts" ,
427+ items: [
428+ {
429+ itemIdentifier: { uri: hypercert1Uri , cid: hypercert1Cid },
430+ itemWeight: " 0.5" ,
431+ },
432+ {
433+ itemIdentifier: { uri: hypercert2Uri , cid: hypercert2Cid },
434+ itemWeight: " 0.3" ,
435+ },
436+ {
437+ itemIdentifier: { uri: hypercert3Uri , cid: hypercert3Cid },
438+ itemWeight: " 0.2" ,
439+ },
440+ ],
441+ avatar: avatarBlob , // optional
442+ banner: bannerBlob , // optional
443+ });
444+
445+ console .log (" Created collection:" , collection .uri );
446+ ```
447+
448+ #### Creating a Project
449+
450+ Projects are collections with automatic ` type="project" ` :
451+
452+ ``` typescript
453+ const project = await repo .hypercerts .createProject ({
454+ title: " Rainforest Restoration" ,
455+ shortDescription: " Multi-year restoration initiative" ,
456+ description: " Comprehensive rainforest restoration project" ,
457+ items: [
458+ {
459+ itemIdentifier: { uri: activity1Uri , cid: activity1Cid },
460+ itemWeight: " 0.6" ,
461+ },
462+ {
463+ itemIdentifier: { uri: activity2Uri , cid: activity2Cid },
464+ itemWeight: " 0.4" ,
465+ },
466+ ],
467+ });
468+ ```
469+
470+ #### Attaching Locations
471+
472+ Both collections and projects can have location data attached as a sidecar record:
473+
474+ ``` typescript
475+ // Attach location to a project
476+ const locationResult = await repo .hypercerts .attachLocationToProject (projectUri , {
477+ lpVersion: " 1.0" ,
478+ srs: " EPSG:4326" ,
479+ locationType: " coordinate-decimal" ,
480+ location: " https://example.com/location.geojson" , // or use a Blob
481+ name: " Project Site" ,
482+ description: " Main restoration site coordinates" ,
483+ });
484+
485+ // Also works for collections
486+ await repo .hypercerts .attachLocationToCollection (collectionUri , locationParams );
487+ ```
488+
489+ #### Listing and Retrieving
490+
491+ ``` typescript
492+ // Get a specific collection
493+ const collection = await repo .hypercerts .getCollection (collectionUri );
494+
495+ // List all collections
496+ const { records } = await repo .hypercerts .listCollections ();
497+
498+ // Get a specific project
499+ const project = await repo .hypercerts .getProject (projectUri );
500+
501+ // List all projects
502+ const { records } = await repo .hypercerts .listProjects ();
503+ ```
504+
505+ #### Updating Collections and Projects
506+
507+ ``` typescript
508+ // Update collection
509+ await repo .hypercerts .updateCollection (collectionUri , {
510+ title: " Updated Title" ,
511+ items: [
512+ /* updated items */
513+ ],
514+ avatar: newAvatarBlob , // or null to remove
515+ });
516+
517+ // Update project (same API)
518+ await repo .hypercerts .updateProject (projectUri , {
519+ shortDescription: " Updated description" ,
520+ banner: null , // removes banner
521+ });
522+ ```
523+
524+ #### Deleting
525+
526+ ``` typescript
527+ // Delete collection
528+ await repo .hypercerts .deleteCollection (collectionUri );
529+
530+ // Delete project
531+ await repo .hypercerts .deleteProject (projectUri );
532+
533+ // Remove location from project
534+ await repo .hypercerts .removeLocationFromProject (projectUri );
535+ ```
536+
537+ ### 6. Blob Operations (Images & Files)
415538
416539``` typescript
417540// Upload an image or file
@@ -422,7 +545,7 @@ console.log("Blob uploaded:", blobResult.ref.$link);
422545const blobData = await repo .blobs .get (" did:plc:user123" , " bafyreiabc123..." );
423546```
424547
425- ### 6 . Organizations (SDS only)
548+ ### 7 . Organizations (SDS only)
426549
427550Organizations allow multiple users to collaborate on shared repositories.
428551
@@ -450,7 +573,7 @@ const org = await repo.organizations.get("did:plc:org123");
450573console .log (` ${org .name } - ${org .description } ` );
451574```
452575
453- ### 7 . Collaborator Management (SDS only)
576+ ### 8 . Collaborator Management (SDS only)
454577
455578Manage who has access to your repository and what they can do.
456579
@@ -519,7 +642,7 @@ await repo.collaborators.transferOwnership({
519642});
520643```
521644
522- ### 8 . Generic Record Operations
645+ ### 9 . Generic Record Operations
523646
524647For working with any ATProto record type:
525648
@@ -564,7 +687,7 @@ const { records, cursor } = await repo.records.list({
564687});
565688```
566689
567- ### 9 . Profile Management (PDS only)
690+ ### 10 . Profile Management (PDS only)
568691
569692``` typescript
570693// Get user profile
@@ -584,40 +707,56 @@ await repo.profile.update({
584707
585708### Repository Operations
586709
587- | Operation | Method | PDS | SDS | Returns |
588- | ------------------ | ---------------------------------------- | --- | --- | ---------------------------- |
589- | ** Records** | | | | |
590- | Create record | ` repo.records.create() ` | ✅ | ✅ | ` { uri, cid } ` |
591- | Get record | ` repo.records.get() ` | ✅ | ✅ | Record data |
592- | Update record | ` repo.records.update() ` | ✅ | ✅ | ` { uri, cid } ` |
593- | Delete record | ` repo.records.delete() ` | ✅ | ✅ | void |
594- | List records | ` repo.records.list() ` | ✅ | ✅ | ` { records, cursor? } ` |
595- | ** Hypercerts** | | | | |
596- | Create hypercert | ` repo.hypercerts.create() ` | ✅ | ✅ | ` { uri, cid, value } ` |
597- | Get hypercert | ` repo.hypercerts.get() ` | ✅ | ✅ | Full hypercert |
598- | Update hypercert | ` repo.hypercerts.update() ` | ✅ | ✅ | ` { uri, cid } ` |
599- | Delete hypercert | ` repo.hypercerts.delete() ` | ✅ | ✅ | void |
600- | List hypercerts | ` repo.hypercerts.list() ` | ✅ | ✅ | ` { records, cursor? } ` |
601- | Add contribution | ` repo.hypercerts.addContribution() ` | ✅ | ✅ | Contribution |
602- | Add measurement | ` repo.hypercerts.addMeasurement() ` | ✅ | ✅ | Measurement |
603- | ** Blobs** | | | | |
604- | Upload blob | ` repo.blobs.upload() ` | ✅ | ✅ | ` { ref, mimeType, size } ` |
605- | Get blob | ` repo.blobs.get() ` | ✅ | ✅ | Blob data |
606- | ** Profile** | | | | |
607- | Get profile | ` repo.profile.get() ` | ✅ | ❌ | Profile data |
608- | Update profile | ` repo.profile.update() ` | ✅ | ❌ | void |
609- | ** Organizations** | | | | |
610- | Create org | ` repo.organizations.create() ` | ❌ | ✅ | ` { did, name, ... } ` |
611- | Get org | ` repo.organizations.get() ` | ❌ | ✅ | Organization |
612- | List orgs | ` repo.organizations.list() ` | ❌ | ✅ | ` { organizations, cursor? } ` |
613- | ** Collaborators** | | | | |
614- | Grant access | ` repo.collaborators.grant() ` | ❌ | ✅ | void |
615- | Revoke access | ` repo.collaborators.revoke() ` | ❌ | ✅ | void |
616- | List collaborators | ` repo.collaborators.list() ` | ❌ | ✅ | ` { collaborators, cursor? } ` |
617- | Check access | ` repo.collaborators.hasAccess() ` | ❌ | ✅ | boolean |
618- | Get role | ` repo.collaborators.getRole() ` | ❌ | ✅ | Role string |
619- | Get permissions | ` repo.collaborators.getPermissions() ` | ❌ | ✅ | Permissions |
620- | Transfer ownership | ` repo.collaborators.transferOwnership() ` | ❌ | ✅ | void |
710+ | Operation | Method | PDS | SDS | Returns |
711+ | ------------------ | ------------------------------------------------ | --- | --- | ---------------------------- |
712+ | ** Records** | | | | |
713+ | Create record | ` repo.records.create() ` | ✅ | ✅ | ` { uri, cid } ` |
714+ | Get record | ` repo.records.get() ` | ✅ | ✅ | Record data |
715+ | Update record | ` repo.records.update() ` | ✅ | ✅ | ` { uri, cid } ` |
716+ | Delete record | ` repo.records.delete() ` | ✅ | ✅ | void |
717+ | List records | ` repo.records.list() ` | ✅ | ✅ | ` { records, cursor? } ` |
718+ | ** Hypercerts** | | | | |
719+ | Create hypercert | ` repo.hypercerts.create() ` | ✅ | ✅ | ` { uri, cid, value } ` |
720+ | Get hypercert | ` repo.hypercerts.get() ` | ✅ | ✅ | Full hypercert |
721+ | Update hypercert | ` repo.hypercerts.update() ` | ✅ | ✅ | ` { uri, cid } ` |
722+ | Delete hypercert | ` repo.hypercerts.delete() ` | ✅ | ✅ | void |
723+ | List hypercerts | ` repo.hypercerts.list() ` | ✅ | ✅ | ` { records, cursor? } ` |
724+ | Add contribution | ` repo.hypercerts.addContribution() ` | ✅ | ✅ | Contribution |
725+ | Add measurement | ` repo.hypercerts.addMeasurement() ` | ✅ | ✅ | Measurement |
726+ | ** Collections** | | | | |
727+ | Create collection | ` repo.hypercerts.createCollection() ` | ✅ | ✅ | ` { uri, cid, locationUri? } ` |
728+ | Get collection | ` repo.hypercerts.getCollection() ` | ✅ | ✅ | Collection data |
729+ | List collections | ` repo.hypercerts.listCollections() ` | ✅ | ✅ | ` { records, cursor? } ` |
730+ | Update collection | ` repo.hypercerts.updateCollection() ` | ✅ | ✅ | ` { uri, cid } ` |
731+ | Delete collection | ` repo.hypercerts.deleteCollection() ` | ✅ | ✅ | void |
732+ | Attach location | ` repo.hypercerts.attachLocationToCollection() ` | ✅ | ✅ | ` { uri, cid } ` |
733+ | Remove location | ` repo.hypercerts.removeLocationFromCollection() ` | ✅ | ✅ | void |
734+ | ** Projects** | | | | |
735+ | Create project | ` repo.hypercerts.createProject() ` | ✅ | ✅ | ` { uri, cid, locationUri? } ` |
736+ | Get project | ` repo.hypercerts.getProject() ` | ✅ | ✅ | Project data |
737+ | List projects | ` repo.hypercerts.listProjects() ` | ✅ | ✅ | ` { records, cursor? } ` |
738+ | Update project | ` repo.hypercerts.updateProject() ` | ✅ | ✅ | ` { uri, cid } ` |
739+ | Delete project | ` repo.hypercerts.deleteProject() ` | ✅ | ✅ | void |
740+ | Attach location | ` repo.hypercerts.attachLocationToProject() ` | ✅ | ✅ | ` { uri, cid } ` |
741+ | Remove location | ` repo.hypercerts.removeLocationFromProject() ` | ✅ | ✅ | void |
742+ | ** Blobs** | | | | |
743+ | Upload blob | ` repo.blobs.upload() ` | ✅ | ✅ | ` { ref, mimeType, size } ` |
744+ | Get blob | ` repo.blobs.get() ` | ✅ | ✅ | Blob data |
745+ | ** Profile** | | | | |
746+ | Get profile | ` repo.profile.get() ` | ✅ | ❌ | Profile data |
747+ | Update profile | ` repo.profile.update() ` | ✅ | ❌ | void |
748+ | ** Organizations** | | | | |
749+ | Create org | ` repo.organizations.create() ` | ❌ | ✅ | ` { did, name, ... } ` |
750+ | Get org | ` repo.organizations.get() ` | ❌ | ✅ | Organization |
751+ | List orgs | ` repo.organizations.list() ` | ❌ | ✅ | ` { organizations, cursor? } ` |
752+ | ** Collaborators** | | | | |
753+ | Grant access | ` repo.collaborators.grant() ` | ❌ | ✅ | void |
754+ | Revoke access | ` repo.collaborators.revoke() ` | ❌ | ✅ | void |
755+ | List collaborators | ` repo.collaborators.list() ` | ❌ | ✅ | ` { collaborators, cursor? } ` |
756+ | Check access | ` repo.collaborators.hasAccess() ` | ❌ | ✅ | boolean |
757+ | Get role | ` repo.collaborators.getRole() ` | ❌ | ✅ | Role string |
758+ | Get permissions | ` repo.collaborators.getPermissions() ` | ❌ | ✅ | Permissions |
759+ | Transfer ownership | ` repo.collaborators.transferOwnership() ` | ❌ | ✅ | void |
621760
622761## Type System
623762
0 commit comments