Skip to content

Commit 26526cf

Browse files
authored
Merge pull request #101 from aspiers/add-location
2 parents 604a4c9 + bf93b3c commit 26526cf

18 files changed

Lines changed: 1438 additions & 596 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
"@hypercerts-org/sdk-core": minor
3+
---
4+
5+
feat: align collection/project types with lexicon + add inline location support
6+
7+
This is a BREAKING change.
8+
9+
**Type Alignment with Lexicon:**
10+
11+
- Changed `createCollection` to use lexicon-aligned `items` array instead of `claims`
12+
- Updated avatar/banner handling to use proper lexicon union types
13+
- Simplified project methods to delegate to collection methods
14+
- Added `CreateCollectionParams`, `UpdateCollectionParams`, and result types derived from lexicon
15+
- Improved type safety by deriving SDK input types from lexicon definitions
16+
17+
**Inline Location Support:**
18+
19+
`AttachLocationParams` now supports three ways to specify location:
20+
21+
1. **StrongRef** - Direct reference with uri and cid (no record creation)
22+
2. **AT-URI string** - Reference to existing location record
23+
3. **Location object** - Full location data to create a new location record
24+
25+
**Changes:**
26+
27+
- Add `AttachLocationParams` union type supporting StrongRef, string URI, or location object
28+
- Add optional `location` field to `CreateCollectionParams`
29+
- Add optional `location` field to `UpdateCollectionParams` (supports `null` to remove)
30+
- Update `CreateCollectionResult` to include optional `locationUri` field
31+
- Implement location handling in `createCollection()` - supports all three forms
32+
- Add tests for collection creation with StrongRef, string URI, and location object
33+
34+
**Example Usage:**
35+
36+
```typescript
37+
// Create a project with location (StrongRef - direct reference)
38+
const project = await repo.hypercerts.createProject({
39+
title: "Climate Initiative",
40+
items: [...],
41+
location: { uri: "at://did:plc:alice/app.certified.location/abc", cid: "bafy..." },
42+
});
43+
44+
// Create with location (AT-URI string - fetches CID)
45+
const project2 = await repo.hypercerts.createProject({
46+
title: "Forest Project",
47+
items: [...],
48+
location: "at://did:plc:bob/app.certified.location/xyz",
49+
});
50+
51+
// Create with location (location object - creates new record)
52+
const project3 = await repo.hypercerts.createProject({
53+
title: "Ocean Project",
54+
items: [...],
55+
location: {
56+
lpVersion: "1.0",
57+
srs: "EPSG:4326",
58+
locationType: "coordinate-decimal",
59+
location: "37.7749, -122.4194",
60+
},
61+
});
62+
63+
// Update project to change location
64+
await repo.hypercerts.updateProject(project.uri, {
65+
location: "at://did:plc:alice/app.certified.location/new",
66+
});
67+
68+
// Remove location
69+
await repo.hypercerts.updateProject(project.uri, {
70+
location: null,
71+
});
72+
```

