Skip to content

Commit ea9a720

Browse files
authored
Merge pull request #64 from hypercerts-org/fix/lexicon_fields
Correct field names and required types to match schema
2 parents 5087c83 + f83f03a commit ea9a720

File tree

11 files changed

+198
-70
lines changed

11 files changed

+198
-70
lines changed

.changeset/fix-lexicon-fields.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@hypercerts-org/sdk-core": patch
3+
"@hypercerts-org/sdk-react": patch
4+
---
5+
6+
fix(lexicon): correct field names and types to match lexicon schema
7+
8+
- Fix `workTimeframeFrom/To` -> `workTimeFrameFrom/To` (capital 'F' in Frame)
9+
- Make `shortDescription` required for hypercert claims per lexicon schema
10+
- Update all interfaces, implementations, and tests to use correct field names
11+
- Add comprehensive lexicon documentation to README

packages/lexicon/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hypercerts-org/lexicon",
3-
"version": "0.7.0",
3+
"version": "0.8.0",
44
"description": "ATProto lexicon definitions and TypeScript types for the Hypercerts protocol",
55
"type": "module",
66
"main": "dist/index.cjs",

packages/sdk-core/README.md

Lines changed: 125 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@ const session = await sdk.callback(callbackParams);
3333
const repo = sdk.getRepository(session);
3434
const claim = await repo.hypercerts.create({
3535
title: "Tree Planting Initiative 2025",
36-
description: "Planted 1000 trees in the rainforest",
37-
impact: {
38-
scope: ["Environmental Conservation"],
39-
work: { from: "2025-01-01", to: "2025-12-31" },
40-
contributors: ["did:plc:contributor1"],
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",
4145
},
4246
});
4347
```
@@ -607,21 +611,134 @@ await mockStore.set(mockSession);
607611

608612
### Working with Lexicons
609613

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+
610676
```typescript
611677
import {
612678
LexiconRegistry,
613679
HYPERCERT_LEXICONS,
614680
HYPERCERT_COLLECTIONS,
615-
} from "@hypercerts-org/sdk-core/lexicons";
681+
} from "@hypercerts-org/sdk-core";
616682

617683
const registry = new LexiconRegistry();
618684
registry.registerLexicons(HYPERCERT_LEXICONS);
619685

