@hypercerts-org/sdk-core 0.10.0-beta.8 → 0.10.0-beta.9
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/CHANGELOG.md +332 -0
- package/README.md +168 -78
- package/dist/index.cjs +1692 -1282
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +546 -179
- package/dist/index.mjs +1691 -1286
- package/dist/index.mjs.map +1 -1
- package/dist/lexicons.cjs +9 -0
- package/dist/lexicons.cjs.map +1 -1
- package/dist/lexicons.d.ts +8 -0
- package/dist/lexicons.mjs +10 -1
- package/dist/lexicons.mjs.map +1 -1
- package/dist/testing.cjs +11 -5
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.ts +25 -28
- package/dist/testing.mjs +11 -5
- package/dist/testing.mjs.map +1 -1
- package/dist/types.cjs +15 -16
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +332 -143
- package/dist/types.mjs +15 -16
- package/dist/types.mjs.map +1 -1
- package/package.json +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,337 @@
|
|
|
1
1
|
# @hypercerts-org/sdk-core
|
|
2
2
|
|
|
3
|
+
## 0.10.0-beta.9
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#128](https://github.com/hypercerts-org/hypercerts-sdk/pull/128)
|
|
8
|
+
[`d10642f`](https://github.com/hypercerts-org/hypercerts-sdk/commit/d10642ff3647513f03db4b73ca2e9ab7a06fe955) Thanks
|
|
9
|
+
[@Kzoeps](https://github.com/Kzoeps)! - **BREAKING CHANGE (pre-1.0):** Add strict URI validation for attachment
|
|
10
|
+
content strings
|
|
11
|
+
|
|
12
|
+
This introduces a breaking behavioral change for 0.x consumers:
|
|
13
|
+
- Add `isValidUri` utility to validate URI strings have a proper scheme (supports http, https, at://, ipfs://, and any
|
|
14
|
+
RFC 3986-compliant scheme)
|
|
15
|
+
- **`addAttachment` now throws `ValidationError`** when content strings are not valid URIs (e.g., plain text like
|
|
16
|
+
`"not-a-uri"`)
|
|
17
|
+
- Export `isValidUri` from the public API for consumer use
|
|
18
|
+
|
|
19
|
+
**Migration Guide:** Existing code that passes plain text or non-URI strings to `addAttachment` will now fail with a
|
|
20
|
+
`ValidationError`. To migrate:
|
|
21
|
+
1. Ensure all content strings passed to `addAttachment` are valid URIs
|
|
22
|
+
2. Use the new `isValidUri` utility to validate strings before passing them
|
|
23
|
+
3. Convert plain text content to proper URI format (e.g., data URIs, IPFS URIs, or HTTP URLs)
|
|
24
|
+
|
|
25
|
+
**Compatibility Note:** Consumers relying on the previous lenient behavior that accepted non-URI strings must update
|
|
26
|
+
their code. The validation now strictly enforces that attachment content must be a valid URI with a recognized scheme.
|
|
27
|
+
|
|
28
|
+
- [#127](https://github.com/hypercerts-org/hypercerts-sdk/pull/127)
|
|
29
|
+
[`5662f3f`](https://github.com/hypercerts-org/hypercerts-sdk/commit/5662f3f03d286a55c2623223b40ebc0542c1dcca) Thanks
|
|
30
|
+
[@Kzoeps](https://github.com/Kzoeps)! - Auto-detect user's PDS URL from OAuth session instead of requiring static
|
|
31
|
+
configuration
|
|
32
|
+
|
|
33
|
+
**Breaking Changes:**
|
|
34
|
+
- `servers.pds` config option has been removed. The user's PDS URL is now automatically detected from the OAuth
|
|
35
|
+
session's token info (`tokenInfo.aud`) during `callback()` and `restoreSession()`. This means the SDK correctly
|
|
36
|
+
routes operations to each user's actual PDS regardless of which server they're hosted on.
|
|
37
|
+
- A new `handleResolver` config option replaces `servers.pds` for its handle resolution role during OAuth
|
|
38
|
+
authorization. This is optional — if omitted, DNS-based resolution is used.
|
|
39
|
+
- `getAccountEmail()` no longer requires `servers.pds` to be configured, since it uses the session's fetch handler
|
|
40
|
+
which internally routes to the correct PDS.
|
|
41
|
+
- `sdk.repository()` is now async (returns `Promise<Repository>`). On cache miss it automatically resolves the PDS
|
|
42
|
+
from the session's token info, so callers no longer need to manually call `resolveSessionPds()` first.
|
|
43
|
+
|
|
44
|
+
**New APIs:**
|
|
45
|
+
- `sdk.resolveSessionPds(session)` — Manually resolve and cache a session's PDS URL. Useful for pre-warming the cache
|
|
46
|
+
or for sessions created outside the SDK's auth flow.
|
|
47
|
+
|
|
48
|
+
**Migration:**
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// Before
|
|
52
|
+
const sdk = createATProtoSDK({
|
|
53
|
+
oauth: { ... },
|
|
54
|
+
servers: { pds: "https://bsky.social", sds: "https://sds.example.com" },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// After
|
|
58
|
+
const sdk = createATProtoSDK({
|
|
59
|
+
oauth: { ... },
|
|
60
|
+
handleResolver: "https://bsky.social", // optional, for handle resolution only
|
|
61
|
+
servers: { sds: "https://sds.example.com" },
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- [#137](https://github.com/hypercerts-org/hypercerts-sdk/pull/137)
|
|
66
|
+
[`6f914e5`](https://github.com/hypercerts-org/hypercerts-sdk/commit/6f914e5a1f76ede52af4b8b75cf71dc935314dd7) Thanks
|
|
67
|
+
[@aspiers](https://github.com/aspiers)! - Add `isValidDid()` utility function for DID format validation
|
|
68
|
+
- Validates DID format (did:method:identifier) with support for numeric method names per W3C spec
|
|
69
|
+
- Exported from `@hypercerts-org/sdk-core` for consumer use
|
|
70
|
+
- `BlobOperationsImpl` constructor now validates `repoDid` and throws `ValidationError` for invalid formats
|
|
71
|
+
|
|
72
|
+
> **⚠️ Potentially breaking:** callers that previously passed invalid DID strings to `BlobOperationsImpl` (directly or
|
|
73
|
+
> via `Repository`) will now receive a `ValidationError` at construction time instead of silently accepting the value.
|
|
74
|
+
> Use `isValidDid(repoDid)` to check before constructing if needed.
|
|
75
|
+
|
|
76
|
+
- [#125](https://github.com/hypercerts-org/hypercerts-sdk/pull/125)
|
|
77
|
+
[`a493f3b`](https://github.com/hypercerts-org/hypercerts-sdk/commit/a493f3b05174eeef104c83f7be14749f1c0185a2) Thanks
|
|
78
|
+
[@Kzoeps](https://github.com/Kzoeps)! - Add dual profile system with separate Bluesky and Certified profile
|
|
79
|
+
operations, plus upsert methods
|
|
80
|
+
|
|
81
|
+
**Core SDK (`@hypercerts-org/sdk-core`):**
|
|
82
|
+
|
|
83
|
+
**Breaking Changes:**
|
|
84
|
+
|
|
85
|
+
The profile API has been completely redesigned to support two profile types:
|
|
86
|
+
- **Removed generic profile methods:**
|
|
87
|
+
- ❌ `profile.get()`
|
|
88
|
+
- ❌ `profile.create(params)`
|
|
89
|
+
- ❌ `profile.update(params)`
|
|
90
|
+
- **Removed deprecated profile types:**
|
|
91
|
+
- ❌ `HypercertProfile` - Use `CertifiedProfileRecord` instead
|
|
92
|
+
- ❌ `CreateHypercertProfileParams` - Use `CreateCertifiedProfileParams` instead
|
|
93
|
+
- ❌ `UpdateHypercertProfileParams` - Use `UpdateCertifiedProfileParams` instead
|
|
94
|
+
- ❌ `HypercertProfileParams` - Use specific create/update types instead
|
|
95
|
+
- ❌ `CreateProfileParams` - Use `CreateCertifiedProfileParams` instead
|
|
96
|
+
- **Removed unused type export:**
|
|
97
|
+
- ❌ `JsonBlobRef` - No longer used in SDK. This type was removed because:
|
|
98
|
+
- It was too "snowflaky" - required converting `BlobRef` instances to JSON format unnecessarily
|
|
99
|
+
- The actual `BlobRef` object works perfectly fine for all use cases
|
|
100
|
+
- It created flaky tests where we manually created mock JSON objects that weren't representative of actual
|
|
101
|
+
`JsonBlobRef` values
|
|
102
|
+
- Internal implementation now uses `BlobRef` instances directly throughout
|
|
103
|
+
- Users who need this type for advanced use cases can import it directly from `@atproto/lexicon`
|
|
104
|
+
- **Added profile-specific methods:**
|
|
105
|
+
- ✅ `profile.getBskyProfile()` - Get Bluesky profile (app.bsky.actor.profile)
|
|
106
|
+
- ✅ `profile.createBskyProfile(params)` - Create Bluesky profile
|
|
107
|
+
- ✅ `profile.updateBskyProfile(params)` - Update Bluesky profile
|
|
108
|
+
- ✅ `profile.getCertifiedProfile()` - Get Certified profile (app.certified.actor.profile) **[Returns `null` if
|
|
109
|
+
profile doesn't exist]**
|
|
110
|
+
- ✅ `profile.createCertifiedProfile(params)` - Create Certified profile
|
|
111
|
+
- ✅ `profile.updateCertifiedProfile(params)` - Update Certified profile
|
|
112
|
+
- ✅ `profile.upsertBskyProfile(params)` - Create or update Bluesky profile **[New]**
|
|
113
|
+
- ✅ `profile.upsertCertifiedProfile(params)` - Create or update Certified profile **[New]**
|
|
114
|
+
|
|
115
|
+
**Features:**
|
|
116
|
+
- **Bluesky profiles** (`app.bsky.actor.profile`):
|
|
117
|
+
- Standard AT Protocol profiles
|
|
118
|
+
- Avatar/banner returned as CDN URLs (`https://cdn.bsky.app/...`)
|
|
119
|
+
- Includes Bluesky-specific fields (labels, pinnedPost, etc.)
|
|
120
|
+
- **Certified profiles** (`app.certified.actor.profile`):
|
|
121
|
+
- Hypercerts-specific profiles with additional fields
|
|
122
|
+
- Avatar/banner returned as PDS blob URLs (`https://pds.../xrpc/...`)
|
|
123
|
+
- **`getCertifiedProfile()` returns `null` if profile doesn't exist** (not an error - common for new users)
|
|
124
|
+
- Supports `pronouns` field (max 20 graphemes)
|
|
125
|
+
- Supports `website` field
|
|
126
|
+
- Images stored using `HypercertImageRecord` format internally (smallImage/largeImage wrappers)
|
|
127
|
+
- **Upsert methods** (Recommended for most use cases):
|
|
128
|
+
- `upsertBskyProfile(params)` - Automatically creates or updates Bluesky profile
|
|
129
|
+
- `upsertCertifiedProfile(params)` - Automatically creates or updates Certified profile
|
|
130
|
+
- Simpler DX - no need to check if profile exists first
|
|
131
|
+
- Perfect for "save profile" operations
|
|
132
|
+
- **New types:**
|
|
133
|
+
- `BskyProfile` - Type for Bluesky profiles (alias for `AppBskyActorDefs.ProfileViewDetailed`)
|
|
134
|
+
- `CertifiedProfile` - Type for Certified profiles
|
|
135
|
+
- `CertifiedProfileRecord` - Record type for Certified profiles (replaces `HypercertProfile`)
|
|
136
|
+
- `CreateBskyProfileParams`, `UpdateBskyProfileParams`
|
|
137
|
+
- `CreateCertifiedProfileParams`, `UpdateCertifiedProfileParams` (replace `CreateHypercertProfileParams`,
|
|
138
|
+
`UpdateHypercertProfileParams`)
|
|
139
|
+
|
|
140
|
+
**Migration Guide:**
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// BEFORE (old API - removed)
|
|
144
|
+
const profile = await repo.profile.get();
|
|
145
|
+
await repo.profile.create({ displayName: "Alice" });
|
|
146
|
+
await repo.profile.update({ displayName: "New Name" });
|
|
147
|
+
|
|
148
|
+
// AFTER - Recommended: Use upsert (works for both create and update)
|
|
149
|
+
await repo.profile.upsertCertifiedProfile({
|
|
150
|
+
displayName: "Alice",
|
|
151
|
+
pronouns: "she/her",
|
|
152
|
+
website: "https://alice.com",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// AFTER - Advanced: Explicit create/update for fine control
|
|
156
|
+
const certProfile = await repo.profile.getCertifiedProfile();
|
|
157
|
+
if (!certProfile) {
|
|
158
|
+
await repo.profile.createCertifiedProfile({
|
|
159
|
+
displayName: "Alice",
|
|
160
|
+
pronouns: "she/her",
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
await repo.profile.updateCertifiedProfile({
|
|
164
|
+
displayName: "New Name",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Getting profiles - handle null case
|
|
169
|
+
const profile = await repo.profile.getCertifiedProfile();
|
|
170
|
+
if (profile) {
|
|
171
|
+
console.log(profile.displayName);
|
|
172
|
+
} else {
|
|
173
|
+
console.log("User hasn't created a profile yet");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Type migrations
|
|
177
|
+
import type {
|
|
178
|
+
CertifiedProfileRecord, // was: HypercertProfile
|
|
179
|
+
CreateCertifiedProfileParams, // was: CreateHypercertProfileParams
|
|
180
|
+
UpdateCertifiedProfileParams, // was: UpdateHypercertProfileParams
|
|
181
|
+
} from "@hypercerts-org/sdk-core/types";
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**React SDK (`@hypercerts-org/sdk-react`):**
|
|
185
|
+
|
|
186
|
+
**Breaking Changes:**
|
|
187
|
+
- `useProfile` hook renamed `update` to `save` and `isUpdating` to `isSaving`
|
|
188
|
+
- `save()` now uses upsert internally - works for first-time profile creation too
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// BEFORE
|
|
192
|
+
const { update, isUpdating } = useProfile();
|
|
193
|
+
await update({ displayName: "Alice" });
|
|
194
|
+
|
|
195
|
+
// AFTER
|
|
196
|
+
const { save, isSaving } = useProfile();
|
|
197
|
+
await save({ displayName: "Alice" }); // Works even if profile doesn't exist!
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- [#130](https://github.com/hypercerts-org/hypercerts-sdk/pull/130)
|
|
201
|
+
[`a9701cd`](https://github.com/hypercerts-org/hypercerts-sdk/commit/a9701cd47e2743207ff6bb6968eef7d9fc4db17c) Thanks
|
|
202
|
+
[@Kzoeps](https://github.com/Kzoeps)! - Fix `addContribution` to properly update hypercerts with contributor
|
|
203
|
+
references
|
|
204
|
+
|
|
205
|
+
**Breaking Changes:**
|
|
206
|
+
|
|
207
|
+
The `addContribution` method signature has changed to align with the `create()` method's contribution handling:
|
|
208
|
+
- `hypercertUri` is now **required** (was optional)
|
|
209
|
+
- `contributors` now accepts `Array<ContributorIdentityParams>` (was `string[]`)
|
|
210
|
+
- Supports DIDs, StrongRefs, or inline contributor creation params
|
|
211
|
+
- `contributionDetails` parameter **replaces** separate `role`/`description` params
|
|
212
|
+
- Supports inline role strings, StrongRefs, or inline contribution creation params
|
|
213
|
+
- Added optional `weight` parameter for contribution weighting
|
|
214
|
+
- Added optional `onProgress` callback for progress tracking
|
|
215
|
+
- Returns `UpdateResult` instead of `CreateResult` (since it updates the hypercert)
|
|
216
|
+
|
|
217
|
+
**What Changed:**
|
|
218
|
+
|
|
219
|
+
The method now correctly:
|
|
220
|
+
- Creates or references contributionDetails records
|
|
221
|
+
- Creates or references contributorInformation records
|
|
222
|
+
- **Updates the hypercert's `contributors` array** with the new entries (this was the bug)
|
|
223
|
+
- Supports batch addition of multiple contributors in one call
|
|
224
|
+
- Preserves existing contributors when adding new ones
|
|
225
|
+
|
|
226
|
+
**Migration:**
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Before (0.10.0-beta.7 and earlier):
|
|
230
|
+
await repo.hypercerts.addContribution({
|
|
231
|
+
hypercertUri: "at://...", // optional
|
|
232
|
+
contributors: ["did:plc:user1"],
|
|
233
|
+
role: "Developer",
|
|
234
|
+
description: "Built features",
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// After (0.10.0-beta.8+):
|
|
238
|
+
await repo.hypercerts.addContribution({
|
|
239
|
+
hypercertUri: "at://...", // required
|
|
240
|
+
contributors: ["did:plc:user1"], // or StrongRef or create params
|
|
241
|
+
contributionDetails: "Developer", // or StrongRef or create params object
|
|
242
|
+
weight: "1.0", // optional
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// With detailed contribution record:
|
|
246
|
+
await repo.hypercerts.addContribution({
|
|
247
|
+
hypercertUri: "at://...",
|
|
248
|
+
contributors: [
|
|
249
|
+
{
|
|
250
|
+
identifier: "did:plc:user1",
|
|
251
|
+
displayName: "Alice",
|
|
252
|
+
image: avatarBlob,
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
contributionDetails: {
|
|
256
|
+
role: "Developer",
|
|
257
|
+
contributionDescription: "Built features",
|
|
258
|
+
startDate: "2024-01-01",
|
|
259
|
+
endDate: "2024-06-30",
|
|
260
|
+
},
|
|
261
|
+
weight: "2.0",
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Additional Breaking Change:**
|
|
266
|
+
|
|
267
|
+
The `update()` method signature has been corrected to accept actual record fields:
|
|
268
|
+
- Now accepts `UpdateHypercertParams` (fields from `HypercertClaim` record schema)
|
|
269
|
+
- Previously accepted `Partial<CreateHypercertParams>` (SDK input format)
|
|
270
|
+
|
|
271
|
+
**Why this change:**
|
|
272
|
+
- Prevents invalid fields like `contributions` being added to records
|
|
273
|
+
- Allows updating `contributors` array directly (which exists in the schema)
|
|
274
|
+
- Type-safe - can only update fields that actually exist in the record
|
|
275
|
+
- Validation now works correctly
|
|
276
|
+
|
|
277
|
+
**Migration for update():**
|
|
278
|
+
|
|
279
|
+
Most code should continue to work since common fields like `title`, `description`, `startDate`, etc. exist in both
|
|
280
|
+
formats.
|
|
281
|
+
|
|
282
|
+
If you were using SDK input fields that don't exist in records (e.g., `contributions`), you'll need to update:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// Before:
|
|
286
|
+
await repo.hypercerts.update({
|
|
287
|
+
uri: hypercertUri,
|
|
288
|
+
updates: {
|
|
289
|
+
contributions: [...], // ❌ Invalid - doesn't exist in record
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// After: Use the actual record field
|
|
294
|
+
await repo.hypercerts.update({
|
|
295
|
+
uri: hypercertUri,
|
|
296
|
+
updates: {
|
|
297
|
+
contributors: [...], // ✅ Valid - exists in record schema
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Or use the new addContribution method
|
|
302
|
+
await repo.hypercerts.addContribution({
|
|
303
|
+
hypercertUri: hypercertUri,
|
|
304
|
+
contributors: ["did:plc:user1"],
|
|
305
|
+
contributionDetails: "Developer",
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Implementation Details:**
|
|
310
|
+
- Added `UpdateHypercertParams` type for type-safe record updates
|
|
311
|
+
- Added `buildContributorEntries()` helper to resolve and build contributor entries
|
|
312
|
+
- Added `attachContributorsToHypercert()` helper to update hypercerts with new contributors
|
|
313
|
+
- Refactored `processContributors()` to reuse `buildContributorEntries()` for consistency
|
|
314
|
+
- Removed unused `createContributionsWithProgress()` method
|
|
315
|
+
|
|
316
|
+
- [#126](https://github.com/hypercerts-org/hypercerts-sdk/pull/126)
|
|
317
|
+
[`5db01ee`](https://github.com/hypercerts-org/hypercerts-sdk/commit/5db01ee2baee53a0fd1c4e1ee1e32f2c7e41c30e) Thanks
|
|
318
|
+
[@Kzoeps](https://github.com/Kzoeps)! - Refactor internal URI parsing and blob upload operations
|
|
319
|
+
|
|
320
|
+
**Breaking:** `BlobOperationsImpl.upload()` now returns AT Protocol's `BlobRef` type instead of a plain
|
|
321
|
+
`{ ref, mimeType, size }` object. Callers should access blob properties via `BlobRef` methods (e.g.
|
|
322
|
+
`result.ref.toString()` for the CID string). SDS uploads now return a proper `BlobRef` instance with `ref`,
|
|
323
|
+
`mimeType`, and `size` correctly populated from the server response.
|
|
324
|
+
- Fix `validateScope` permission prefix regex to correctly accept query-param style scopes (e.g. `repo?action=create`,
|
|
325
|
+
`blob?accept=video/*`, `rpc?lxm=*`) and reject bare `atproto` with a suffix
|
|
326
|
+
- Export `AT_URI_REGEX` from `@hypercerts-org/sdk-core` for direct regex usage
|
|
327
|
+
- Consolidate AT-URI parsing in HypercertOperationsImpl using `parseAtUri()` utility
|
|
328
|
+
- Add internal `fetchRecord<T>()` and `saveRecord()` helpers to reduce code duplication
|
|
329
|
+
- Fix `AT_URI_REGEX` rkey capture group to use `[^/]+` instead of `.+` to prevent over-matching
|
|
330
|
+
- Fix `fetchRecord` to throw `NetworkError` when CID is absent instead of silently using an empty string
|
|
331
|
+
- Fix `saveRecord` error message formatting (was passing two arguments to `NetworkError`)
|
|
332
|
+
- Remove dead `parseAndValidateUri` method
|
|
333
|
+
- Eliminate redundant network fetch in `updateProject` by passing pre-fetched record to `updateCollectionRecord`
|
|
334
|
+
|
|
3
335
|
## 0.10.0-beta.8
|
|
4
336
|
|
|
5
337
|
### Minor Changes
|