.claude/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"Bash(pnpm lint:*)",
88
"Bash(pnpm test:*)",
99
"Bash(pnpm typecheck:*)"
10-
]
10+
],
11+
"deny": ["Bash(npm:*)", "Bash(yarn:*)"]
1112
}
1213
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
name: writing-changesets
3+
description:
4+
Create changeset files for user-facing changes. Use when making API changes, modifying types, adding features, or any
5+
change that affects package consumers.
6+
---
7+
8+
# Writing Changesets
9+
10+
Create a changeset file to document user-facing changes for release.
11+
12+
## When to Use
13+
14+
Add a changeset when making changes that affect consumers:
15+
16+
- Adding new SDK methods or operations (createProject, addEvidence, etc.)
17+
- Modifying existing API signatures (breaking or non-breaking)
18+
- Changing TypeScript type exports or interfaces
19+
- Adding new React hooks or components
20+
- Renaming any exported constants, types, functions, or hooks
21+
- Changing behavior of existing operations
22+
- Bug fixes that affect external behavior
23+
- Any change that requires a version bump or affects package consumers
24+
25+
Skip changesets for internal changes (build scripts, tests, refactoring, documentation only).
26+
27+
## Packages
28+
29+
The SDK has two publishable packages:
30+
31+
- `@hypercerts-org/sdk-core` - Core SDK
32+
- `@hypercerts-org/sdk-react` - React hooks etc.
33+
34+
## Format
35+
36+
Create in `.changeset/` a Markdown file with a descriptive kebab-case name (e.g., `fix-collection-type-alignment.md`) in
37+
this format:
38+
39+
```markdown
40+
---
41+
"@hypercerts-org/sdk-core": minor
42+
---
43+
44+
Align collection/project CRUD types with lexicon definitions
45+
```
46+
47+
For changes affecting both packages:
48+
49+
```markdown
50+
---
51+
"@hypercerts-org/sdk-core": minor
52+
"@hypercerts-org/sdk-react": minor
53+
---
54+
55+
Add comprehensive project support to SDK
56+
57+
**Core SDK (`@hypercerts-org/sdk-core`):**
58+
59+
- Add project CRUD operations (createProject, getProject, listProjects)
60+
- Add project events (projectCreated, projectUpdated, projectDeleted)
61+
- Support for avatar and banner blob uploads
62+
63+
**React SDK (`@hypercerts-org/sdk-react`):**
64+
65+
- Add useProjects and useProject hooks
66+
- Project query keys for cache management
67+
- TypeScript types for projects
68+
```
69+
70+
### Frontmatter Fields
71+
72+
There should be a frontmatter field for each package being changed. The field name should be the package name, and the
73+
field value should be one of the following change types:
74+
75+
- `patch` - Bug fixes, non-breaking changes
76+
- `minor` - New features, non-breaking additions (also breaking changes if the version in `package.json` is still 0.x.y)
77+
- `major` - Breaking changes (_ONLY_ use if the version in `package.json` is already greater than 0.x.y)
78+
79+
**Current versions are 0.x.y, so use `minor` for breaking changes.**
80+
81+
### Description
82+
83+
In the body after the frontmatter field(s), write a clear, concise description following conventional commit style.
84+
Focus on what changed and why. For multi-package changes, use sections to separate changes.
85+
86+
## Example Changesets
87+
88+
**New SDK feature:**
89+
90+
```markdown
91+
---
92+
"@hypercerts-org/sdk-core": minor
93+
---
94+
95+
Add project CRUD operations to repository interface
96+
```
97+
98+
**API signature change:**
99+
100+
```markdown
101+
---
102+
"@hypercerts-org/sdk-core": minor
103+
---
104+
105+
Evidence records are now created separately instead of being embedded inline in hypercerts
106+
107+
**Breaking Changes:**
108+
109+
- Evidence is no longer embedded in the hypercert record - use `result.evidenceUris` to access evidence record URIs
110+
- `addEvidence()` now accepts a single `CreateHypercertEvidenceParams` object instead of
111+
`(uri: string, evidence: HypercertEvidence[])`
112+
```
113+
114+
**Type/interface change:**
115+
116+
```markdown
117+
---
118+
"@hypercerts-org/sdk-core": minor
119+
---
120+
121+
Align collection/project CRUD types with lexicon definitions
122+
123+
- Update CreateCollectionParams to match lexicon schema
124+
- Add CreateCollectionResult type with optional location URI
125+
- Simplify project operations to delegate to collection operations
126+
```
127+
128+
**React hook addition:**
129+
130+
```markdown
131+
---
132+
"@hypercerts-org/sdk-react": minor
133+
---
134+
135+
Add useProjects and useProject hooks for project management
136+
```
137+
138+
**Bug fix:**
139+
140+
```markdown
141+
---
142+
"@hypercerts-org/sdk-core": patch
143+
---
144+
145+
Fix SDS routing for organization endpoints
146+
```
147+
148+
## Key Files
149+
150+
- `.changeset/config.json` - Changeset configuration
151+
- Existing changeset files in `.changeset/` - Reference for naming and format
152+
- `package.json` - Contains version and release scripts
153+
- `packages/sdk-core/package.json` - Core SDK version
154+
- `packages/sdk-react/package.json` - React SDK version

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ yarn-error.log*
2222
/.idea
2323
stats.html
2424
coverage/
25-
.npmrc
25+
.npmrc
26+
tmp/

AGENTS.md

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,38 @@ Use the error hierarchy in `sdk-core/src/core/errors.ts`:
217217
- Test files: `*.test.ts` in `tests/` directory
218218
- Use fixtures from `tests/utils/fixtures.ts`
219219