620686
// Validate a record
621-
const isValid = registry.validate(
622-
"org.hypercerts.claim",
687+
const result = registry.validate(
688+
HYPERCERT_COLLECTIONS.CLAIM,
623689
claimData
624690
);
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"
625742
```
626743

627744
## Development

packages/sdk-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hypercerts-org/sdk-core",
3-
"version": "0.7.0",
3+
"version": "0.8.0",
44
"description": "Framework-agnostic ATProto SDK core for authentication, repository operations, and lexicon management",
55
"main": "dist/index.cjs",
66
"repository": {

packages/sdk-core/src/repository/HypercertOperationsImpl.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,18 +266,15 @@ export class HypercertOperationsImpl extends EventEmitter<HypercertEvents> imple
266266
const hypercertRecord: Record<string, unknown> = {
267267
$type: HYPERCERT_COLLECTIONS.CLAIM,
268268
title: params.title,
269+
shortDescription: params.shortDescription,
269270
description: params.description,
270271
workScope: params.workScope,
271-
workTimeframeFrom: params.workTimeframeFrom,
272-
workTimeframeTo: params.workTimeframeTo,
272+
workTimeFrameFrom: params.workTimeFrameFrom,
273+
workTimeFrameTo: params.workTimeFrameTo,
273274
rights: { uri: result.rightsUri, cid: result.rightsCid },
274275
createdAt,
275276
};
276277

277-
if (params.shortDescription) {
278-
hypercertRecord.shortDescription = params.shortDescription;
279-
}
280-
281278
if (imageBlobRef) {
282279
hypercertRecord.image = imageBlobRef;
283280
}

packages/sdk-core/src/repository/interfaces.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ export interface CreateHypercertParams {
117117
*
118118
* ISO 8601 date format (YYYY-MM-DD).
119119
*/
120-
workTimeframeFrom: string;
120+
workTimeFrameFrom: string;
121121

122122
/**
123123
* End date of the work period.
124124
*
125125
* ISO 8601 date format (YYYY-MM-DD).
126126
*/
127-
workTimeframeTo: string;
127+
workTimeFrameTo: string;
128128

129129
/**
130130
* Rights associated with the hypercert.
@@ -153,11 +153,11 @@ export interface CreateHypercertParams {
153153
};
154154

155155
/**
156-
* Optional short description for display in lists/cards.
156+
* Short description for display in lists/cards.
157157
*
158-
* Should be under 200 characters.
158+
* Required field. Should be under 300 characters.
159159
*/
160-
shortDescription?: string;
160+
shortDescription: string;
161161

162162
/**
163163
* Optional cover image for the hypercert.

packages/sdk-core/tests/repository/HypercertOperationsImpl.test.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ describe("HypercertOperationsImpl", () => {
3838
describe("create", () => {
3939
const validParams = {
4040
title: "Test Hypercert",
41+
shortDescription: "A test hypercert",
4142
description: "A test hypercert for unit testing",
4243
workScope: "Testing",
43-
workTimeframeFrom: "2024-01-01T00:00:00Z",
44-
workTimeframeTo: "2024-12-31T23:59:59Z",
44+
workTimeFrameFrom: "2024-01-01T00:00:00Z",
45+
workTimeFrameTo: "2024-12-31T23:59:59Z",
4546
rights: {
4647
name: "Attribution",
4748
type: "CC-BY-4.0",
@@ -138,8 +139,8 @@ describe("HypercertOperationsImpl", () => {
138139
title: "Test",
139140
description: "Test",
140141
workScope: "Test",
141-
workTimeframeFrom: "2024-01-01",
142-
workTimeframeTo: "2024-12-31",
142+
workTimeFrameFrom: "2024-01-01",
143+
workTimeFrameTo: "2024-12-31",
143144
createdAt: "2024-01-01",
144145
},
145146
},
@@ -178,8 +179,8 @@ describe("HypercertOperationsImpl", () => {
178179
title: "Test",
179180
description: "Test",
180181
workScope: "Test",
181-
workTimeframeFrom: "2024-01-01",
182-
workTimeframeTo: "2024-12-31",
182+
workTimeFrameFrom: "2024-01-01",
183+
workTimeFrameTo: "2024-12-31",
183184
createdAt: "2024-01-01",
184185
},
185186
},
@@ -337,8 +338,8 @@ describe("HypercertOperationsImpl", () => {
337338
title: "Old Title",
338339
description: "Old description",
339340
workScope: "Old scope",
340-
workTimeframeFrom: "2024-01-01",
341-
workTimeframeTo: "2024-12-31",
341+
workTimeFrameFrom: "2024-01-01",
342+
workTimeFrameTo: "2024-12-31",
342343
createdAt: "2024-01-01T00:00:00Z",
343344
rights: { uri: "at://rights", cid: "rights-cid" },
344345
},
@@ -403,8 +404,8 @@ describe("HypercertOperationsImpl", () => {
403404
title: "Title",
404405
description: "Desc",
405406
workScope: "Scope",
406-
workTimeframeFrom: "2024-01-01",
407-
workTimeframeTo: "2024-12-31",
407+
workTimeFrameFrom: "2024-01-01",
408+
workTimeFrameTo: "2024-12-31",
408409
createdAt: "2024-01-01",
409410
rights: { uri: "at://rights", cid: "cid" },
410411
image: { ref: { $link: "old-image" } },
@@ -462,8 +463,8 @@ describe("HypercertOperationsImpl", () => {
462463
title: "Test",
463464
description: "Test",
464465
workScope: "Test",
465-
workTimeframeFrom: "2024-01-01",
466-
workTimeframeTo: "2024-12-31",
466+
workTimeFrameFrom: "2024-01-01",
467+
workTimeFrameTo: "2024-12-31",
467468
createdAt: "2024-01-01",
468469
},
469470
},
@@ -519,8 +520,8 @@ describe("HypercertOperationsImpl", () => {
519520
title: "Test",
520521
description: "Test",
521522
workScope: "Test",
522-
workTimeframeFrom: "2024-01-01",
523-
workTimeframeTo: "2024-12-31",
523+
workTimeFrameFrom: "2024-01-01",
524+
workTimeFrameTo: "2024-12-31",
524525
createdAt: "2024-01-01",
525526
},
526527
},
@@ -555,8 +556,8 @@ describe("HypercertOperationsImpl", () => {
555556
title: "Test",
556557
description: "Test",
557558
workScope: "Test",
558-
workTimeframeFrom: "2024-01-01",
559-
workTimeframeTo: "2024-12-31",
559+
workTimeFrameFrom: "2024-01-01",
560+
workTimeFrameTo: "2024-12-31",
560561
createdAt: "2024-01-01",
561562
},
562563
},

packages/sdk-react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hypercerts-org/sdk-react",
3-
"version": "0.7.0",
3+
"version": "0.8.0",
44
"description": "React hooks and components for the Hypercerts ATProto SDK",
55
"type": "module",
66
"main": "dist/index.cjs",

packages/sdk-react/src/hooks/useHypercerts.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ const DEFAULT_LIMIT = 50;
5353
* const handleSubmit = async (data) => {
5454
* const result = await create({
5555
* title: data.title,
56+
* shortDescription: data.shortDesc,
5657
* description: data.description,
5758
* workScope: data.workScope,
58-
* workTimeframeFrom: data.startDate,
59-
* workTimeframeTo: data.endDate,
59+
* workTimeFrameFrom: data.startDate,
60+
* workTimeFrameTo: data.endDate,
6061
* rights: {
6162
* name: "CC-BY-4.0",
6263
* type: "license",

0 commit comments

Comments
 (0)