@hypercerts-org/sdk-core 0.7.0-beta.0 → 0.9.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 +125 -8
- package/dist/index.cjs +40 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -8
- package/dist/index.mjs +40 -12
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +13 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,11 +33,15 @@ const session = await sdk.callback(callbackParams);
|
|
|
33
33
|
const repo = sdk.getRepository(session);
|
|
34
34
|
const claim = await repo.hypercerts.create({
|
|
35
35
|
title: "Tree Planting Initiative 2025",
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
shortDescription: "1000 trees planted in rainforest",
|
|
37
|
+
description: "Planted 1000 trees in the Amazon rainforest region",
|
|
38
|
+
workScope: "Environmental Conservation",
|
|
39
|
+
workTimeFrameFrom: "2025-01-01T00:00:00Z",
|
|
40
|
+
workTimeFrameTo: "2025-12-31T23:59:59Z",
|
|
41
|
+
rights: {
|
|
42
|
+
name: "Attribution",
|
|
43
|
+
type: "license",
|
|
44
|
+
description: "CC-BY-4.0",
|
|
41
45
|
},
|
|
42
46
|
});
|
|
43
47
|
```
|
|
@@ -607,21 +611,134 @@ await mockStore.set(mockSession);
|
|
|
607
611
|
|
|
608
612
|
### Working with Lexicons
|
|
609
613
|
|
|
614
|
+
The SDK exports lexicon types and validation utilities from the `@hypercerts-org/lexicon` package for direct record manipulation and validation.
|
|
615
|
+
|
|
616
|
+
#### Lexicon Types
|
|
617
|
+
|
|
618
|
+
All lexicon types are available with proper TypeScript support:
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
import type {
|
|
622
|
+
HypercertClaim,
|
|
623
|
+
HypercertRights,
|
|
624
|
+
HypercertContribution,
|
|
625
|
+
HypercertCollection,
|
|
626
|
+
HypercertMeasurement,
|
|
627
|
+
HypercertEvaluation,
|
|
628
|
+
HypercertLocation,
|
|
629
|
+
StrongRef,
|
|
630
|
+
} from "@hypercerts-org/sdk-core";
|
|
631
|
+
|
|
632
|
+
// Create a properly typed hypercert claim
|
|
633
|
+
const claim: HypercertClaim = {
|
|
634
|
+
$type: "org.hypercerts.claim",
|
|
635
|
+
title: "Community Garden Project",
|
|
636
|
+
shortDescription: "Urban garden serving 50 families", // REQUIRED
|
|
637
|
+
description: "Detailed description...",
|
|
638
|
+
workScope: "Food Security",
|
|
639
|
+
workTimeFrameFrom: "2024-01-01T00:00:00Z", // Note: Capital 'F'
|
|
640
|
+
workTimeFrameTo: "2024-12-31T00:00:00Z", // Note: Capital 'F'
|
|
641
|
+
rights: { uri: "at://...", cid: "..." },
|
|
642
|
+
createdAt: new Date().toISOString(),
|
|
643
|
+
};
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
#### Validation
|
|
647
|
+
|
|
648
|
+
Validate records before creating them:
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
import {
|
|
652
|
+
validate,
|
|
653
|
+
OrgHypercertsClaim,
|
|
654
|
+
HYPERCERT_COLLECTIONS,
|
|
655
|
+
} from "@hypercerts-org/sdk-core";
|
|
656
|
+
|
|
657
|
+
// Validate using the lexicon package
|
|
658
|
+
const validation = validate(
|
|
659
|
+
HYPERCERT_COLLECTIONS.CLAIM, // "org.hypercerts.claim"
|
|
660
|
+
claim
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
if (!validation.valid) {
|
|
664
|
+
console.error("Validation failed:", validation.error);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Or use type-specific validators
|
|
668
|
+
const isValid = OrgHypercertsClaim.isMain(claim);
|
|
669
|
+
const validationResult = OrgHypercertsClaim.validateMain(claim);
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
#### Using LexiconRegistry
|
|
673
|
+
|
|
674
|
+
For repository-level validation:
|
|
675
|
+
|
|
610
676
|
```typescript
|
|
611
677
|
import {
|
|
612
678
|
LexiconRegistry,
|
|
613
679
|
HYPERCERT_LEXICONS,
|
|
614
680
|
HYPERCERT_COLLECTIONS,
|
|
615
|
-
} from "@hypercerts-org/sdk-core
|
|
681
|
+
} from "@hypercerts-org/sdk-core";
|
|
616
682
|
|
|
617
683
|
const registry = new LexiconRegistry();
|
|
618
684
|
registry.registerLexicons(HYPERCERT_LEXICONS);
|
|
619
685
|
|
|
620
686
|
// Validate a record
|
|
621
|
-
const
|
|
622
|
-
|
|
687
|
+
const result = registry.validate(
|
|
688
|
+
HYPERCERT_COLLECTIONS.CLAIM,
|
|
623
689
|
claimData
|
|
624
690
|
);
|
|
691
|
+
|
|
692
|
+
if (!result.valid) {
|
|
693
|
+
console.error("Invalid record:", result.error);
|
|
694
|
+
}
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
#### Creating Records with Proper Types
|
|
698
|
+
|
|
699
|
+
```typescript
|
|
700
|
+
import type {
|
|
701
|
+
HypercertContribution,
|
|
702
|
+
StrongRef,
|
|
703
|
+
} from "@hypercerts-org/sdk-core";
|
|
704
|
+
import { HYPERCERT_COLLECTIONS } from "@hypercerts-org/sdk-core";
|
|
705
|
+
|
|
706
|
+
// Create a contribution record
|
|
707
|
+
const contribution: HypercertContribution = {
|
|
708
|
+
$type: HYPERCERT_COLLECTIONS.CONTRIBUTION,
|
|
709
|
+
hypercert: {
|
|
710
|
+
uri: "at://did:plc:abc/org.hypercerts.claim/xyz",
|
|
711
|
+
cid: "bafyrei...",
|
|
712
|
+
} as StrongRef,
|
|
713
|
+
contributors: ["did:plc:contributor1", "did:plc:contributor2"],
|
|
714
|
+
role: "implementer",
|
|
715
|
+
description: "On-ground implementation team",
|
|
716
|
+
workTimeframeFrom: "2024-01-01T00:00:00Z", // Note: lowercase 'f' for contributions
|
|
717
|
+
workTimeframeTo: "2024-06-30T00:00:00Z", // Note: lowercase 'f' for contributions
|
|
718
|
+
createdAt: new Date().toISOString(),
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// Use with repository operations
|
|
722
|
+
await repo.records.create({
|
|
723
|
+
collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,
|
|
724
|
+
record: contribution,
|
|
725
|
+
});
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
#### Available Lexicon Collections
|
|
729
|
+
|
|
730
|
+
```typescript
|
|
731
|
+
import { HYPERCERT_COLLECTIONS } from "@hypercerts-org/sdk-core";
|
|
732
|
+
|
|
733
|
+
// Collection NSIDs
|
|
734
|
+
HYPERCERT_COLLECTIONS.CLAIM // "org.hypercerts.claim"
|
|
735
|
+
HYPERCERT_COLLECTIONS.RIGHTS // "org.hypercerts.claim.rights"
|
|
736
|
+
HYPERCERT_COLLECTIONS.CONTRIBUTION // "org.hypercerts.claim.contribution"
|
|
737
|
+
HYPERCERT_COLLECTIONS.MEASUREMENT // "org.hypercerts.claim.measurement"
|
|
738
|
+
HYPERCERT_COLLECTIONS.EVALUATION // "org.hypercerts.claim.evaluation"
|
|
739
|
+
HYPERCERT_COLLECTIONS.EVIDENCE // "org.hypercerts.claim.evidence"
|
|
740
|
+
HYPERCERT_COLLECTIONS.COLLECTION // "org.hypercerts.collection"
|
|
741
|
+
HYPERCERT_COLLECTIONS.LOCATION // "app.certified.location"
|
|
625
742
|
```
|
|
626
743
|
|
|
627
744
|
## Development
|
package/dist/index.cjs
CHANGED
|
@@ -2270,6 +2270,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2270
2270
|
// Step 2: Create rights record
|
|
2271
2271
|
this.emitProgress(params.onProgress, { name: "createRights", status: "start" });
|
|
2272
2272
|
const rightsRecord = {
|
|
2273
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.RIGHTS,
|
|
2273
2274
|
rightsName: params.rights.name,
|
|
2274
2275
|
rightsType: params.rights.type,
|
|
2275
2276
|
rightsDescription: params.rights.description,
|
|
@@ -2298,17 +2299,16 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2298
2299
|
// Step 3: Create hypercert record
|
|
2299
2300
|
this.emitProgress(params.onProgress, { name: "createHypercert", status: "start" });
|
|
2300
2301
|
const hypercertRecord = {
|
|
2302
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.CLAIM,
|
|
2301
2303
|
title: params.title,
|
|
2304
|
+
shortDescription: params.shortDescription,
|
|
2302
2305
|
description: params.description,
|
|
2303
2306
|
workScope: params.workScope,
|
|
2304
|
-
|
|
2305
|
-
|
|
2307
|
+
workTimeFrameFrom: params.workTimeFrameFrom,
|
|
2308
|
+
workTimeFrameTo: params.workTimeFrameTo,
|
|
2306
2309
|
rights: { uri: result.rightsUri, cid: result.rightsCid },
|
|
2307
2310
|
createdAt,
|
|
2308
2311
|
};
|
|
2309
|
-
if (params.shortDescription) {
|
|
2310
|
-
hypercertRecord.shortDescription = params.shortDescription;
|
|
2311
|
-
}
|
|
2312
2312
|
if (imageBlobRef) {
|
|
2313
2313
|
hypercertRecord.image = imageBlobRef;
|
|
2314
2314
|
}
|
|
@@ -2645,6 +2645,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2645
2645
|
* await repo.hypercerts.attachLocation(hypercertUri, {
|
|
2646
2646
|
* value: "San Francisco, CA",
|
|
2647
2647
|
* name: "SF Bay Area",
|
|
2648
|
+
* srs: "EPSG:4326",
|
|
2648
2649
|
* });
|
|
2649
2650
|
* ```
|
|
2650
2651
|
*
|
|
@@ -2663,32 +2664,54 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2663
2664
|
*/
|
|
2664
2665
|
async attachLocation(hypercertUri, location) {
|
|
2665
2666
|
try {
|
|
2666
|
-
//
|
|
2667
|
-
|
|
2667
|
+
// Validate required srs field
|
|
2668
|
+
if (!location.srs) {
|
|
2669
|
+
throw new ValidationError("srs (Spatial Reference System) is required. Example: 'EPSG:4326' for WGS84 coordinates, or 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' for CRS84.");
|
|
2670
|
+
}
|
|
2671
|
+
// Validate that hypercert exists (unused but confirms hypercert is valid)
|
|
2672
|
+
await this.get(hypercertUri);
|
|
2668
2673
|
const createdAt = new Date().toISOString();
|
|
2669
|
-
|
|
2674
|
+
// Determine location type and prepare location data
|
|
2675
|
+
let locationData;
|
|
2676
|
+
let locationType;
|
|
2670
2677
|
if (location.geojson) {
|
|
2678
|
+
// Upload GeoJSON as a blob
|
|
2671
2679
|
const arrayBuffer = await location.geojson.arrayBuffer();
|
|
2672
2680
|
const uint8Array = new Uint8Array(arrayBuffer);
|
|
2673
2681
|
const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {
|
|
2674
2682
|
encoding: location.geojson.type || "application/geo+json",
|
|
2675
2683
|
});
|
|
2676
2684
|
if (uploadResult.success) {
|
|
2677
|
-
|
|
2685
|
+
locationData = {
|
|
2678
2686
|
$type: "blob",
|
|
2679
2687
|
ref: { $link: uploadResult.data.blob.ref.toString() },
|
|
2680
2688
|
mimeType: uploadResult.data.blob.mimeType,
|
|
2681
2689
|
size: uploadResult.data.blob.size,
|
|
2682
2690
|
};
|
|
2691
|
+
locationType = "geojson-point";
|
|
2692
|
+
}
|
|
2693
|
+
else {
|
|
2694
|
+
throw new NetworkError("Failed to upload GeoJSON blob");
|
|
2683
2695
|
}
|
|
2684
2696
|
}
|
|
2697
|
+
else {
|
|
2698
|
+
// Use value as a URI reference
|
|
2699
|
+
locationData = {
|
|
2700
|
+
$type: "app.certified.defs#uri",
|
|
2701
|
+
uri: location.value,
|
|
2702
|
+
};
|
|
2703
|
+
locationType = "coordinate-decimal";
|
|
2704
|
+
}
|
|
2705
|
+
// Build location record according to app.certified.location lexicon
|
|
2685
2706
|
const locationRecord = {
|
|
2686
|
-
|
|
2687
|
-
|
|
2707
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.LOCATION,
|
|
2708
|
+
lpVersion: "1.0",
|
|
2709
|
+
srs: location.srs,
|
|
2710
|
+
locationType,
|
|
2711
|
+
location: locationData,
|
|
2688
2712
|
createdAt,
|
|
2689
2713
|
name: location.name,
|
|
2690
2714
|
description: location.description,
|
|
2691
|
-
srs: location.srs,
|
|
2692
2715
|
};
|
|
2693
2716
|
const validation = this.lexiconRegistry.validate(lexicon.HYPERCERT_COLLECTIONS.LOCATION, locationRecord);
|
|
2694
2717
|
if (!validation.valid) {
|
|
@@ -2775,10 +2798,12 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2775
2798
|
try {
|
|
2776
2799
|
const createdAt = new Date().toISOString();
|
|
2777
2800
|
const contributionRecord = {
|
|
2801
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.CONTRIBUTION,
|
|
2778
2802
|
contributors: params.contributors,
|
|
2779
2803
|
role: params.role,
|
|
2780
2804
|
createdAt,
|
|
2781
2805
|
description: params.description,
|
|
2806
|
+
hypercert: { uri: "", cid: "" }, // Will be set below if hypercertUri provided
|
|
2782
2807
|
};
|
|
2783
2808
|
if (params.hypercertUri) {
|
|
2784
2809
|
const hypercert = await this.get(params.hypercertUri);
|
|
@@ -2839,6 +2864,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2839
2864
|
const hypercert = await this.get(params.hypercertUri);
|
|
2840
2865
|
const createdAt = new Date().toISOString();
|
|
2841
2866
|
const measurementRecord = {
|
|
2867
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.MEASUREMENT,
|
|
2842
2868
|
hypercert: { uri: hypercert.uri, cid: hypercert.cid },
|
|
2843
2869
|
measurers: params.measurers,
|
|
2844
2870
|
metric: params.metric,
|
|
@@ -2894,6 +2920,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2894
2920
|
const subject = await this.get(params.subjectUri);
|
|
2895
2921
|
const createdAt = new Date().toISOString();
|
|
2896
2922
|
const evaluationRecord = {
|
|
2923
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.EVALUATION,
|
|
2897
2924
|
subject: { uri: subject.uri, cid: subject.cid },
|
|
2898
2925
|
evaluators: params.evaluators,
|
|
2899
2926
|
summary: params.summary,
|
|
@@ -2968,6 +2995,7 @@ class HypercertOperationsImpl extends eventemitter3.EventEmitter {
|
|
|
2968
2995
|
}
|
|
2969
2996
|
}
|
|
2970
2997
|
const collectionRecord = {
|
|
2998
|
+
$type: lexicon.HYPERCERT_COLLECTIONS.COLLECTION,
|
|
2971
2999
|
title: params.title,
|
|
2972
3000
|
claims: params.claims.map((c) => ({ claim: { uri: c.uri, cid: c.cid }, weight: c.weight })),
|
|
2973
3001
|
createdAt,
|