220+
### SDK Type Design Principles
221+
222+
- Types like `HypercertClaim` should always be used rather than underlying types like `OrgHypercertsClaimActivity.Main`
223+
which are exported from the lexicons package
224+
225+
- Whenever an SDK method creates a record, there should be a corresponding type like `CreateCollectionParams` defined,
226+
which is derived from `HypercertCollection`, but with `$type` and `createdAt` made optional. Then the method should
227+
ensure that those are auto-populated if missing.
228+
229+
- For any methods which can refer to a _potentially_ existing record, e.g. update methods or attach methods like
230+
`attachLocationToProject()`, then the user should be able to reference that object in three different ways:
231+
1. provide an AT-URI pointing to an existing record
232+
2. provide a StrongRef pointing to an existing record
233+
3. provide an object of a type named like `Create*Params` where \* can be Collection / Activity etc. as appropriate
234+
235+
These possibilities should be a union type called something like `CollectionParams`.
236+
237+
- There should also be types like `UpdateCollectionParams` which should be a `Partial` allowing the update methods to
238+
perform selective updates on just some parts of the record.
239+
240+
- So in summary, for each lexicon entity type, there should be five types, e.g. for the `org.hypercerts.claim.rights`
241+
lexicon there should be:
242+
1. `OrgHypercertsClaimRights.Main` (from the lexicon package)
243+
2. `HypercertRights` - the same as 1, as syntactic sugar defined by the SDK. These should all be defined in the same
244+
place in the same file.
245+
3. `CreateRightsParams` - `SetOptional<HypercertRights, "$type" | "createdAt">` should be the basis for this
246+
definition. However if the lexicon contains strongRefs to other lexicons, this should be further wrapped with
247+
`OverrideProperties` from the `type-fest` package to replace any nested objects with the equivalent `Create*Params`
248+
type, so that creation of multiple records can be achieved by calling a single create method for the main record.
249+
4. `UpdateRightsParams` - `Partial<CreateRightsParams>`
250+
5. `RightsParams` - union type `string | StrongRef | CreateRightsParams`
251+
220252
## Build Output
221253

222254
### sdk-core
@@ -247,23 +279,33 @@ Each entrypoint outputs:
247279

248280
Uses [Changesets](https://github.com/changesets/changesets) for versioning.
249281

250-
**Flow:** `feature``develop` (beta) → `main` (stable)
282+
**Branch flow:** `feature``develop` (beta) → `main` (stable)
251283

252-
### Commands
284+
### Creating Changesets
253285

254-
```bash
255-
pnpm changeset # Add changeset (required for package changes)
256-
pnpm version-packages # Apply changesets locally
257-
pnpm release # Build and publish
258-
```
286+
**REQUIRED: All user-facing changes must include a changeset.**
287+
288+
To create a changeset, use the `writing-changesets` skill.
289+
290+
**The skill is the single source of truth for:**
291+
292+
- When changesets are required vs optional
293+
- How to format changeset files correctly
294+
- Which packages to include in the frontmatter
295+
- Changeset type selection (patch/minor/major)
296+
- Examples for different types of changes
297+
298+
Do not attempt to create changesets without consulting this skill first.
259299

260-
### Branches
300+
### Release Branches
261301

262302
- **develop**: Auto-publishes `@beta` tag (e.g., `0.2.0-beta.0`)
263303
- **main**: Creates Release PR → merge to publish `@latest`
264304

265305
### Before merging develop → main
266306

307+
You should never do this unless explicitly requested by the user:
308+
267309
```bash
268310
pnpm changeset pre exit
269311
git add .changeset/pre.json
@@ -357,27 +399,11 @@ git commit -m "feat(hypercerts): add project CRUD operations"
357399
# - Block commit if build fails
358400

359401
# 6. If prompted, add changeset for user-facing changes
360-
pnpm changeset
402+
# See "Release Process" section - use the writing-changesets skill
361403
git add .changeset/*.md
362404
git commit -m "chore: add changeset for project operations"
363405
```
364406

365-
### When to Add a Changeset
366-
367-
Run `pnpm changeset` before pushing if your changes include:
368-
369-
- New features or API changes
370-
- Bug fixes that affect users
371-
- Breaking changes
372-
- Performance improvements
373-
374-
Skip changesets for:
375-
376-
- Internal refactoring
377-
- Test-only changes
378-
- Documentation updates
379-
- Development tooling changes
380-
381407
## Key Files Reference
382408

383409
### sdk-core

eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ export default [
3030
},
3131
},
3232
{
33-
ignores: ["**/dist/**", "**/node_modules/**", "**/*.config.*", "**/.rollup.cache/**", "**/coverage/**"],
33+
ignores: ["**/dist/**", "**/node_modules/**", "**/.rollup.cache/**", "**/coverage/**", "**/tmp/**"],
3434
},
3535
];

opencode.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"pnpm format*": "allow",
88
"pnpm lint*": "allow",
99
"pnpm test*": "allow",
10-
"pnpm typecheck*": "allow"
10+
"pnpm typecheck*": "allow",
11+
"npm *": "deny",
12+
"yarn *": "deny"
1113
}
1214
}
1315
}

0 commit comments

Comments
 (0)