Skip to content
11 changes: 11 additions & 0 deletions .changeset/refactor-uri-parsing-utilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@hypercerts-org/sdk-core": patch
---

Refactor internal URI parsing and blob upload operations

- Export `AT_URI_REGEX` from `@hypercerts-org/sdk-core` for direct regex usage
- Consolidate AT-URI parsing in HypercertOperationsImpl using `parseAtUri()` utility
- Add internal `fetchRecord<T>()` and `saveRecord()` helpers to reduce code duplication
- Simplify `BlobOperationsImpl.upload()` to return `BlobRef` directly from the API instead of manually reconstructing it
- Update return type of `upload()` from manual `{ ref, mimeType, size }` to AT Protocol's `BlobRef` type
2 changes: 1 addition & 1 deletion packages/sdk-core/src/auth/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ export function validateScope(scope: string): {
const invalidPermissions: string[] = [];

// Pattern for valid permission prefixes
const validPrefixes = /^(atproto|transition:|account:|repo:|blob:?|rpc:|identity:|include:)/;
const validPrefixes = /^(atproto$|transition:|account:|repo[:?]|blob[:?]|rpc[:?]|identity:|include:)/;

for (const permission of permissions) {
if (!validPrefixes.test(permission)) {
Expand Down
1 change: 1 addition & 0 deletions packages/sdk-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export {
parseAtUri,
buildAtUri,
extractRkeyFromUri,
AT_URI_REGEX,
isValidAtUri,
createStrongRef,
createStrongRefFromResult,
Expand Down
31 changes: 31 additions & 0 deletions packages/sdk-core/src/lexicons/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,37 @@
import type { StrongRef } from "../services/hypercerts/types.js";
import type { CreateResult, UpdateResult } from "../repository/types.js";

/**
* Regular expression for parsing AT-URIs.
*
* AT-URIs follow the format: `at://{did}/{collection}/{rkey}`
*
* Capture groups:
* - [1] did - The DID of the repository owner (e.g., "did:plc:abc123")
* - [2] collection - The NSID of the record type (e.g., "org.hypercerts.claim.activity")
* - [3] rkey - The record key (e.g., "3km2vj4kfqp2a")
*
* @example Direct regex usage
* ```typescript
* const match = AT_URI_REGEX.exec("at://did:plc:abc/org.hypercerts.claim.activity/xyz");
* if (match) {
* const [, did, collection, rkey] = match;
* }
* ```
*
* @example Validation
* ```typescript
* if (AT_URI_REGEX.test(userInput)) {
* // Valid AT-URI format
* }
* ```
*
* @remarks
* For most use cases, prefer using {@link parseAtUri} which provides
* better error messages and returns a typed object.
*/
export const AT_URI_REGEX = /^at:\/\/([^/]+)\/([^/]+)\/(.+)$/;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

/**
* Components of an AT-URI (AT Protocol Uniform Resource Identifier).
*
Expand Down
4 changes: 3 additions & 1 deletion packages/sdk-core/src/repository/BlobOperationsImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ export class BlobOperationsImpl implements BlobOperations {
throw new NetworkError(`SDS blob upload failed: ${response.statusText}`);
}

const result = await response.json();
const result = (await response.json()) as {
blob: BlobRef;
};

return result.blob;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
Expand Down
Loading