@hypercerts-org/sdk-core 0.10.0-beta.4 → 0.10.0-beta.5
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 +153 -0
- package/README.md +131 -6
- package/dist/index.cjs +2597 -320
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1900 -169
- package/dist/index.mjs +3588 -1341
- package/dist/index.mjs.map +1 -1
- package/dist/lexicons.cjs +446 -34
- package/dist/lexicons.cjs.map +1 -1
- package/dist/lexicons.d.ts +248 -8
- package/dist/lexicons.mjs +422 -11
- package/dist/lexicons.mjs.map +1 -1
- package/dist/testing.d.ts +56 -9
- package/dist/types.cjs +89 -9
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +358 -66
- package/dist/types.mjs +89 -9
- package/dist/types.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/core/errors.ts","../src/storage/InMemorySessionStore.ts","../src/storage/InMemoryStateStore.ts","../src/auth/permissions.ts","../src/auth/OAuthClient.ts","../src/agent/ConfigurableAgent.ts","../src/repository/RecordOperationsImpl.ts","../src/repository/BlobOperationsImpl.ts","../src/repository/ProfileOperationsImpl.ts","../src/lexicons.ts","../src/repository/HypercertOperationsImpl.ts","../src/repository/CollaboratorOperationsImpl.ts","../src/repository/OrganizationOperationsImpl.ts","../src/repository/Repository.ts","../src/core/config.ts","../src/core/SDK.ts","../src/core/types.ts"],"sourcesContent":["/**\n * Base error class for all SDK errors.\n *\n * All errors thrown by the Hypercerts SDK extend this class, making it easy\n * to catch and handle SDK-specific errors.\n *\n * @example Catching all SDK errors\n * ```typescript\n * try {\n * await sdk.authorize(\"user.bsky.social\");\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * console.error(`SDK Error [${error.code}]: ${error.message}`);\n * console.error(`HTTP Status: ${error.status}`);\n * }\n * }\n * ```\n *\n * @example Checking error codes\n * ```typescript\n * try {\n * await repo.records.get(collection, rkey);\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * switch (error.code) {\n * case \"AUTHENTICATION_ERROR\":\n * // Redirect to login\n * break;\n * case \"VALIDATION_ERROR\":\n * // Show form errors\n * break;\n * case \"NETWORK_ERROR\":\n * // Retry or show offline message\n * break;\n * }\n * }\n * }\n * ```\n */\nexport class ATProtoSDKError extends Error {\n /**\n * Creates a new SDK error.\n *\n * @param message - Human-readable error description\n * @param code - Machine-readable error code for programmatic handling\n * @param status - HTTP status code associated with this error type\n * @param cause - The underlying error that caused this error, if any\n */\n constructor(\n message: string,\n public code: string,\n public status?: number,\n public cause?: unknown,\n ) {\n super(message);\n this.name = \"ATProtoSDKError\";\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when authentication fails.\n *\n * This error indicates problems with the OAuth flow, invalid credentials,\n * or failed token exchanges. Common causes:\n * - Invalid authorization code\n * - Expired or invalid state parameter\n * - Revoked or invalid tokens\n * - User denied authorization\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.callback(params);\n * } catch (error) {\n * if (error instanceof AuthenticationError) {\n * // Clear any stored state and redirect to login\n * console.error(\"Authentication failed:\", error.message);\n * }\n * }\n * ```\n */\nexport class AuthenticationError extends ATProtoSDKError {\n /**\n * Creates an authentication error.\n *\n * @param message - Description of what went wrong during authentication\n * @param cause - The underlying error (e.g., from the OAuth client)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"AUTHENTICATION_ERROR\", 401, cause);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Error thrown when a session has expired and cannot be refreshed.\n *\n * This typically occurs when:\n * - The refresh token has expired (usually after extended inactivity)\n * - The user has revoked access to your application\n * - The PDS has invalidated all sessions for the user\n *\n * When this error occurs, the user must re-authenticate.\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.restoreSession(did);\n * } catch (error) {\n * if (error instanceof SessionExpiredError) {\n * // Clear stored session and prompt user to log in again\n * localStorage.removeItem(\"userDid\");\n * window.location.href = \"/login\";\n * }\n * }\n * ```\n */\nexport class SessionExpiredError extends ATProtoSDKError {\n /**\n * Creates a session expired error.\n *\n * @param message - Description of why the session expired\n * @param cause - The underlying error from the token refresh attempt\n */\n constructor(message: string = \"Session expired\", cause?: unknown) {\n super(message, \"SESSION_EXPIRED\", 401, cause);\n this.name = \"SessionExpiredError\";\n }\n}\n\n/**\n * Error thrown when input validation fails.\n *\n * This error indicates that provided data doesn't meet the required format\n * or constraints. Common causes:\n * - Missing required fields\n * - Invalid URL formats\n * - Invalid DID format\n * - Schema validation failures for records\n * - Invalid configuration values\n *\n * @example\n * ```typescript\n * try {\n * await sdk.authorize(\"\"); // Empty identifier\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Invalid input:\", error.message);\n * // Show validation error to user\n * }\n * }\n * ```\n *\n * @example With Zod validation cause\n * ```typescript\n * try {\n * await repo.records.create(collection, record);\n * } catch (error) {\n * if (error instanceof ValidationError && error.cause) {\n * // error.cause may be a ZodError with detailed field errors\n * const zodError = error.cause as ZodError;\n * zodError.errors.forEach(e => {\n * console.error(`Field ${e.path.join(\".\")}: ${e.message}`);\n * });\n * }\n * }\n * ```\n */\nexport class ValidationError extends ATProtoSDKError {\n /**\n * Creates a validation error.\n *\n * @param message - Description of what validation failed\n * @param cause - The underlying validation error (e.g., ZodError)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"VALIDATION_ERROR\", 400, cause);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Error thrown when a network request fails.\n *\n * This error indicates connectivity issues or server unavailability.\n * Common causes:\n * - No internet connection\n * - DNS resolution failure\n * - Server timeout\n * - Server returned 5xx error\n * - TLS/SSL errors\n *\n * These errors are typically transient and may succeed on retry.\n *\n * @example\n * ```typescript\n * try {\n * await repo.records.list(collection);\n * } catch (error) {\n * if (error instanceof NetworkError) {\n * // Implement retry logic or show offline indicator\n * console.error(\"Network error:\", error.message);\n * await retryWithBackoff(() => repo.records.list(collection));\n * }\n * }\n * ```\n */\nexport class NetworkError extends ATProtoSDKError {\n /**\n * Creates a network error.\n *\n * @param message - Description of the network failure\n * @param cause - The underlying error (e.g., fetch error, timeout)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"NETWORK_ERROR\", 503, cause);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Error thrown when an SDS-only operation is attempted on a PDS.\n *\n * Certain operations are only available on Shared Data Servers (SDS),\n * such as collaborator management and organization operations.\n * This error is thrown when these operations are attempted on a\n * Personal Data Server (PDS).\n *\n * @example\n * ```typescript\n * const pdsRepo = sdk.repository(session); // Default is PDS\n *\n * try {\n * // This will throw SDSRequiredError\n * await pdsRepo.collaborators.list();\n * } catch (error) {\n * if (error instanceof SDSRequiredError) {\n * // Switch to SDS for this operation\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n * const collaborators = await sdsRepo.collaborators.list();\n * }\n * }\n * ```\n */\nexport class SDSRequiredError extends ATProtoSDKError {\n /**\n * Creates an SDS required error.\n *\n * @param message - Description of which operation requires SDS\n * @param cause - Any underlying error\n */\n constructor(message: string = \"This operation requires a Shared Data Server (SDS)\", cause?: unknown) {\n super(message, \"SDS_REQUIRED\", 400, cause);\n this.name = \"SDSRequiredError\";\n }\n}\n","import type { SessionStore } from \"../core/interfaces.js\";\nimport type { NodeSavedSession } from \"@atproto/oauth-client-node\";\n\n/**\n * In-memory implementation of the SessionStore interface.\n *\n * This store keeps OAuth sessions in memory using a Map. It's intended\n * for development, testing, and simple use cases where session persistence\n * across restarts is not required.\n *\n * @remarks\n * **Warning**: This implementation is **not suitable for production** because:\n * - Sessions are lost when the process restarts\n * - Sessions cannot be shared across multiple server instances\n * - No automatic cleanup of expired sessions\n *\n * For production, implement {@link SessionStore} with a persistent backend:\n * - **Redis**: Good for distributed systems, supports TTL\n * - **PostgreSQL/MySQL**: Good for existing database infrastructure\n * - **MongoDB**: Good for document-based storage\n *\n * @example Basic usage\n * ```typescript\n * import { InMemorySessionStore } from \"@hypercerts-org/sdk/storage\";\n *\n * const sessionStore = new InMemorySessionStore();\n *\n * const sdk = new ATProtoSDK({\n * oauth: { ... },\n * storage: {\n * sessionStore, // Will warn in logs for production\n * },\n * });\n * ```\n *\n * @example Testing usage\n * ```typescript\n * const sessionStore = new InMemorySessionStore();\n *\n * // After tests, clean up\n * sessionStore.clear();\n * ```\n *\n * @see {@link SessionStore} for the interface definition\n * @see {@link InMemoryStateStore} for the corresponding state store\n */\nexport class InMemorySessionStore implements SessionStore {\n /**\n * Internal storage for sessions, keyed by DID.\n * @internal\n */\n private sessions = new Map<string, NodeSavedSession>();\n\n /**\n * Retrieves a session by DID.\n *\n * @param did - The user's Decentralized Identifier\n * @returns Promise resolving to the session, or `undefined` if not found\n *\n * @example\n * ```typescript\n * const session = await sessionStore.get(\"did:plc:abc123\");\n * if (session) {\n * console.log(\"Session found\");\n * }\n * ```\n */\n async get(did: string): Promise<NodeSavedSession | undefined> {\n return this.sessions.get(did);\n }\n\n /**\n * Stores or updates a session.\n *\n * @param did - The user's DID to use as the key\n * @param session - The session data to store\n *\n * @remarks\n * If a session already exists for the DID, it is overwritten.\n *\n * @example\n * ```typescript\n * await sessionStore.set(\"did:plc:abc123\", sessionData);\n * ```\n */\n async set(did: string, session: NodeSavedSession): Promise<void> {\n this.sessions.set(did, session);\n }\n\n /**\n * Deletes a session by DID.\n *\n * @param did - The DID of the session to delete\n *\n * @remarks\n * If no session exists for the DID, this is a no-op.\n *\n * @example\n * ```typescript\n * await sessionStore.del(\"did:plc:abc123\");\n * ```\n */\n async del(did: string): Promise<void> {\n this.sessions.delete(did);\n }\n\n /**\n * Clears all stored sessions.\n *\n * This is primarily useful for testing to ensure a clean state\n * between test runs.\n *\n * @remarks\n * This method is synchronous (not async) for convenience in test cleanup.\n *\n * @example\n * ```typescript\n * // In test teardown\n * afterEach(() => {\n * sessionStore.clear();\n * });\n * ```\n */\n clear(): void {\n this.sessions.clear();\n }\n}\n","import type { StateStore } from \"../core/interfaces.js\";\nimport type { NodeSavedState } from \"@atproto/oauth-client-node\";\n\n/**\n * In-memory implementation of the StateStore interface.\n *\n * This store keeps OAuth state parameters in memory using a Map. State is\n * used during the OAuth authorization flow for CSRF protection and PKCE.\n *\n * @remarks\n * **Warning**: This implementation is **not suitable for production** because:\n * - State is lost when the process restarts (breaking in-progress OAuth flows)\n * - State cannot be shared across multiple server instances\n * - No automatic cleanup of expired state (memory leak potential)\n *\n * For production, implement {@link StateStore} with a persistent backend\n * that supports TTL (time-to-live):\n * - **Redis**: Ideal choice with built-in TTL support\n * - **Database with cleanup job**: PostgreSQL/MySQL with periodic cleanup\n *\n * **State Lifecycle**:\n * 1. Created when user starts OAuth flow (`authorize()`)\n * 2. Retrieved and validated during callback\n * 3. Deleted after successful or failed callback\n * 4. Should expire after ~15 minutes if callback never happens\n *\n * @example Basic usage\n * ```typescript\n * import { InMemoryStateStore } from \"@hypercerts-org/sdk/storage\";\n *\n * const stateStore = new InMemoryStateStore();\n *\n * const sdk = new ATProtoSDK({\n * oauth: { ... },\n * storage: {\n * stateStore, // Will warn in logs for production\n * },\n * });\n * ```\n *\n * @example Testing usage\n * ```typescript\n * const stateStore = new InMemoryStateStore();\n *\n * // After tests, clean up\n * stateStore.clear();\n * ```\n *\n * @see {@link StateStore} for the interface definition\n * @see {@link InMemorySessionStore} for the corresponding session store\n */\nexport class InMemoryStateStore implements StateStore {\n /**\n * Internal storage for OAuth state, keyed by state string.\n * @internal\n */\n private states = new Map<string, NodeSavedState>();\n\n /**\n * Retrieves OAuth state by key.\n *\n * @param key - The state key (random string from authorization URL)\n * @returns Promise resolving to the state, or `undefined` if not found\n *\n * @remarks\n * The key is a cryptographically random string generated during\n * the authorization request. It's included in the callback URL\n * and used to retrieve the associated PKCE verifier and other data.\n *\n * @example\n * ```typescript\n * // During OAuth callback\n * const state = await stateStore.get(params.get(\"state\")!);\n * if (!state) {\n * throw new Error(\"Invalid or expired state\");\n * }\n * ```\n */\n async get(key: string): Promise<NodeSavedState | undefined> {\n return this.states.get(key);\n }\n\n /**\n * Stores OAuth state temporarily.\n *\n * @param key - The state key to use for storage\n * @param state - The OAuth state data (includes PKCE verifier, etc.)\n *\n * @remarks\n * In production implementations, state should be stored with a TTL\n * of approximately 10-15 minutes to prevent stale state accumulation.\n *\n * @example\n * ```typescript\n * // Called internally by OAuthClient during authorize()\n * await stateStore.set(stateKey, {\n * // PKCE code verifier, redirect URI, etc.\n * });\n * ```\n */\n async set(key: string, state: NodeSavedState): Promise<void> {\n this.states.set(key, state);\n }\n\n /**\n * Deletes OAuth state by key.\n *\n * @param key - The state key to delete\n *\n * @remarks\n * Called after the OAuth callback is processed (whether successful or not)\n * to clean up the temporary state.\n *\n * @example\n * ```typescript\n * // After processing callback\n * await stateStore.del(stateKey);\n * ```\n */\n async del(key: string): Promise<void> {\n this.states.delete(key);\n }\n\n /**\n * Clears all stored state.\n *\n * This is primarily useful for testing to ensure a clean state\n * between test runs.\n *\n * @remarks\n * This method is synchronous (not async) for convenience in test cleanup.\n * In production, be careful using this as it will invalidate all\n * in-progress OAuth flows.\n *\n * @example\n * ```typescript\n * // In test teardown\n * afterEach(() => {\n * stateStore.clear();\n * });\n * ```\n */\n clear(): void {\n this.states.clear();\n }\n}\n","/**\n * OAuth Scopes and Granular Permissions\n *\n * This module provides type-safe, Zod-validated OAuth scope and permission management\n * for the ATProto SDK. It supports both legacy transitional scopes and the new\n * granular permissions model.\n *\n * @see https://atproto.com/specs/oauth\n * @see https://atproto.com/specs/permission\n *\n * @module auth/permissions\n */\n\nimport { z } from \"zod\";\n\n/**\n * Base OAuth scope - required for all sessions\n *\n * @constant\n */\nexport const ATPROTO_SCOPE = \"atproto\" as const;\n\n/**\n * Transitional OAuth scopes for legacy compatibility.\n *\n * These scopes provide broad access and are maintained for backwards compatibility.\n * New applications should use granular permissions instead.\n *\n * @deprecated Use granular permissions (account:*, repo:*, etc.) for better control\n * @constant\n */\nexport const TRANSITION_SCOPES = {\n /** Broad PDS permissions including record creation, blob uploads, and preferences */\n GENERIC: \"transition:generic\",\n /** Direct messages access (requires transition:generic) */\n CHAT: \"transition:chat.bsky\",\n /** Email address and confirmation status */\n EMAIL: \"transition:email\",\n} as const;\n\n/**\n * Zod schema for transitional scopes.\n *\n * Validates that a scope string is one of the known transitional scopes.\n *\n * @example\n * ```typescript\n * TransitionScopeSchema.parse('transition:email'); // Valid\n * TransitionScopeSchema.parse('invalid'); // Throws ZodError\n * ```\n */\nexport const TransitionScopeSchema = z\n .enum([\"transition:generic\", \"transition:chat.bsky\", \"transition:email\"])\n .describe(\"Legacy transitional OAuth scopes\");\n\n/**\n * Type for transitional scopes inferred from schema.\n */\nexport type TransitionScope = z.infer<typeof TransitionScopeSchema>;\n\n/**\n * Zod schema for account permission attributes.\n *\n * Account attributes specify what aspect of the account is being accessed.\n */\nexport const AccountAttrSchema = z.enum([\"email\", \"repo\"]);\n\n/**\n * Type for account attributes inferred from schema.\n */\nexport type AccountAttr = z.infer<typeof AccountAttrSchema>;\n\n/**\n * Zod schema for account actions.\n *\n * Account actions specify the level of access (read-only or management).\n */\nexport const AccountActionSchema = z.enum([\"read\", \"manage\"]);\n\n/**\n * Type for account actions inferred from schema.\n */\nexport type AccountAction = z.infer<typeof AccountActionSchema>;\n\n/**\n * Zod schema for repository actions.\n *\n * Repository actions specify what operations can be performed on records.\n */\nexport const RepoActionSchema = z.enum([\"create\", \"update\", \"delete\"]);\n\n/**\n * Type for repository actions inferred from schema.\n */\nexport type RepoAction = z.infer<typeof RepoActionSchema>;\n\n/**\n * Zod schema for identity permission attributes.\n *\n * Identity attributes specify what identity information can be managed.\n */\nexport const IdentityAttrSchema = z.enum([\"handle\", \"*\"]);\n\n/**\n * Type for identity attributes inferred from schema.\n */\nexport type IdentityAttr = z.infer<typeof IdentityAttrSchema>;\n\n/**\n * Zod schema for MIME type patterns.\n *\n * Validates MIME type strings like \"image/*\" or \"video/mp4\".\n *\n * @example\n * ```typescript\n * MimeTypeSchema.parse('image/*'); // Valid\n * MimeTypeSchema.parse('video/mp4'); // Valid\n * MimeTypeSchema.parse('invalid'); // Throws ZodError\n * ```\n */\nexport const MimeTypeSchema = z\n .string()\n .regex(\n /^[a-z]+\\/[a-z0-9*+-]+$/i,\n 'Invalid MIME type pattern. Expected format: type/subtype (e.g., \"image/*\" or \"video/mp4\")',\n );\n\n/**\n * Zod schema for NSID (Namespaced Identifier).\n *\n * NSIDs are reverse-DNS style identifiers used throughout ATProto\n * (e.g., \"app.bsky.feed.post\" or \"com.example.myrecord\").\n *\n * @see https://atproto.com/specs/nsid\n *\n * @example\n * ```typescript\n * NsidSchema.parse('app.bsky.feed.post'); // Valid\n * NsidSchema.parse('com.example.myrecord'); // Valid\n * NsidSchema.parse('InvalidNSID'); // Throws ZodError\n * ```\n */\nexport const NsidSchema = z\n .string()\n .regex(\n /^[a-zA-Z][a-zA-Z0-9-]*(\\.[a-zA-Z][a-zA-Z0-9-]*)+$/,\n 'Invalid NSID format. Expected reverse-DNS format (e.g., \"app.bsky.feed.post\")',\n );\n\n/**\n * Zod schema for account permission.\n *\n * Account permissions control access to account-level information like email\n * and repository management.\n *\n * @example Without action (read-only)\n * ```typescript\n * const input = { type: 'account', attr: 'email' };\n * AccountPermissionSchema.parse(input); // Returns: \"account:email\"\n * ```\n *\n * @example With action\n * ```typescript\n * const input = { type: 'account', attr: 'email', action: 'manage' };\n * AccountPermissionSchema.parse(input); // Returns: \"account:email?action=manage\"\n * ```\n */\nexport const AccountPermissionSchema = z\n .object({\n type: z.literal(\"account\"),\n attr: AccountAttrSchema,\n action: AccountActionSchema.optional(),\n })\n .transform(({ attr, action }) => {\n let perm = `account:${attr}`;\n if (action) {\n perm += `?action=${action}`;\n }\n return perm;\n });\n\n/**\n * Input type for account permission (before transform).\n */\nexport type AccountPermissionInput = z.input<typeof AccountPermissionSchema>;\n\n/**\n * Zod schema for repository permission.\n *\n * Repository permissions control write access to records by collection type.\n * The collection must be a valid NSID or wildcard (*).\n *\n * @example Without actions (all actions allowed)\n * ```typescript\n * const input = { type: 'repo', collection: 'app.bsky.feed.post' };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:app.bsky.feed.post\"\n * ```\n *\n * @example With specific actions\n * ```typescript\n * const input = {\n * type: 'repo',\n * collection: 'app.bsky.feed.post',\n * actions: ['create', 'update']\n * };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:app.bsky.feed.post?action=create&action=update\"\n * ```\n *\n * @example With wildcard collection\n * ```typescript\n * const input = { type: 'repo', collection: '*', actions: ['delete'] };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:*?action=delete\"\n * ```\n */\nexport const RepoPermissionSchema = z\n .object({\n type: z.literal(\"repo\"),\n collection: NsidSchema.or(z.literal(\"*\")),\n actions: z.array(RepoActionSchema).optional(),\n })\n .transform(({ collection, actions }) => {\n let perm = `repo:${collection}`;\n if (actions && actions.length > 0) {\n const params = actions.map((a) => `action=${a}`).join(\"&\");\n perm += `?${params}`;\n }\n return perm;\n });\n\n/**\n * Input type for repository permission (before transform).\n */\nexport type RepoPermissionInput = z.input<typeof RepoPermissionSchema>;\n\n/**\n * Zod schema for blob permission.\n *\n * Blob permissions control media file uploads constrained by MIME type patterns.\n *\n * @example Single MIME type\n * ```typescript\n * const input = { type: 'blob', mimeTypes: ['image/*'] };\n * BlobPermissionSchema.parse(input); // Returns: \"blob:image/*\"\n * ```\n *\n * @example Multiple MIME types\n * ```typescript\n * const input = { type: 'blob', mimeTypes: ['image/*', 'video/*'] };\n * BlobPermissionSchema.parse(input); // Returns: \"blob?accept=image/*&accept=video/*\"\n * ```\n */\nexport const BlobPermissionSchema = z\n .object({\n type: z.literal(\"blob\"),\n mimeTypes: z.array(MimeTypeSchema).min(1, \"At least one MIME type required\"),\n })\n .transform(({ mimeTypes }) => {\n if (mimeTypes.length === 1) {\n return `blob:${mimeTypes[0]}`;\n }\n const accepts = mimeTypes.map((t) => `accept=${encodeURIComponent(t)}`).join(\"&\");\n return `blob?${accepts}`;\n });\n\n/**\n * Input type for blob permission (before transform).\n */\nexport type BlobPermissionInput = z.input<typeof BlobPermissionSchema>;\n\n/**\n * Zod schema for RPC permission.\n *\n * RPC permissions control authenticated API calls to remote services.\n * At least one of lexicon or aud must be restricted (both cannot be wildcards).\n *\n * @example Specific lexicon with wildcard audience\n * ```typescript\n * const input = {\n * type: 'rpc',\n * lexicon: 'com.atproto.repo.createRecord',\n * aud: '*'\n * };\n * RpcPermissionSchema.parse(input);\n * // Returns: \"rpc:com.atproto.repo.createRecord?aud=*\"\n * ```\n *\n * @example With specific audience\n * ```typescript\n * const input = {\n * type: 'rpc',\n * lexicon: 'com.atproto.repo.createRecord',\n * aud: 'did:web:api.example.com',\n * inheritAud: true\n * };\n * RpcPermissionSchema.parse(input);\n * // Returns: \"rpc:com.atproto.repo.createRecord?aud=did%3Aweb%3Aapi.example.com&inheritAud=true\"\n * ```\n */\nexport const RpcPermissionSchema = z\n .object({\n type: z.literal(\"rpc\"),\n lexicon: NsidSchema.or(z.literal(\"*\")),\n aud: z.string().min(1, \"Audience is required\"),\n inheritAud: z.boolean().optional(),\n })\n .refine(\n ({ lexicon, aud }) => lexicon !== \"*\" || aud !== \"*\",\n \"At least one of lexicon or aud must be restricted (wildcards cannot both be used)\",\n )\n .transform(({ lexicon, aud, inheritAud }) => {\n let perm = `rpc:${lexicon}?aud=${encodeURIComponent(aud)}`;\n if (inheritAud) {\n perm += \"&inheritAud=true\";\n }\n return perm;\n });\n\n/**\n * Input type for RPC permission (before transform).\n */\nexport type RpcPermissionInput = z.input<typeof RpcPermissionSchema>;\n\n/**\n * Zod schema for identity permission.\n *\n * Identity permissions control access to DID documents and handles.\n *\n * @example Handle management\n * ```typescript\n * const input = { type: 'identity', attr: 'handle' };\n * IdentityPermissionSchema.parse(input); // Returns: \"identity:handle\"\n * ```\n *\n * @example All identity attributes\n * ```typescript\n * const input = { type: 'identity', attr: '*' };\n * IdentityPermissionSchema.parse(input); // Returns: \"identity:*\"\n * ```\n */\nexport const IdentityPermissionSchema = z\n .object({\n type: z.literal(\"identity\"),\n attr: IdentityAttrSchema,\n })\n .transform(({ attr }) => `identity:${attr}`);\n\n/**\n * Input type for identity permission (before transform).\n */\nexport type IdentityPermissionInput = z.input<typeof IdentityPermissionSchema>;\n\n/**\n * Zod schema for permission set inclusion.\n *\n * Include permissions reference permission sets bundled under a single NSID.\n *\n * @example Without audience\n * ```typescript\n * const input = { type: 'include', nsid: 'com.example.authBasicFeatures' };\n * IncludePermissionSchema.parse(input);\n * // Returns: \"include:com.example.authBasicFeatures\"\n * ```\n *\n * @example With audience\n * ```typescript\n * const input = {\n * type: 'include',\n * nsid: 'com.example.authBasicFeatures',\n * aud: 'did:web:api.example.com'\n * };\n * IncludePermissionSchema.parse(input);\n * // Returns: \"include:com.example.authBasicFeatures?aud=did%3Aweb%3Aapi.example.com\"\n * ```\n */\nexport const IncludePermissionSchema = z\n .object({\n type: z.literal(\"include\"),\n nsid: NsidSchema,\n aud: z.string().optional(),\n })\n .transform(({ nsid, aud }) => {\n let perm = `include:${nsid}`;\n if (aud) {\n perm += `?aud=${encodeURIComponent(aud)}`;\n }\n return perm;\n });\n\n/**\n * Input type for include permission (before transform).\n */\nexport type IncludePermissionInput = z.input<typeof IncludePermissionSchema>;\n\n/**\n * Union schema for all permission types.\n *\n * This schema accepts any of the supported permission types and validates\n * them according to their specific rules.\n */\nexport const PermissionSchema = z.union([\n AccountPermissionSchema,\n RepoPermissionSchema,\n BlobPermissionSchema,\n RpcPermissionSchema,\n IdentityPermissionSchema,\n IncludePermissionSchema,\n]);\n\n/**\n * Input type for any permission (before transform).\n */\nexport type PermissionInput = z.input<typeof PermissionSchema>;\n\n/**\n * Output type for any permission (after transform).\n */\nexport type Permission = z.output<typeof PermissionSchema>;\n\n/**\n * Fluent builder for constructing OAuth permission arrays.\n *\n * This class provides a convenient, type-safe way to build arrays of permissions\n * using method chaining.\n *\n * @example Basic usage\n * ```typescript\n * const builder = new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .blob(['image/*', 'video/*']);\n *\n * const permissions = builder.build();\n * // Returns: ['account:email?action=read', 'repo:app.bsky.feed.post?action=create&action=update', 'blob:image/*,video/*']\n * ```\n *\n * @example With transitional scopes\n * ```typescript\n * const builder = new PermissionBuilder()\n * .transition('email')\n * .transition('generic');\n *\n * const scopes = builder.build();\n * // Returns: ['transition:email', 'transition:generic']\n * ```\n */\nexport class PermissionBuilder {\n private permissions: string[] = [];\n\n /**\n * Add a transitional scope.\n *\n * @param scope - The transitional scope name ('email', 'generic', or 'chat.bsky')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.transition('email').transition('generic');\n * ```\n */\n transition(scope: \"email\" | \"generic\" | \"chat.bsky\"): this {\n const fullScope = `transition:${scope}`;\n const validated = TransitionScopeSchema.parse(fullScope);\n this.permissions.push(validated);\n return this;\n }\n\n /**\n * Add an account permission.\n *\n * @param attr - The account attribute ('email' or 'repo')\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountEmail('read').accountRepo('manage');\n * ```\n */\n account(attr: z.infer<typeof AccountAttrSchema>, action?: z.infer<typeof AccountActionSchema>): this {\n const permission = AccountPermissionSchema.parse({\n type: \"account\",\n attr,\n action,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Convenience method for account:email permission.\n *\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountEmail('read');\n * ```\n */\n accountEmail(action?: z.infer<typeof AccountActionSchema>): this {\n return this.account(\"email\", action);\n }\n\n /**\n * Convenience method for account:repo permission.\n *\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountRepo('manage');\n * ```\n */\n accountRepo(action?: z.infer<typeof AccountActionSchema>): this {\n return this.account(\"repo\", action);\n }\n\n /**\n * Add a repository permission.\n *\n * @param collection - The NSID of the collection or '*' for all\n * @param actions - Optional array of actions ('create', 'update', 'delete')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repo('app.bsky.feed.post', ['create', 'update']);\n * ```\n */\n repo(collection: string, actions?: z.infer<typeof RepoActionSchema>[]): this {\n const permission = RepoPermissionSchema.parse({\n type: \"repo\",\n collection,\n actions,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Convenience method for repository write permissions (create + update).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoWrite('app.bsky.feed.post');\n * ```\n */\n repoWrite(collection: string): this {\n return this.repo(collection, [\"create\", \"update\"]);\n }\n\n /**\n * Convenience method for repository read permission (no actions).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoRead('app.bsky.feed.post');\n * ```\n */\n repoRead(collection: string): this {\n return this.repo(collection, []);\n }\n\n /**\n * Convenience method for full repository permissions (create + update + delete).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoFull('app.bsky.feed.post');\n * ```\n */\n repoFull(collection: string): this {\n return this.repo(collection, [\"create\", \"update\", \"delete\"]);\n }\n\n /**\n * Add a blob permission.\n *\n * @param mimeTypes - Array of MIME types or a single MIME type\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.blob(['image/*', 'video/*']);\n * builder.blob('image/*');\n * ```\n */\n blob(mimeTypes: string | string[]): this {\n const types = Array.isArray(mimeTypes) ? mimeTypes : [mimeTypes];\n const permission = BlobPermissionSchema.parse({\n type: \"blob\",\n mimeTypes: types,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an RPC permission.\n *\n * @param lexicon - The NSID of the lexicon or '*' for all\n * @param aud - The audience (DID or URL)\n * @param inheritAud - Whether to inherit audience\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.rpc('com.atproto.repo.createRecord', 'did:web:api.example.com');\n * ```\n */\n rpc(lexicon: string, aud: string, inheritAud?: boolean): this {\n const permission = RpcPermissionSchema.parse({\n type: \"rpc\",\n lexicon,\n aud,\n inheritAud,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an identity permission.\n *\n * @param attr - The identity attribute ('handle' or '*')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.identity('handle');\n * ```\n */\n identity(attr: z.infer<typeof IdentityAttrSchema>): this {\n const permission = IdentityPermissionSchema.parse({\n type: \"identity\",\n attr,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an include permission.\n *\n * @param nsid - The NSID of the scope set to include\n * @param aud - Optional audience restriction\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.include('com.example.authBasicFeatures');\n * ```\n */\n include(nsid: string, aud?: string): this {\n const permission = IncludePermissionSchema.parse({\n type: \"include\",\n nsid,\n aud,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add a custom permission string directly (bypasses validation).\n *\n * Use this for testing or special cases where you need to add\n * a permission that doesn't fit the standard types.\n *\n * @param permission - The permission string\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.custom('atproto');\n * ```\n */\n custom(permission: string): this {\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add the base atproto scope.\n *\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.atproto();\n * ```\n */\n atproto(): this {\n this.permissions.push(ATPROTO_SCOPE);\n return this;\n }\n\n /**\n * Build and return the array of permission strings.\n *\n * @returns Array of permission strings\n *\n * @example\n * ```typescript\n * const permissions = builder.build();\n * ```\n */\n build(): string[] {\n return [...this.permissions];\n }\n\n /**\n * Clear all permissions from the builder.\n *\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.clear().accountEmail('read');\n * ```\n */\n clear(): this {\n this.permissions = [];\n return this;\n }\n\n /**\n * Get the current number of permissions.\n *\n * @returns The number of permissions\n *\n * @example\n * ```typescript\n * const count = builder.count();\n * ```\n */\n count(): number {\n return this.permissions.length;\n }\n}\n\n/**\n * Build a scope string from an array of permissions.\n *\n * This is a convenience function that joins permission strings with spaces,\n * which is the standard format for OAuth scope parameters.\n *\n * @param permissions - Array of permission strings\n * @returns Space-separated scope string\n *\n * @example\n * ```typescript\n * const permissions = ['account:email?action=read', 'repo:app.bsky.feed.post'];\n * const scope = buildScope(permissions);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post\"\n * ```\n */\nexport function buildScope(permissions: string[]): string {\n return permissions.join(\" \");\n}\n\n/**\n * Pre-built scope presets for common use cases.\n *\n * These presets provide ready-to-use permission sets for typical application scenarios.\n */\nexport const ScopePresets = {\n /**\n * Email access scope - allows reading user's email address.\n *\n * Includes:\n * - account:email?action=read\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.EMAIL_READ;\n * // Use in OAuth flow to request email access\n * ```\n */\n EMAIL_READ: buildScope(new PermissionBuilder().accountEmail(\"read\").build()),\n\n /**\n * Profile read scope - allows reading user's profile.\n *\n * Includes:\n * - repo:app.bsky.actor.profile (read-only)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.PROFILE_READ;\n * ```\n */\n PROFILE_READ: buildScope(new PermissionBuilder().repoRead(\"app.bsky.actor.profile\").build()),\n\n /**\n * Profile write scope - allows updating user's profile.\n *\n * Includes:\n * - repo:app.bsky.actor.profile (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.PROFILE_WRITE;\n * ```\n */\n PROFILE_WRITE: buildScope(new PermissionBuilder().repoWrite(\"app.bsky.actor.profile\").build()),\n\n /**\n * Post creation scope - allows creating and updating posts.\n *\n * Includes:\n * - repo:app.bsky.feed.post (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.POST_WRITE;\n * ```\n */\n POST_WRITE: buildScope(new PermissionBuilder().repoWrite(\"app.bsky.feed.post\").build()),\n\n /**\n * Social interactions scope - allows liking, reposting, and following.\n *\n * Includes:\n * - repo:app.bsky.feed.like (create + update)\n * - repo:app.bsky.feed.repost (create + update)\n * - repo:app.bsky.graph.follow (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.SOCIAL_WRITE;\n * ```\n */\n SOCIAL_WRITE: buildScope(\n new PermissionBuilder()\n .repoWrite(\"app.bsky.feed.like\")\n .repoWrite(\"app.bsky.feed.repost\")\n .repoWrite(\"app.bsky.graph.follow\")\n .build(),\n ),\n\n /**\n * Media upload scope - allows uploading images and videos.\n *\n * Includes:\n * - blob permissions for image/* and video/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.MEDIA_UPLOAD;\n * ```\n */\n MEDIA_UPLOAD: buildScope(new PermissionBuilder().blob([\"image/*\", \"video/*\"]).build()),\n\n /**\n * Image upload only scope - allows uploading images.\n *\n * Includes:\n * - blob:image/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.IMAGE_UPLOAD;\n * ```\n */\n IMAGE_UPLOAD: buildScope(new PermissionBuilder().blob(\"image/*\").build()),\n\n /**\n * Posting app scope - full posting capabilities including media.\n *\n * Includes:\n * - repo:app.bsky.feed.post (create + update)\n * - repo:app.bsky.feed.like (create + update)\n * - repo:app.bsky.feed.repost (create + update)\n * - blob permissions for image/* and video/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.POSTING_APP;\n * ```\n */\n POSTING_APP: buildScope(\n new PermissionBuilder()\n .repoWrite(\"app.bsky.feed.post\")\n .repoWrite(\"app.bsky.feed.like\")\n .repoWrite(\"app.bsky.feed.repost\")\n .blob([\"image/*\", \"video/*\"])\n .build(),\n ),\n\n /**\n * Read-only app scope - allows reading all repository data.\n *\n * Includes:\n * - repo:* (read-only, no actions)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.READ_ONLY;\n * ```\n */\n READ_ONLY: buildScope(new PermissionBuilder().repoRead(\"*\").build()),\n\n /**\n * Full access scope - allows all repository operations.\n *\n * Includes:\n * - repo:* (create + update + delete)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.FULL_ACCESS;\n * ```\n */\n FULL_ACCESS: buildScope(new PermissionBuilder().repoFull(\"*\").build()),\n\n /**\n * Email + Profile scope - common combination for user identification.\n *\n * Includes:\n * - account:email?action=read\n * - repo:app.bsky.actor.profile (read-only)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.EMAIL_AND_PROFILE;\n * ```\n */\n EMAIL_AND_PROFILE: buildScope(\n new PermissionBuilder().accountEmail(\"read\").repoRead(\"app.bsky.actor.profile\").build(),\n ),\n\n /**\n * Transitional email scope (legacy).\n *\n * Uses the transitional scope format for backward compatibility.\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.TRANSITION_EMAIL;\n * ```\n */\n TRANSITION_EMAIL: buildScope(new PermissionBuilder().transition(\"email\").build()),\n\n /**\n * Transitional generic scope (legacy).\n *\n * Uses the transitional scope format for backward compatibility.\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.TRANSITION_GENERIC;\n * ```\n */\n TRANSITION_GENERIC: buildScope(new PermissionBuilder().transition(\"generic\").build()),\n} as const;\n\n/**\n * Parse a scope string into an array of individual permissions.\n *\n * This splits a space-separated scope string into individual permission strings.\n *\n * @param scope - Space-separated scope string\n * @returns Array of permission strings\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post\";\n * const permissions = parseScope(scope);\n * // Returns: ['account:email?action=read', 'repo:app.bsky.feed.post']\n * ```\n */\nexport function parseScope(scope: string): string[] {\n return scope.trim().split(/\\s+/).filter(Boolean);\n}\n\n/**\n * Check if a scope string contains a specific permission.\n *\n * This function performs exact string matching. For more advanced\n * permission checking (e.g., wildcard matching), you'll need to\n * implement custom logic.\n *\n * @param scope - Space-separated scope string\n * @param permission - The permission to check for\n * @returns True if the scope contains the permission\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post\";\n * hasPermission(scope, \"account:email?action=read\"); // true\n * hasPermission(scope, \"account:repo\"); // false\n * ```\n */\nexport function hasPermission(scope: string, permission: string): boolean {\n const permissions = parseScope(scope);\n return permissions.includes(permission);\n}\n\n/**\n * Check if a scope string contains all of the specified permissions.\n *\n * @param scope - Space-separated scope string\n * @param requiredPermissions - Array of permissions to check for\n * @returns True if the scope contains all required permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post blob:image/*\";\n * hasAllPermissions(scope, [\"account:email?action=read\", \"blob:image/*\"]); // true\n * hasAllPermissions(scope, [\"account:email?action=read\", \"account:repo\"]); // false\n * ```\n */\nexport function hasAllPermissions(scope: string, requiredPermissions: string[]): boolean {\n const permissions = parseScope(scope);\n return requiredPermissions.every((required) => permissions.includes(required));\n}\n\n/**\n * Check if a scope string contains any of the specified permissions.\n *\n * @param scope - Space-separated scope string\n * @param checkPermissions - Array of permissions to check for\n * @returns True if the scope contains at least one of the permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post\";\n * hasAnyPermission(scope, [\"account:email?action=read\", \"account:repo\"]); // true\n * hasAnyPermission(scope, [\"account:repo\", \"identity:handle\"]); // false\n * ```\n */\nexport function hasAnyPermission(scope: string, checkPermissions: string[]): boolean {\n const permissions = parseScope(scope);\n return checkPermissions.some((check) => permissions.includes(check));\n}\n\n/**\n * Merge multiple scope strings into a single scope string with deduplicated permissions.\n *\n * @param scopes - Array of scope strings to merge\n * @returns Merged scope string with unique permissions\n *\n * @example\n * ```typescript\n * const scope1 = \"account:email?action=read repo:app.bsky.feed.post\";\n * const scope2 = \"repo:app.bsky.feed.post blob:image/*\";\n * const merged = mergeScopes([scope1, scope2]);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post blob:image/*\"\n * ```\n */\nexport function mergeScopes(scopes: string[]): string {\n const allPermissions = scopes.flatMap(parseScope);\n const uniquePermissions = [...new Set(allPermissions)];\n return buildScope(uniquePermissions);\n}\n\n/**\n * Remove specific permissions from a scope string.\n *\n * @param scope - Space-separated scope string\n * @param permissionsToRemove - Array of permissions to remove\n * @returns New scope string without the specified permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post blob:image/*\";\n * const filtered = removePermissions(scope, [\"blob:image/*\"]);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post\"\n * ```\n */\nexport function removePermissions(scope: string, permissionsToRemove: string[]): string {\n const permissions = parseScope(scope);\n const filtered = permissions.filter((p) => !permissionsToRemove.includes(p));\n return buildScope(filtered);\n}\n\n/**\n * Validate that all permissions in a scope string are well-formed.\n *\n * This checks that each permission matches expected patterns for transitional\n * or granular permissions. It does NOT validate against the full Zod schemas.\n *\n * @param scope - Space-separated scope string\n * @returns Object with isValid flag and array of invalid permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read invalid:permission\";\n * const result = validateScope(scope);\n * // Returns: { isValid: false, invalidPermissions: ['invalid:permission'] }\n * ```\n */\nexport function validateScope(scope: string): {\n isValid: boolean;\n invalidPermissions: string[];\n} {\n const permissions = parseScope(scope);\n const invalidPermissions: string[] = [];\n\n // Pattern for valid permission prefixes\n const validPrefixes = /^(atproto|transition:|account:|repo:|blob:?|rpc:|identity:|include:)/;\n\n for (const permission of permissions) {\n if (!validPrefixes.test(permission)) {\n invalidPermissions.push(permission);\n }\n }\n\n return {\n isValid: invalidPermissions.length === 0,\n invalidPermissions,\n };\n}\n","import { NodeOAuthClient, JoseKey, type NodeSavedSession } from \"@atproto/oauth-client-node\";\nimport type { SessionStore, StateStore, LoggerInterface } from \"../core/interfaces.js\";\nimport type { ATProtoSDKConfig } from \"../core/config.js\";\nimport { AuthenticationError, NetworkError } from \"../core/errors.js\";\nimport { InMemorySessionStore } from \"../storage/InMemorySessionStore.js\";\nimport { InMemoryStateStore } from \"../storage/InMemoryStateStore.js\";\nimport { parseScope, validateScope, ATPROTO_SCOPE } from \"./permissions.js\";\n\n/**\n * Options for the OAuth authorization flow.\n *\n * @internal\n */\ninterface AuthorizeOptions {\n /**\n * OAuth scope string to request specific permissions.\n * Overrides the default scope from the SDK configuration.\n */\n scope?: string;\n}\n\n/**\n * OAuth 2.0 client for AT Protocol authentication with DPoP support.\n *\n * This class wraps the `@atproto/oauth-client-node` library to provide\n * OAuth 2.0 authentication with the following features:\n *\n * - **DPoP (Demonstrating Proof of Possession)**: Binds tokens to cryptographic keys\n * to prevent token theft and replay attacks\n * - **PKCE (Proof Key for Code Exchange)**: Protects against authorization code interception\n * - **Automatic Token Refresh**: Transparently refreshes expired access tokens\n * - **Session Persistence**: Stores sessions in configurable storage backends\n *\n * @remarks\n * This class is typically used internally by {@link ATProtoSDK}. Direct usage\n * is only needed for advanced scenarios.\n *\n * The client uses lazy initialization - the underlying `NodeOAuthClient` is\n * created asynchronously on first use. This allows the constructor to return\n * synchronously while deferring async key parsing.\n *\n * @example Direct usage (advanced)\n * ```typescript\n * import { OAuthClient } from \"@hypercerts-org/sdk\";\n *\n * const client = new OAuthClient({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: { pds: \"https://bsky.social\" },\n * });\n *\n * // Start authorization\n * const authUrl = await client.authorize(\"user.bsky.social\");\n *\n * // Handle callback\n * const session = await client.callback(new URLSearchParams(callbackUrl.search));\n * ```\n *\n * @see {@link ATProtoSDK} for the recommended high-level API\n * @see https://atproto.com/specs/oauth for AT Protocol OAuth specification\n */\nexport class OAuthClient {\n /** The underlying NodeOAuthClient instance (lazily initialized) */\n private client: NodeOAuthClient | null = null;\n\n /** Promise that resolves to the initialized client */\n private clientPromise: Promise<NodeOAuthClient>;\n\n /** SDK configuration */\n private config: ATProtoSDKConfig;\n\n /** Optional logger for debugging */\n private logger?: LoggerInterface;\n\n /**\n * Creates a new OAuth client.\n *\n * @param config - SDK configuration including OAuth credentials and server URLs\n * @throws {@link AuthenticationError} if the JWK private key is not valid JSON\n *\n * @remarks\n * The constructor validates the JWK format synchronously but defers\n * the actual client initialization to the first API call.\n */\n constructor(config: ATProtoSDKConfig) {\n this.config = config;\n this.logger = config.logger;\n\n // Validate JWK format synchronously (before async initialization)\n try {\n JSON.parse(config.oauth.jwkPrivate);\n } catch (error) {\n throw new AuthenticationError(\"Failed to parse JWK private key. Ensure it is valid JSON.\", error);\n }\n\n // Initialize client lazily (async initialization)\n this.clientPromise = this.initializeClient();\n }\n\n /**\n * Initializes the NodeOAuthClient asynchronously.\n *\n * This method is called lazily on first use. It:\n * 1. Parses the JWK private key(s)\n * 2. Builds OAuth client metadata\n * 3. Creates the underlying NodeOAuthClient\n *\n * @returns Promise resolving to the initialized client\n * @internal\n */\n private async initializeClient(): Promise<NodeOAuthClient> {\n if (this.client) {\n return this.client;\n }\n\n // Parse JWK private key (already validated in constructor)\n const privateJWK = JSON.parse(this.config.oauth.jwkPrivate) as {\n keys: Array<{ kid: string; [key: string]: unknown }>;\n };\n\n // Build client metadata\n const clientMetadata = this.buildClientMetadata();\n\n // Convert JWK keys to JoseKey instances (await here)\n const keyset = await Promise.all(\n privateJWK.keys.map((key) =>\n JoseKey.fromImportable(key as unknown as Parameters<typeof JoseKey.fromImportable>[0], key.kid),\n ),\n );\n\n // Create fetch with timeout\n const fetchWithTimeout = this.createFetchWithTimeout(this.config.timeouts?.pdsMetadata ?? 30000);\n\n // Use provided stores or fall back to in-memory implementations\n const stateStore = this.config.storage?.stateStore ?? new InMemoryStateStore();\n const sessionStore = this.config.storage?.sessionStore ?? new InMemorySessionStore();\n\n this.client = new NodeOAuthClient({\n clientMetadata,\n keyset,\n stateStore: this.createStateStoreAdapter(stateStore),\n sessionStore: this.createSessionStoreAdapter(sessionStore),\n handleResolver: this.config.servers?.pds,\n fetch: this.config.fetch ?? fetchWithTimeout,\n });\n\n return this.client;\n }\n\n /**\n * Gets the OAuth client instance, initializing if needed.\n *\n * @returns Promise resolving to the initialized client\n * @internal\n */\n private async getClient(): Promise<NodeOAuthClient> {\n return this.clientPromise;\n }\n\n /**\n * Builds OAuth client metadata from configuration.\n *\n * The metadata describes your application to the authorization server\n * and must match what's published at your `clientId` URL.\n *\n * @returns OAuth client metadata object\n * @internal\n *\n * @remarks\n * Key metadata fields:\n * - `client_id`: URL to your client metadata JSON\n * - `redirect_uris`: Where to redirect after auth (must match config)\n * - `dpop_bound_access_tokens`: Always true for AT Protocol\n * - `token_endpoint_auth_method`: Uses private_key_jwt for security\n */\n private buildClientMetadata() {\n const clientIdUrl = new URL(this.config.oauth.clientId);\n const metadata = {\n client_id: this.config.oauth.clientId,\n client_name: \"ATProto SDK Client\",\n client_uri: clientIdUrl.origin,\n redirect_uris: [this.config.oauth.redirectUri] as [string, ...string[]],\n scope: this.config.oauth.scope,\n grant_types: [\"authorization_code\", \"refresh_token\"] as [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"] as [\"code\"],\n application_type: \"web\" as const,\n token_endpoint_auth_method: \"private_key_jwt\" as const,\n token_endpoint_auth_signing_alg: \"ES256\",\n dpop_bound_access_tokens: true,\n jwks_uri: this.config.oauth.jwksUri,\n } as const;\n\n // Validate scope before returning metadata\n this.validateClientMetadataScope(metadata.scope);\n\n return metadata;\n }\n\n /**\n * Validates the OAuth scope in client metadata and logs warnings/suggestions.\n *\n * This method:\n * 1. Checks if the scope is well-formed using permission utilities\n * 2. Detects mixing of transitional and granular permissions\n * 3. Logs warnings for missing `atproto` scope\n * 4. Suggests migration to granular permissions for transitional scopes\n *\n * @param scope - The OAuth scope string to validate\n * @internal\n */\n private validateClientMetadataScope(scope: string): void {\n // Parse the scope into individual permissions\n const permissions = parseScope(scope);\n\n // Validate well-formedness\n const validation = validateScope(scope);\n if (!validation.isValid) {\n this.logger?.error(\"Invalid OAuth scope detected\", {\n invalidPermissions: validation.invalidPermissions,\n scope,\n });\n }\n\n // Check for atproto scope\n const hasAtproto = permissions.includes(ATPROTO_SCOPE);\n if (!hasAtproto) {\n this.logger?.warn(\"OAuth scope missing 'atproto' - basic API access may be limited\", {\n scope,\n suggestion: \"Add 'atproto' to your scope for basic API access\",\n });\n }\n\n // Detect transitional scopes\n const transitionalScopes = permissions.filter((p) => p.startsWith(\"transition:\"));\n const granularScopes = permissions.filter(\n (p) =>\n p.startsWith(\"account:\") ||\n p.startsWith(\"repo:\") ||\n p.startsWith(\"blob\") ||\n p.startsWith(\"rpc:\") ||\n p.startsWith(\"identity:\") ||\n p.startsWith(\"include:\"),\n );\n\n // Log info about transitional scopes\n if (transitionalScopes.length > 0) {\n this.logger?.info(\"Using transitional OAuth scopes (legacy)\", {\n transitionalScopes,\n note: \"Transitional scopes are supported but granular permissions are recommended\",\n });\n\n // Suggest migration to granular permissions\n if (transitionalScopes.includes(\"transition:email\")) {\n this.logger?.info(\"Consider migrating 'transition:email' to granular permissions\", {\n suggestion: \"Use: account:email?action=read\",\n example: \"import { ScopePresets } from '@hypercerts-org/sdk-core'; scope: ScopePresets.EMAIL_READ\",\n });\n }\n if (transitionalScopes.includes(\"transition:generic\")) {\n this.logger?.info(\"Consider migrating 'transition:generic' to granular permissions\", {\n suggestion: \"Use specific permissions like: repo:* account:repo?action=read\",\n example: \"import { ScopePresets } from '@hypercerts-org/sdk-core'; scope: ScopePresets.FULL_ACCESS\",\n });\n }\n }\n\n // Warn if mixing transitional and granular\n if (transitionalScopes.length > 0 && granularScopes.length > 0) {\n this.logger?.warn(\"Mixing transitional and granular OAuth scopes\", {\n transitionalScopes,\n granularScopes,\n note: \"While supported, it's recommended to use either transitional or granular permissions consistently\",\n });\n }\n }\n\n /**\n * Creates a fetch handler with timeout support.\n *\n * @param timeoutMs - Request timeout in milliseconds\n * @returns A fetch function that aborts after the timeout\n * @internal\n */\n private createFetchWithTimeout(timeoutMs: number): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(input, {\n ...init,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(`Request timeout after ${timeoutMs}ms`, error);\n }\n throw new NetworkError(\"Network request failed\", error);\n }\n };\n }\n\n /**\n * Creates a state store adapter compatible with NodeOAuthClient.\n *\n * @param store - The StateStore implementation to adapt\n * @returns An adapter compatible with NodeOAuthClient\n * @internal\n */\n private createStateStoreAdapter(store: StateStore): import(\"@atproto/oauth-client-node\").NodeSavedStateStore {\n return {\n get: (key: string) => store.get(key),\n set: (key: string, value: import(\"@atproto/oauth-client-node\").NodeSavedState) => store.set(key, value),\n del: (key: string) => store.del(key),\n };\n }\n\n /**\n * Creates a session store adapter compatible with NodeOAuthClient.\n *\n * @param store - The SessionStore implementation to adapt\n * @returns An adapter compatible with NodeOAuthClient\n * @internal\n */\n private createSessionStoreAdapter(store: SessionStore): import(\"@atproto/oauth-client-node\").NodeSavedSessionStore {\n return {\n get: (did: string) => store.get(did),\n set: (did: string, session: NodeSavedSession) => store.set(did, session),\n del: (did: string) => store.del(did),\n };\n }\n\n /**\n * Initiates the OAuth authorization flow.\n *\n * This method resolves the user's identity from their identifier,\n * generates PKCE codes, creates OAuth state, and returns an\n * authorization URL to redirect the user to.\n *\n * @param identifier - The user's ATProto identifier. Accepts:\n * - Handle (e.g., `\"alice.bsky.social\"`)\n * - DID (e.g., `\"did:plc:abc123...\"`)\n * - PDS URL (e.g., `\"https://bsky.social\"`)\n * @param options - Optional authorization settings\n * @returns A Promise resolving to the authorization URL\n * @throws {@link AuthenticationError} if authorization setup fails\n * @throws {@link NetworkError} if identity resolution fails\n *\n * @example\n * ```typescript\n * // Get authorization URL\n * const authUrl = await client.authorize(\"user.bsky.social\");\n *\n * // Redirect user (in a web app)\n * window.location.href = authUrl;\n *\n * // Or return to client (in an API)\n * res.json({ authUrl });\n * ```\n */\n async authorize(identifier: string, options?: AuthorizeOptions): Promise<string> {\n try {\n this.logger?.debug(\"Initiating OAuth authorization\", { identifier });\n\n const client = await this.getClient();\n const scope = options?.scope ?? this.config.oauth.scope;\n const authUrl = await client.authorize(identifier, { scope });\n\n this.logger?.debug(\"Authorization URL generated\", { identifier });\n // Convert URL to string if needed\n return typeof authUrl === \"string\" ? authUrl : authUrl.toString();\n } catch (error) {\n this.logger?.error(\"Authorization failed\", { identifier, error });\n if (error instanceof NetworkError || error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Failed to initiate authorization: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Handles the OAuth callback and exchanges the authorization code for tokens.\n *\n * Call this method when the user is redirected back to your application.\n * It validates the state, exchanges the code for tokens, and creates\n * a persistent session.\n *\n * @param params - URL search parameters from the callback. Expected parameters:\n * - `code`: The authorization code\n * - `state`: The state parameter (for CSRF protection)\n * - `iss`: The issuer (authorization server URL)\n * @returns A Promise resolving to the authenticated OAuth session\n * @throws {@link AuthenticationError} if:\n * - The callback contains an OAuth error\n * - The state is invalid or expired\n * - The code exchange fails\n * - Session persistence fails\n *\n * @example\n * ```typescript\n * // In your callback route handler\n * app.get(\"/callback\", async (req, res) => {\n * const params = new URLSearchParams(req.url.split(\"?\")[1]);\n *\n * try {\n * const session = await client.callback(params);\n * // Store DID for session restoration\n * req.session.userDid = session.sub;\n * res.redirect(\"/dashboard\");\n * } catch (error) {\n * res.redirect(\"/login?error=auth_failed\");\n * }\n * });\n * ```\n *\n * @remarks\n * After successful token exchange, this method verifies that the session\n * was properly persisted by attempting to restore it. This ensures the\n * storage backend is working correctly.\n */\n async callback(params: URLSearchParams): Promise<import(\"@atproto/oauth-client\").OAuthSession> {\n try {\n this.logger?.debug(\"Processing OAuth callback\");\n\n // Check for OAuth errors\n const error = params.get(\"error\");\n if (error) {\n const errorDescription = params.get(\"error_description\");\n throw new AuthenticationError(errorDescription || error);\n }\n\n const client = await this.getClient();\n const result = await client.callback(params);\n const session = result.session;\n const did = session.sub;\n\n this.logger?.info(\"OAuth callback successful\", { did });\n\n // Verify session can be restored (validates persistence)\n try {\n const restored = await client.restore(did);\n if (!restored) {\n throw new AuthenticationError(\"OAuth session was not persisted\");\n }\n this.logger?.debug(\"Session verified and restorable\", { did });\n } catch (restoreError) {\n this.logger?.error(\"Failed to verify persisted session\", {\n did,\n error: restoreError,\n });\n throw new AuthenticationError(\"Failed to persist OAuth session\", restoreError);\n }\n\n return session;\n } catch (error) {\n this.logger?.error(\"OAuth callback failed\", { error });\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `OAuth callback failed: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Restores an OAuth session by DID.\n *\n * Use this method to restore a previously authenticated session.\n * The method automatically refreshes expired access tokens using\n * the stored refresh token.\n *\n * @param did - The user's Decentralized Identifier (e.g., `\"did:plc:abc123...\"`)\n * @returns A Promise resolving to the session, or `null` if not found\n * @throws {@link AuthenticationError} if session restoration fails (not for missing sessions)\n * @throws {@link NetworkError} if token refresh requires network and fails\n *\n * @example\n * ```typescript\n * // On application startup or request\n * const userDid = req.session.userDid;\n * if (userDid) {\n * const session = await client.restore(userDid);\n * if (session) {\n * // Session restored, user is authenticated\n * req.atprotoSession = session;\n * } else {\n * // No session found, user needs to log in\n * delete req.session.userDid;\n * }\n * }\n * ```\n *\n * @remarks\n * Token refresh is handled automatically by the underlying OAuth client.\n * If the refresh token has expired or been revoked, this method will\n * throw an {@link AuthenticationError}.\n */\n async restore(did: string): Promise<import(\"@atproto/oauth-client\").OAuthSession | null> {\n try {\n this.logger?.debug(\"Restoring session\", { did });\n\n const client = await this.getClient();\n const session = await client.restore(did);\n\n if (session) {\n this.logger?.debug(\"Session restored\", { did });\n } else {\n this.logger?.debug(\"No session found\", { did });\n }\n\n return session;\n } catch (error) {\n this.logger?.error(\"Failed to restore session\", { did, error });\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new AuthenticationError(\n `Failed to restore session: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Revokes an OAuth session.\n *\n * This method invalidates the session's tokens both locally and\n * (if supported) on the authorization server. After revocation,\n * the session cannot be restored.\n *\n * @param did - The user's DID to revoke\n * @throws {@link AuthenticationError} if revocation fails\n *\n * @example\n * ```typescript\n * // Log out endpoint\n * app.post(\"/logout\", async (req, res) => {\n * const userDid = req.session.userDid;\n * if (userDid) {\n * await client.revoke(userDid);\n * delete req.session.userDid;\n * }\n * res.redirect(\"/\");\n * });\n * ```\n *\n * @remarks\n * Even if revocation fails on the server, the local session is\n * removed. The error is thrown to inform you that remote revocation\n * may not have succeeded.\n */\n async revoke(did: string): Promise<void> {\n try {\n this.logger?.debug(\"Revoking session\", { did });\n\n const client = await this.getClient();\n await client.revoke(did);\n\n this.logger?.info(\"Session revoked\", { did });\n } catch (error) {\n this.logger?.error(\"Failed to revoke session\", { did, error });\n throw new AuthenticationError(\n `Failed to revoke session: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n}\n","/**\n * ConfigurableAgent - Agent with configurable service URL routing.\n *\n * This module provides an Agent extension that allows routing requests to\n * a specific server URL, overriding the default URL from the OAuth session.\n *\n * @packageDocumentation\n */\n\nimport { Agent } from \"@atproto/api\";\nimport type { Session } from \"../core/types.js\";\n\n/**\n * FetchHandler type - function that makes HTTP requests with authentication.\n * Takes a pathname and request init, returns a Response promise.\n */\ntype FetchHandler = (pathname: string, init: RequestInit) => Promise<Response>;\n\n/**\n * Agent subclass that routes requests to a configurable service URL.\n *\n * The standard Agent uses the service URL embedded in the OAuth session's\n * fetch handler. This class allows overriding that URL to route requests\n * to different servers (e.g., PDS vs SDS, or multiple SDS instances).\n *\n * @remarks\n * This is particularly useful for:\n * - Routing to a Shared Data Server (SDS) while authenticated via PDS\n * - Supporting multiple SDS instances for different organizations\n * - Testing against different server environments\n *\n * @example Basic usage\n * ```typescript\n * const session = await sdk.authorize(\"user.bsky.social\");\n *\n * // Create agent routing to SDS instead of session's default PDS\n * const sdsAgent = new ConfigurableAgent(session, \"https://sds.hypercerts.org\");\n *\n * // All requests will now go to the SDS\n * await sdsAgent.com.atproto.repo.createRecord({...});\n * ```\n *\n * @example Multiple SDS instances\n * ```typescript\n * // Route to organization A's SDS\n * const orgAAgent = new ConfigurableAgent(session, \"https://sds-org-a.example.com\");\n *\n * // Route to organization B's SDS\n * const orgBAgent = new ConfigurableAgent(session, \"https://sds-org-b.example.com\");\n * ```\n */\nexport class ConfigurableAgent extends Agent {\n private customServiceUrl: string;\n\n /**\n * Creates a ConfigurableAgent that routes to a specific service URL.\n *\n * @param session - OAuth session for authentication\n * @param serviceUrl - Base URL of the server to route requests to\n *\n * @remarks\n * The agent wraps the session's fetch handler to intercept requests and\n * prepend the custom service URL instead of using the session's default.\n */\n constructor(session: Session, serviceUrl: string) {\n // Create a custom fetch handler that uses our service URL\n const customFetchHandler: FetchHandler = async (pathname: string, init: RequestInit) => {\n // Construct the full URL with our custom service\n const url = new URL(pathname, serviceUrl).toString();\n\n // Use the session's fetch handler for authentication (DPoP, etc.)\n return session.fetchHandler(url, init);\n };\n\n // Initialize the parent Agent with our custom fetch handler\n super(customFetchHandler);\n\n this.customServiceUrl = serviceUrl;\n }\n\n /**\n * Gets the service URL this agent routes to.\n *\n * @returns The base URL of the configured service\n */\n getServiceUrl(): string {\n return this.customServiceUrl;\n }\n}\n","/**\n * RecordOperationsImpl - Low-level record CRUD operations.\n *\n * This module provides the implementation for direct AT Protocol\n * record operations (create, read, update, delete, list).\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError, ValidationError } from \"../core/errors.js\";\nimport type { RecordOperations } from \"./interfaces.js\";\nimport type { CreateResult, UpdateResult, PaginatedList } from \"./types.js\";\n\n/**\n * Implementation of low-level AT Protocol record operations.\n *\n * This class provides direct access to the AT Protocol repository API\n * for CRUD operations on records. It handles:\n *\n * - Lexicon validation before create/update operations\n * - Error mapping to SDK error types\n * - Response normalization\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.records}.\n *\n * All operations are performed against the repository DID specified\n * at construction time. To operate on a different repository, create\n * a new Repository instance using {@link Repository.repo}.\n *\n * @example\n * ```typescript\n * // Access through Repository\n * const repo = sdk.repository(session);\n *\n * // Create a record\n * const { uri, cid } = await repo.records.create({\n * collection: \"org.example.myRecord\",\n * record: { title: \"Hello\", createdAt: new Date().toISOString() },\n * });\n *\n * // Update the record\n * const rkey = uri.split(\"/\").pop()!;\n * await repo.records.update({\n * collection: \"org.example.myRecord\",\n * rkey,\n * record: { title: \"Updated\", createdAt: new Date().toISOString() },\n * });\n * ```\n *\n * @internal\n */\nexport class RecordOperationsImpl implements RecordOperations {\n /**\n * Creates a new RecordOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository to operate on\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n ) {}\n\n /**\n * Creates a new record in the specified collection.\n *\n * @param params - Creation parameters\n * @param params.collection - NSID of the collection (e.g., \"org.hypercerts.hypercert\")\n * @param params.record - Record data conforming to the collection's lexicon schema\n * @param params.rkey - Optional record key. If not provided, a TID (timestamp-based ID)\n * is automatically generated by the server.\n * @returns Promise resolving to the created record's URI and CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @remarks\n * The record is validated against the collection's lexicon before sending\n * to the server. If no lexicon is registered for the collection, validation\n * is skipped (allowing custom record types).\n *\n * **AT-URI Format**: `at://{did}/{collection}/{rkey}`\n *\n * @example\n * ```typescript\n * const result = await repo.records.create({\n * collection: \"org.hypercerts.hypercert\",\n * record: {\n * title: \"My Hypercert\",\n * description: \"...\",\n * createdAt: new Date().toISOString(),\n * },\n * });\n * console.log(`Created: ${result.uri}`);\n * // Output: Created: at://did:plc:abc123/org.hypercerts.hypercert/xyz789\n * ```\n */\n async create(params: { collection: string; record: unknown; rkey?: string }): Promise<CreateResult> {\n try {\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: params.collection,\n record: params.record as Record<string, unknown>,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates an existing record (full replacement).\n *\n * @param params - Update parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key (the last segment of the AT-URI)\n * @param params.record - New record data (completely replaces existing record)\n * @returns Promise resolving to the updated record's URI and new CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @remarks\n * This is a full replacement operation, not a partial update. The entire\n * record is replaced with the new data. To preserve existing fields,\n * first fetch the record with {@link get}, modify it, then update.\n *\n * @example\n * ```typescript\n * // Get existing record\n * const existing = await repo.records.get({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n *\n * // Update with modified data\n * const updated = await repo.records.update({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * record: {\n * ...existing.value,\n * title: \"Updated Title\",\n * },\n * });\n * ```\n */\n async update(params: { collection: string; rkey: string; record: unknown }): Promise<UpdateResult> {\n try {\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n record: params.record as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a single record by collection and key.\n *\n * @param params - Get parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key\n * @returns Promise resolving to the record's URI, CID, and value\n * @throws {@link NetworkError} if the record is not found or request fails\n *\n * @example\n * ```typescript\n * const record = await repo.records.get({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n *\n * console.log(record.uri); // at://did:plc:abc123/org.hypercerts.hypercert/xyz789\n * console.log(record.cid); // bafyrei...\n * console.log(record.value); // { title: \"...\", description: \"...\", ... }\n * ```\n */\n async get(params: { collection: string; rkey: string }): Promise<{ uri: string; cid: string; value: unknown }> {\n try {\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid ?? \"\", value: result.data.value };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to get record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Lists records in a collection with pagination.\n *\n * @param params - List parameters\n * @param params.collection - NSID of the collection\n * @param params.limit - Maximum number of records to return (server may impose its own limit)\n * @param params.cursor - Pagination cursor from a previous response\n * @returns Promise resolving to paginated list of records\n * @throws {@link NetworkError} if the request fails\n *\n * @remarks\n * Records are returned in reverse chronological order (newest first).\n * Use the `cursor` from the response to fetch subsequent pages.\n *\n * @example Paginating through all records\n * ```typescript\n * let cursor: string | undefined;\n * const allRecords = [];\n *\n * do {\n * const page = await repo.records.list({\n * collection: \"org.hypercerts.hypercert\",\n * limit: 100,\n * cursor,\n * });\n * allRecords.push(...page.records);\n * cursor = page.cursor;\n * } while (cursor);\n *\n * console.log(`Total records: ${allRecords.length}`);\n * ```\n */\n async list(params: {\n collection: string;\n limit?: number;\n cursor?: string;\n }): Promise<PaginatedList<{ uri: string; cid: string; value: unknown }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: params.collection,\n limit: params.limit,\n cursor: params.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list records\");\n }\n\n return {\n records: result.data.records?.map((r) => ({ uri: r.uri, cid: r.cid, value: r.value })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to list records: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Deletes a record from a collection.\n *\n * @param params - Delete parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key to delete\n * @throws {@link NetworkError} if the deletion fails\n *\n * @remarks\n * Deletion is permanent. The record's AT-URI cannot be reused (the same\n * rkey can be used for a new record, but it will have a different CID).\n *\n * @example\n * ```typescript\n * await repo.records.delete({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n * ```\n */\n async delete(params: { collection: string; rkey: string }): Promise<void> {\n try {\n const result = await this.agent.com.atproto.repo.deleteRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to delete record\");\n }\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to delete record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n}\n","/**\n * BlobOperationsImpl - Blob upload and retrieval operations.\n *\n * This module provides the implementation for AT Protocol blob operations,\n * handling binary data like images and files.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError } from \"../core/errors.js\";\nimport type { BlobOperations } from \"./interfaces.js\";\n\n/**\n * Implementation of blob operations for binary data handling.\n *\n * Blobs in AT Protocol are content-addressed binary objects stored\n * separately from records. They are referenced in records using a\n * blob reference object with a CID ($link).\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.blobs}.\n *\n * **Blob Size Limits**: PDS servers typically impose size limits on blobs.\n * Common limits are:\n * - Images: 1MB\n * - Other files: Varies by server configuration\n *\n * **Supported MIME Types**: Any MIME type is technically supported, but\n * servers may reject certain types. Images (JPEG, PNG, GIF, WebP) are\n * universally supported.\n *\n * @example\n * ```typescript\n * // Upload an image blob\n * const imageBlob = new Blob([imageData], { type: \"image/jpeg\" });\n * const { ref, mimeType, size } = await repo.blobs.upload(imageBlob);\n *\n * // Use the ref in a record\n * await repo.records.create({\n * collection: \"org.example.post\",\n * record: {\n * text: \"Check out this image!\",\n * image: ref, // { $link: \"bafyrei...\" }\n * createdAt: new Date().toISOString(),\n * },\n * });\n * ```\n *\n * @internal\n */\nexport class BlobOperationsImpl implements BlobOperations {\n /**\n * Creates a new BlobOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository (used for blob retrieval)\n * @param _serverUrl - Server URL (reserved for future use)\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n ) {}\n\n /**\n * Uploads a blob to the server.\n *\n * @param blob - The blob to upload (File or Blob object)\n * @returns Promise resolving to blob reference and metadata\n * @throws {@link NetworkError} if the upload fails\n *\n * @remarks\n * The returned `ref` object should be used directly in records to\n * reference the blob. The `$link` property contains the blob's CID.\n *\n * **MIME Type Detection**: If the blob has no type, it defaults to\n * `application/octet-stream`. For best results, always specify the\n * correct MIME type when creating the Blob.\n *\n * @example Uploading an image\n * ```typescript\n * // From a File input\n * const file = fileInput.files[0];\n * const { ref } = await repo.blobs.upload(file);\n *\n * // From raw data\n * const imageBlob = new Blob([uint8Array], { type: \"image/png\" });\n * const { ref, mimeType, size } = await repo.blobs.upload(imageBlob);\n *\n * console.log(`Uploaded ${size} bytes of ${mimeType}`);\n * console.log(`CID: ${ref.$link}`);\n * ```\n *\n * @example Using in a hypercert\n * ```typescript\n * const coverImage = new Blob([imageData], { type: \"image/jpeg\" });\n * const { ref } = await repo.blobs.upload(coverImage);\n *\n * // The ref is used directly in the record\n * await repo.hypercerts.create({\n * title: \"My Hypercert\",\n * // ... other fields\n * image: coverImage, // HypercertOperations handles upload internally\n * });\n * ```\n */\n async upload(blob: Blob): Promise<{ ref: { $link: string }; mimeType: string; size: number }> {\n try {\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n const result = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: blob.type || \"application/octet-stream\",\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to upload blob\");\n }\n\n return {\n ref: { $link: result.data.blob.ref.toString() },\n mimeType: result.data.blob.mimeType,\n size: result.data.blob.size,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to upload blob: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Retrieves a blob by its CID.\n *\n * @param cid - Content Identifier (CID) of the blob, typically from a blob\n * reference's `$link` property\n * @returns Promise resolving to blob data and MIME type\n * @throws {@link NetworkError} if the blob is not found or retrieval fails\n *\n * @remarks\n * The returned data is a Uint8Array which can be converted to other\n * formats as needed (Blob, ArrayBuffer, Base64, etc.).\n *\n * **MIME Type**: The returned MIME type comes from the Content-Type header.\n * If the server doesn't provide one, it defaults to `application/octet-stream`.\n *\n * @example Basic retrieval\n * ```typescript\n * // Get a blob from a record's blob reference\n * const record = await repo.records.get({ collection, rkey });\n * const blobRef = (record.value as any).image;\n *\n * const { data, mimeType } = await repo.blobs.get(blobRef.$link);\n *\n * // Convert to a Blob for use in the browser\n * const blob = new Blob([data], { type: mimeType });\n * const url = URL.createObjectURL(blob);\n * ```\n *\n * @example Displaying an image\n * ```typescript\n * const { data, mimeType } = await repo.blobs.get(imageCid);\n *\n * // Create data URL for <img> src\n * const base64 = btoa(String.fromCharCode(...data));\n * const dataUrl = `data:${mimeType};base64,${base64}`;\n *\n * // Or use object URL\n * const blob = new Blob([data], { type: mimeType });\n * img.src = URL.createObjectURL(blob);\n * ```\n */\n async get(cid: string): Promise<{ data: Uint8Array; mimeType: string }> {\n try {\n const result = await this.agent.com.atproto.sync.getBlob({\n did: this.repoDid,\n cid,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get blob\");\n }\n\n return {\n data: result.data,\n mimeType: result.headers[\"content-type\"] || \"application/octet-stream\",\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get blob: ${error instanceof Error ? error.message : \"Unknown error\"}`, error);\n }\n }\n}\n","/**\n * ProfileOperationsImpl - User profile operations.\n *\n * This module provides the implementation for AT Protocol profile\n * management, including fetching and updating user profiles.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError } from \"../core/errors.js\";\nimport type { ProfileOperations } from \"./interfaces.js\";\nimport type { UpdateResult } from \"./types.js\";\n\n/**\n * Implementation of profile operations for user profile management.\n *\n * Profiles in AT Protocol are stored as records in the `app.bsky.actor.profile`\n * collection with the special rkey \"self\". This class provides a convenient\n * API for reading and updating profile data.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.profile}.\n *\n * **Profile Fields**:\n * - `handle`: Read-only, managed by the PDS\n * - `displayName`: User's display name (max 64 chars typically)\n * - `description`: Profile bio (max 256 chars typically)\n * - `avatar`: Profile picture blob reference\n * - `banner`: Banner image blob reference\n * - `website`: User's website URL (may not be available on all servers)\n *\n * @example\n * ```typescript\n * // Get profile\n * const profile = await repo.profile.get();\n * console.log(`${profile.displayName} (@${profile.handle})`);\n *\n * // Update profile\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"Updated bio\",\n * });\n *\n * // Update with new avatar\n * const avatarBlob = new Blob([imageData], { type: \"image/png\" });\n * await repo.profile.update({ avatar: avatarBlob });\n *\n * // Remove a field\n * await repo.profile.update({ website: null });\n * ```\n *\n * @internal\n */\nexport class ProfileOperationsImpl implements ProfileOperations {\n /**\n * Creates a new ProfileOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository/user\n * @param _serverUrl - Server URL (reserved for future use)\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n ) {}\n\n /**\n * Gets the repository's profile.\n *\n * @returns Promise resolving to profile data\n * @throws {@link NetworkError} if the profile cannot be fetched\n *\n * @remarks\n * This method fetches the full profile using the `getProfile` API,\n * which includes resolved information like follower counts on some\n * servers. For hypercerts SDK usage, the basic profile fields are\n * returned.\n *\n * **Note**: The `website` field may not be available on all AT Protocol\n * servers. Standard Bluesky profiles don't include this field.\n *\n * @example\n * ```typescript\n * const profile = await repo.profile.get();\n *\n * console.log(`Handle: @${profile.handle}`);\n * console.log(`Name: ${profile.displayName || \"(not set)\"}`);\n * console.log(`Bio: ${profile.description || \"(no bio)\"}`);\n *\n * if (profile.avatar) {\n * // Avatar is a URL or blob reference\n * console.log(`Avatar: ${profile.avatar}`);\n * }\n * ```\n */\n async get(): Promise<{\n handle: string;\n displayName?: string;\n description?: string;\n avatar?: string;\n banner?: string;\n website?: string;\n }> {\n try {\n const result = await this.agent.getProfile({ actor: this.repoDid });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get profile\");\n }\n\n return {\n handle: result.data.handle,\n displayName: result.data.displayName,\n description: result.data.description,\n avatar: result.data.avatar,\n banner: result.data.banner,\n // Note: website may not be available in standard profile\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to get profile: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates the repository's profile.\n *\n * @param params - Fields to update. Pass `null` to remove a field.\n * Omitted fields are preserved from the existing profile.\n * @returns Promise resolving to update result with new URI and CID\n * @throws {@link NetworkError} if the update fails\n *\n * @remarks\n * This method performs a read-modify-write operation:\n * 1. Fetches the existing profile record\n * 2. Merges in the provided updates\n * 3. Writes the updated profile back\n *\n * **Image Handling**: When providing `avatar` or `banner` as a Blob,\n * the image is automatically uploaded and the blob reference is stored\n * in the profile.\n *\n * **Field Removal**: Pass `null` to explicitly remove a field. Omitting\n * a field (not including it in params) preserves the existing value.\n *\n * @example Update display name and bio\n * ```typescript\n * await repo.profile.update({\n * displayName: \"Alice\",\n * description: \"Building impact certificates\",\n * });\n * ```\n *\n * @example Update avatar image\n * ```typescript\n * // From a file input\n * const file = document.getElementById(\"avatar\").files[0];\n * await repo.profile.update({ avatar: file });\n *\n * // From raw data\n * const response = await fetch(\"https://example.com/my-avatar.png\");\n * const blob = await response.blob();\n * await repo.profile.update({ avatar: blob });\n * ```\n *\n * @example Remove description\n * ```typescript\n * // Removes the description field entirely\n * await repo.profile.update({ description: null });\n * ```\n *\n * @example Multiple updates at once\n * ```typescript\n * const newAvatar = new Blob([avatarData], { type: \"image/png\" });\n * const newBanner = new Blob([bannerData], { type: \"image/jpeg\" });\n *\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"New bio\",\n * avatar: newAvatar,\n * banner: newBanner,\n * });\n * ```\n */\n async update(params: {\n displayName?: string | null;\n description?: string | null;\n avatar?: Blob | null;\n banner?: Blob | null;\n website?: string | null;\n }): Promise<UpdateResult> {\n try {\n // Get existing profile record\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection: \"app.bsky.actor.profile\",\n rkey: \"self\",\n });\n\n const existingProfile = (existing.data.value as Record<string, unknown>) || {};\n\n // Build updated profile\n const updatedProfile: Record<string, unknown> = { ...existingProfile };\n\n if (params.displayName !== undefined) {\n if (params.displayName === null) {\n delete updatedProfile.displayName;\n } else {\n updatedProfile.displayName = params.displayName;\n }\n }\n\n if (params.description !== undefined) {\n if (params.description === null) {\n delete updatedProfile.description;\n } else {\n updatedProfile.description = params.description;\n }\n }\n\n // Handle avatar upload\n if (params.avatar !== undefined) {\n if (params.avatar === null) {\n delete updatedProfile.avatar;\n } else {\n const arrayBuffer = await params.avatar.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.avatar.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n updatedProfile.avatar = uploadResult.data.blob;\n }\n }\n }\n\n // Handle banner upload\n if (params.banner !== undefined) {\n if (params.banner === null) {\n delete updatedProfile.banner;\n } else {\n const arrayBuffer = await params.banner.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.banner.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n updatedProfile.banner = uploadResult.data.blob;\n }\n }\n }\n\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection: \"app.bsky.actor.profile\",\n rkey: \"self\",\n record: updatedProfile,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update profile\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update profile: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n}\n","/**\n * Lexicons entrypoint - Lexicon definitions and registry.\n *\n * This sub-entrypoint exports the lexicon registry and hypercert\n * lexicon constants for working with AT Protocol record schemas.\n *\n * @remarks\n * Import from `@hypercerts-org/sdk/lexicons`:\n *\n * ```typescript\n * import {\n * LexiconRegistry,\n * HYPERCERT_LEXICONS,\n * HYPERCERT_COLLECTIONS,\n * } from \"@hypercerts-org/sdk/lexicons\";\n * ```\n *\n * **Exports**:\n * - {@link LexiconRegistry} - Registry for managing and validating lexicons\n * - {@link HYPERCERT_LEXICONS} - Array of all hypercert lexicon documents\n * - {@link HYPERCERT_COLLECTIONS} - Constants for collection NSIDs\n *\n * @example Using collection constants\n * ```typescript\n * import { HYPERCERT_COLLECTIONS } from \"@hypercerts-org/sdk/lexicons\";\n *\n * // List hypercerts using the correct collection name\n * const records = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.RECORD,\n * });\n *\n * // List contributions\n * const contributions = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n * });\n * ```\n *\n * @example Custom lexicon registration\n * ```typescript\n * import { LexiconRegistry } from \"@hypercerts-org/sdk/lexicons\";\n *\n * const registry = sdk.getLexiconRegistry();\n *\n * // Register custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... },\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", record);\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Import lexicon JSON files and constants from the published package\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport {\n CERTIFIED_DEFS_LEXICON_JSON,\n LOCATION_LEXICON_JSON,\n STRONGREF_LEXICON_JSON,\n HYPERCERTS_DEFS_LEXICON_JSON,\n ACTIVITY_LEXICON_JSON,\n COLLECTION_LEXICON_JSON,\n CONTRIBUTION_LEXICON_JSON,\n EVALUATION_LEXICON_JSON,\n EVIDENCE_LEXICON_JSON,\n MEASUREMENT_LEXICON_JSON,\n RIGHTS_LEXICON_JSON,\n PROJECT_LEXICON_JSON,\n BADGE_AWARD_LEXICON_JSON,\n BADGE_DEFINITION_LEXICON_JSON,\n BADGE_RESPONSE_LEXICON_JSON,\n FUNDING_RECEIPT_LEXICON_JSON,\n // NSID constants\n ACTIVITY_NSID,\n RIGHTS_NSID,\n LOCATION_NSID,\n CONTRIBUTION_NSID,\n MEASUREMENT_NSID,\n EVALUATION_NSID,\n EVIDENCE_NSID,\n COLLECTION_NSID,\n PROJECT_NSID,\n BADGE_AWARD_NSID,\n BADGE_DEFINITION_NSID,\n BADGE_RESPONSE_NSID,\n FUNDING_RECEIPT_NSID,\n} from \"@hypercerts-org/lexicon\";\n\n/**\n * All hypercert-related lexicons for registration with AT Protocol Agent.\n * This array contains all lexicon documents from the published package.\n */\nexport const HYPERCERT_LEXICONS: LexiconDoc[] = [\n CERTIFIED_DEFS_LEXICON_JSON as LexiconDoc,\n LOCATION_LEXICON_JSON as LexiconDoc,\n STRONGREF_LEXICON_JSON as LexiconDoc,\n HYPERCERTS_DEFS_LEXICON_JSON as LexiconDoc,\n ACTIVITY_LEXICON_JSON as LexiconDoc,\n COLLECTION_LEXICON_JSON as LexiconDoc,\n CONTRIBUTION_LEXICON_JSON as LexiconDoc,\n EVALUATION_LEXICON_JSON as LexiconDoc,\n EVIDENCE_LEXICON_JSON as LexiconDoc,\n MEASUREMENT_LEXICON_JSON as LexiconDoc,\n RIGHTS_LEXICON_JSON as LexiconDoc,\n PROJECT_LEXICON_JSON as LexiconDoc,\n BADGE_AWARD_LEXICON_JSON as LexiconDoc,\n BADGE_DEFINITION_LEXICON_JSON as LexiconDoc,\n BADGE_RESPONSE_LEXICON_JSON as LexiconDoc,\n FUNDING_RECEIPT_LEXICON_JSON as LexiconDoc,\n];\n\n/**\n * Collection NSIDs (Namespaced Identifiers) for hypercert records.\n *\n * Use these constants when performing record operations to ensure\n * correct collection names.\n */\nexport const HYPERCERT_COLLECTIONS = {\n /**\n * Main hypercert claim record collection.\n */\n CLAIM: ACTIVITY_NSID,\n\n /**\n * Rights record collection.\n */\n RIGHTS: RIGHTS_NSID,\n\n /**\n * Location record collection (shared certified lexicon).\n */\n LOCATION: LOCATION_NSID,\n\n /**\n * Contribution record collection.\n */\n CONTRIBUTION: CONTRIBUTION_NSID,\n\n /**\n * Measurement record collection.\n */\n MEASUREMENT: MEASUREMENT_NSID,\n\n /**\n * Evaluation record collection.\n */\n EVALUATION: EVALUATION_NSID,\n\n /**\n * Evidence record collection.\n */\n EVIDENCE: EVIDENCE_NSID,\n\n /**\n * Collection record collection (groups of hypercerts).\n */\n COLLECTION: COLLECTION_NSID,\n\n /**\n * Project record collection.\n */\n PROJECT: PROJECT_NSID,\n\n /**\n * Badge award record collection.\n */\n BADGE_AWARD: BADGE_AWARD_NSID,\n\n /**\n * Badge definition record collection.\n */\n BADGE_DEFINITION: BADGE_DEFINITION_NSID,\n\n /**\n * Badge response record collection.\n */\n BADGE_RESPONSE: BADGE_RESPONSE_NSID,\n\n /**\n * Funding receipt record collection.\n */\n FUNDING_RECEIPT: FUNDING_RECEIPT_NSID,\n} as const;\n","/**\n * HypercertOperationsImpl - High-level hypercert operations.\n *\n * This module provides the implementation for creating and managing\n * hypercerts, including related records like rights, locations,\n * contributions, measurements, and evaluations.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { EventEmitter } from \"eventemitter3\";\nimport { NetworkError, ValidationError } from \"../core/errors.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport { validate } from \"@hypercerts-org/lexicon\";\nimport {\n HYPERCERT_COLLECTIONS,\n type JsonBlobRef,\n type HypercertEvidence,\n type HypercertClaim,\n type HypercertRights,\n type HypercertContribution,\n type HypercertMeasurement,\n type HypercertEvaluation,\n type HypercertCollection,\n type HypercertLocation,\n} from \"../services/hypercerts/types.js\";\nimport type {\n HypercertOperations,\n HypercertEvents,\n CreateHypercertParams,\n CreateHypercertResult,\n} from \"./interfaces.js\";\nimport type { CreateResult, UpdateResult, PaginatedList, ListParams, ProgressStep } from \"./types.js\";\n\n/**\n * Implementation of high-level hypercert operations.\n *\n * This class provides a convenient API for creating and managing hypercerts\n * with automatic handling of:\n *\n * - Image upload and blob reference management\n * - Rights record creation and linking\n * - Location attachment with optional GeoJSON support\n * - Contribution tracking\n * - Measurement and evaluation records\n * - Hypercert collections\n *\n * The class extends EventEmitter to provide real-time progress notifications\n * during complex operations.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.hypercerts}.\n *\n * **Record Relationships**:\n * - Hypercert → Rights (required, 1:1)\n * - Hypercert → Location (optional, 1:many)\n * - Hypercert → Contribution (optional, 1:many)\n * - Hypercert → Measurement (optional, 1:many)\n * - Hypercert → Evaluation (optional, 1:many)\n * - Collection → Hypercerts (1:many via claims array)\n *\n * @example Creating a hypercert with progress tracking\n * ```typescript\n * repo.hypercerts.on(\"recordCreated\", ({ uri }) => {\n * console.log(`Hypercert created: ${uri}`);\n * });\n *\n * const result = await repo.hypercerts.create({\n * title: \"Climate Impact\",\n * description: \"Reduced emissions by 100 tons\",\n * workScope: \"Climate\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: { name: \"CC-BY\", type: \"license\", description: \"...\" },\n * onProgress: (step) => console.log(`${step.name}: ${step.status}`),\n * });\n * ```\n *\n * @internal\n */\nexport class HypercertOperationsImpl extends EventEmitter<HypercertEvents> implements HypercertOperations {\n /**\n * Creates a new HypercertOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository to operate on\n * @param _serverUrl - Server URL (reserved for future use)\n * @param logger - Optional logger for debugging\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n private logger?: LoggerInterface,\n ) {\n super();\n }\n\n /**\n * Emits a progress event to the optional progress handler.\n *\n * @param onProgress - Progress callback from create params\n * @param step - Progress step information\n * @internal\n */\n private emitProgress(onProgress: ((step: ProgressStep) => void) | undefined, step: ProgressStep): void {\n if (onProgress) {\n try {\n onProgress(step);\n } catch (err) {\n this.logger?.error(`Error in progress handler: ${err instanceof Error ? err.message : \"Unknown\"}`);\n }\n }\n }\n\n /**\n * Uploads an image blob and returns a blob reference.\n *\n * @param image - Image blob to upload\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to blob reference or undefined\n * @throws {@link NetworkError} if upload fails\n * @internal\n */\n private async uploadImageBlob(\n image: Blob,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<JsonBlobRef | undefined> {\n this.emitProgress(onProgress, { name: \"uploadImage\", status: \"start\" });\n try {\n const arrayBuffer = await image.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: image.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n const blobRef: JsonBlobRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n this.emitProgress(onProgress, {\n name: \"uploadImage\",\n status: \"success\",\n data: { size: image.size },\n });\n return blobRef;\n }\n throw new NetworkError(\"Image upload succeeded but returned no blob reference\");\n } catch (error) {\n this.emitProgress(onProgress, { name: \"uploadImage\", status: \"error\", error: error as Error });\n throw new NetworkError(`Failed to upload image: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a rights record for a hypercert.\n *\n * @param rights - Rights data\n * @param createdAt - ISO timestamp for creation\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to rights URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if creation fails\n * @internal\n */\n private async createRightsRecord(\n rights: { name: string; type: string; description: string },\n createdAt: string,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<{ uri: string; cid: string }> {\n this.emitProgress(onProgress, { name: \"createRights\", status: \"start\" });\n const rightsRecord: HypercertRights = {\n $type: HYPERCERT_COLLECTIONS.RIGHTS,\n rightsName: rights.name,\n rightsType: rights.type,\n rightsDescription: rights.description,\n createdAt,\n };\n\n const rightsValidation = validate(rightsRecord, HYPERCERT_COLLECTIONS.RIGHTS, \"main\", false);\n if (!rightsValidation.success) {\n throw new ValidationError(`Invalid rights record: ${rightsValidation.error?.message}`);\n }\n\n const rightsResult = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.RIGHTS,\n record: rightsRecord as Record<string, unknown>,\n });\n\n if (!rightsResult.success) {\n throw new NetworkError(\"Failed to create rights record\");\n }\n\n const uri = rightsResult.data.uri;\n const cid = rightsResult.data.cid;\n this.emit(\"rightsCreated\", { uri, cid });\n this.emitProgress(onProgress, {\n name: \"createRights\",\n status: \"success\",\n data: { uri },\n });\n\n return { uri, cid };\n }\n\n /**\n * Creates the main hypercert record.\n *\n * @param params - Hypercert creation parameters\n * @param rightsUri - URI of the associated rights record\n * @param rightsCid - CID of the associated rights record\n * @param imageBlobRef - Optional image blob reference\n * @param createdAt - ISO timestamp for creation\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to hypercert URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if creation fails\n * @internal\n */\n private async createHypercertRecord(\n params: CreateHypercertParams,\n rightsUri: string,\n rightsCid: string,\n imageBlobRef: JsonBlobRef | undefined,\n createdAt: string,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<{ uri: string; cid: string }> {\n this.emitProgress(onProgress, { name: \"createHypercert\", status: \"start\" });\n const hypercertRecord: Record<string, unknown> = {\n $type: HYPERCERT_COLLECTIONS.CLAIM,\n title: params.title,\n shortDescription: params.shortDescription,\n description: params.description,\n workScope: params.workScope,\n startDate: params.startDate,\n endDate: params.endDate,\n rights: { uri: rightsUri, cid: rightsCid },\n createdAt,\n };\n\n if (imageBlobRef) {\n hypercertRecord.image = imageBlobRef;\n }\n\n if (params.evidence && params.evidence.length > 0) {\n hypercertRecord.evidence = params.evidence;\n }\n\n const hypercertValidation = validate(hypercertRecord, HYPERCERT_COLLECTIONS.CLAIM, \"main\", false);\n if (!hypercertValidation.success) {\n throw new ValidationError(`Invalid hypercert record: ${hypercertValidation.error?.message}`);\n }\n\n const hypercertResult = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CLAIM,\n record: hypercertRecord,\n });\n\n if (!hypercertResult.success) {\n throw new NetworkError(\"Failed to create hypercert record\");\n }\n\n const uri = hypercertResult.data.uri;\n const cid = hypercertResult.data.cid;\n this.emit(\"recordCreated\", { uri, cid });\n this.emitProgress(onProgress, {\n name: \"createHypercert\",\n status: \"success\",\n data: { uri },\n });\n\n return { uri, cid };\n }\n\n /**\n * Attaches a location to a hypercert with progress tracking.\n *\n * @param hypercertUri - URI of the hypercert\n * @param location - Location data\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to location URI\n * @internal\n */\n private async attachLocationWithProgress(\n hypercertUri: string,\n location: { value: string; name?: string; description?: string; srs?: string; geojson?: Blob },\n onProgress?: (step: ProgressStep) => void,\n ): Promise<string> {\n this.emitProgress(onProgress, { name: \"attachLocation\", status: \"start\" });\n try {\n const locationResult = await this.attachLocation(hypercertUri, location);\n this.emitProgress(onProgress, {\n name: \"attachLocation\",\n status: \"success\",\n data: { uri: locationResult.uri },\n });\n return locationResult.uri;\n } catch (error) {\n this.emitProgress(onProgress, { name: \"attachLocation\", status: \"error\", error: error as Error });\n this.logger?.warn(`Failed to attach location: ${error instanceof Error ? error.message : \"Unknown\"}`);\n throw error;\n }\n }\n\n /**\n * Creates contribution records with progress tracking.\n *\n * @param hypercertUri - URI of the hypercert\n * @param contributions - Array of contribution data\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to array of contribution URIs\n * @internal\n */\n private async createContributionsWithProgress(\n hypercertUri: string,\n contributions: Array<{ contributors: string[]; role: string; description?: string }>,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<string[]> {\n this.emitProgress(onProgress, { name: \"createContributions\", status: \"start\" });\n try {\n const contributionUris: string[] = [];\n for (const contrib of contributions) {\n const contribResult = await this.addContribution({\n hypercertUri,\n contributors: contrib.contributors,\n role: contrib.role,\n description: contrib.description,\n });\n contributionUris.push(contribResult.uri);\n }\n this.emitProgress(onProgress, {\n name: \"createContributions\",\n status: \"success\",\n data: { count: contributionUris.length },\n });\n return contributionUris;\n } catch (error) {\n this.emitProgress(onProgress, { name: \"createContributions\", status: \"error\", error: error as Error });\n this.logger?.warn(`Failed to create contributions: ${error instanceof Error ? error.message : \"Unknown\"}`);\n throw error;\n }\n }\n\n /**\n * Creates a new hypercert with all related records.\n *\n * This method orchestrates the creation of a hypercert and its associated\n * records in the correct order:\n *\n * 1. Upload image (if provided)\n * 2. Create rights record\n * 3. Create hypercert record (referencing rights)\n * 4. Attach location (if provided)\n * 5. Create contributions (if provided)\n *\n * @param params - Creation parameters (see {@link CreateHypercertParams})\n * @returns Promise resolving to URIs and CIDs of all created records\n * @throws {@link ValidationError} if any record fails validation\n * @throws {@link NetworkError} if any API call fails\n *\n * @remarks\n * The operation is not atomic - if a later step fails, earlier records\n * will still exist. The result object will contain URIs for all\n * successfully created records.\n *\n * **Progress Steps**:\n * - `uploadImage`: Image blob upload\n * - `createRights`: Rights record creation\n * - `createHypercert`: Main hypercert record creation\n * - `attachLocation`: Location record creation\n * - `createContributions`: Contribution records creation\n *\n * @example Minimal hypercert\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"My Impact\",\n * description: \"Description of impact work\",\n * workScope: \"Education\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-06-30\",\n * rights: {\n * name: \"Attribution\",\n * type: \"license\",\n * description: \"CC-BY-4.0\",\n * },\n * });\n * ```\n *\n * @example Full hypercert with all options\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"Reforestation Project\",\n * description: \"Planted 10,000 trees...\",\n * shortDescription: \"10K trees planted\",\n * workScope: \"Environment\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: { name: \"Open\", type: \"impact\", description: \"...\" },\n * image: coverImageBlob,\n * location: { value: \"Amazon, Brazil\", name: \"Amazon Basin\" },\n * contributions: [\n * { contributors: [\"did:plc:org1\"], role: \"coordinator\" },\n * { contributors: [\"did:plc:org2\"], role: \"implementer\" },\n * ],\n * evidence: [{ uri: \"https://...\", description: \"Satellite data\" }],\n * onProgress: console.log,\n * });\n * ```\n */\n async create(params: CreateHypercertParams): Promise<CreateHypercertResult> {\n const createdAt = new Date().toISOString();\n const result: CreateHypercertResult = {\n hypercertUri: \"\",\n rightsUri: \"\",\n hypercertCid: \"\",\n rightsCid: \"\",\n };\n\n try {\n // Step 1: Upload image if provided\n const imageBlobRef = params.image ? await this.uploadImageBlob(params.image, params.onProgress) : undefined;\n\n // Step 2: Create rights record\n const { uri: rightsUri, cid: rightsCid } = await this.createRightsRecord(\n params.rights,\n createdAt,\n params.onProgress,\n );\n result.rightsUri = rightsUri;\n result.rightsCid = rightsCid;\n\n // Step 3: Create hypercert record\n const { uri: hypercertUri, cid: hypercertCid } = await this.createHypercertRecord(\n params,\n rightsUri,\n rightsCid,\n imageBlobRef,\n createdAt,\n params.onProgress,\n );\n result.hypercertUri = hypercertUri;\n result.hypercertCid = hypercertCid;\n\n // Step 4: Attach location if provided\n if (params.location) {\n try {\n result.locationUri = await this.attachLocationWithProgress(hypercertUri, params.location, params.onProgress);\n } catch {\n // Error already logged and progress emitted\n }\n }\n\n // Step 5: Create contributions if provided\n if (params.contributions && params.contributions.length > 0) {\n try {\n result.contributionUris = await this.createContributionsWithProgress(\n hypercertUri,\n params.contributions,\n params.onProgress,\n );\n } catch {\n // Error already logged and progress emitted\n }\n }\n\n return result;\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates an existing hypercert record.\n *\n * @param params - Update parameters\n * @param params.uri - AT-URI of the hypercert to update\n * @param params.updates - Partial record with fields to update\n * @param params.image - New image blob, `null` to remove, `undefined` to keep existing\n * @returns Promise resolving to update result\n * @throws {@link ValidationError} if the URI format is invalid or record fails validation\n * @throws {@link NetworkError} if the update fails\n *\n * @remarks\n * This is a partial update - only specified fields are changed.\n * The `createdAt` and `rights` fields cannot be changed.\n *\n * @example Update title and description\n * ```typescript\n * await repo.hypercerts.update({\n * uri: \"at://did:plc:abc/org.hypercerts.hypercert/xyz\",\n * updates: {\n * title: \"Updated Title\",\n * description: \"New description\",\n * },\n * });\n * ```\n *\n * @example Update with new image\n * ```typescript\n * await repo.hypercerts.update({\n * uri: hypercertUri,\n * updates: { title: \"New Title\" },\n * image: newImageBlob,\n * });\n * ```\n *\n * @example Remove image\n * ```typescript\n * await repo.hypercerts.update({\n * uri: hypercertUri,\n * updates: {},\n * image: null, // Explicitly remove image\n * });\n * ```\n */\n async update(params: {\n uri: string;\n updates: Partial<Omit<HypercertClaim, \"$type\" | \"createdAt\" | \"rights\">>;\n image?: Blob | null;\n }): Promise<UpdateResult> {\n try {\n const uriMatch = params.uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${params.uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n // The existing record comes from ATProto, use it directly\n // TypeScript ensures type safety through the HypercertClaim interface\n const existingRecord = existing.data.value as HypercertClaim;\n\n const recordForUpdate: Record<string, unknown> = {\n ...existingRecord,\n ...params.updates,\n createdAt: existingRecord.createdAt,\n rights: existingRecord.rights,\n };\n\n // Handle image update\n delete (recordForUpdate as { image?: unknown }).image;\n if (params.image !== undefined) {\n if (params.image === null) {\n // Remove image\n } else {\n const arrayBuffer = await params.image.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.image.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n recordForUpdate.image = {\n $type: \"blob\",\n ref: uploadResult.data.blob.ref,\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n }\n }\n } else if (existingRecord.image) {\n // Preserve existing image\n recordForUpdate.image = existingRecord.image;\n }\n\n const validation = validate(recordForUpdate, collection, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid hypercert record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection,\n rkey,\n record: recordForUpdate,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update hypercert\");\n }\n\n this.emit(\"recordUpdated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a hypercert by its AT-URI.\n *\n * @param uri - AT-URI of the hypercert (e.g., \"at://did:plc:abc/org.hypercerts.hypercert/xyz\")\n * @returns Promise resolving to hypercert URI, CID, and parsed record\n * @throws {@link ValidationError} if the URI format is invalid or record doesn't match schema\n * @throws {@link NetworkError} if the record cannot be fetched\n *\n * @example\n * ```typescript\n * const { uri, cid, record } = await repo.hypercerts.get(hypercertUri);\n * console.log(`${record.title}: ${record.description}`);\n * ```\n */\n async get(uri: string): Promise<{ uri: string; cid: string; record: HypercertClaim }> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get hypercert\");\n }\n\n return {\n uri: result.data.uri,\n cid: result.data.cid ?? \"\",\n record: result.data.value as HypercertClaim,\n };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Lists hypercerts in the repository with pagination.\n *\n * @param params - Optional pagination parameters\n * @returns Promise resolving to paginated list of hypercerts\n * @throws {@link NetworkError} if the list operation fails\n *\n * @example\n * ```typescript\n * // Get first page\n * const { records, cursor } = await repo.hypercerts.list({ limit: 20 });\n *\n * // Get next page\n * if (cursor) {\n * const nextPage = await repo.hypercerts.list({ limit: 20, cursor });\n * }\n * ```\n */\n async list(params?: ListParams): Promise<PaginatedList<{ uri: string; cid: string; record: HypercertClaim }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CLAIM,\n limit: params?.limit,\n cursor: params?.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list hypercerts\");\n }\n\n return {\n records:\n result.data.records?.map((r) => ({\n uri: r.uri,\n cid: r.cid,\n record: r.value as HypercertClaim,\n })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to list hypercerts: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Deletes a hypercert record.\n *\n * @param uri - AT-URI of the hypercert to delete\n * @throws {@link ValidationError} if the URI format is invalid\n * @throws {@link NetworkError} if the deletion fails\n *\n * @remarks\n * This only deletes the hypercert record itself. Related records\n * (rights, locations, contributions) are not automatically deleted.\n *\n * @example\n * ```typescript\n * await repo.hypercerts.delete(hypercertUri);\n * ```\n */\n async delete(uri: string): Promise<void> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.deleteRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to delete hypercert\");\n }\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to delete hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Attaches a location to an existing hypercert.\n *\n * @param hypercertUri - AT-URI of the hypercert to attach location to\n * @param location - Location data\n * @param location.value - Location value (address, coordinates, or description)\n * @param location.name - Optional human-readable name\n * @param location.description - Optional description\n * @param location.srs - Spatial Reference System (e.g., \"EPSG:4326\")\n * @param location.geojson - Optional GeoJSON blob for precise boundaries\n * @returns Promise resolving to location record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example Simple location\n * ```typescript\n * await repo.hypercerts.attachLocation(hypercertUri, {\n * value: \"San Francisco, CA\",\n * name: \"SF Bay Area\",\n * srs: \"EPSG:4326\",\n * });\n * ```\n *\n * @example Location with GeoJSON\n * ```typescript\n * const geojsonBlob = new Blob([JSON.stringify(geojson)], {\n * type: \"application/geo+json\"\n * });\n *\n * await repo.hypercerts.attachLocation(hypercertUri, {\n * value: \"Custom Region\",\n * srs: \"EPSG:4326\",\n * geojson: geojsonBlob,\n * });\n * ```\n */\n async attachLocation(\n hypercertUri: string,\n location: { value: string; name?: string; description?: string; srs?: string; geojson?: Blob },\n ): Promise<CreateResult> {\n try {\n // Validate required srs field\n if (!location.srs) {\n throw new ValidationError(\n \"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.\",\n );\n }\n\n // Validate that hypercert exists (unused but confirms hypercert is valid)\n await this.get(hypercertUri);\n const createdAt = new Date().toISOString();\n\n // Determine location type and prepare location data\n let locationData: { $type: string; uri: string } | JsonBlobRef;\n let locationType: string;\n\n if (location.geojson) {\n // Upload GeoJSON as a blob\n const arrayBuffer = await location.geojson.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: location.geojson.type || \"application/geo+json\",\n });\n if (uploadResult.success) {\n locationData = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n locationType = \"geojson-point\";\n } else {\n throw new NetworkError(\"Failed to upload GeoJSON blob\");\n }\n } else {\n // Use value as a URI reference\n locationData = {\n $type: \"org.hypercerts.defs#uri\",\n uri: location.value,\n };\n locationType = \"coordinate-decimal\";\n }\n\n // Build location record according to app.certified.location lexicon\n const locationRecord: HypercertLocation = {\n $type: HYPERCERT_COLLECTIONS.LOCATION,\n lpVersion: \"1.0\",\n srs: location.srs,\n locationType,\n location: locationData,\n createdAt,\n name: location.name,\n description: location.description,\n };\n\n const validation = validate(locationRecord, HYPERCERT_COLLECTIONS.LOCATION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid location record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.LOCATION,\n record: locationRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to attach location\");\n }\n\n this.emit(\"locationAttached\", { uri: result.data.uri, cid: result.data.cid, hypercertUri });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to attach location: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Adds evidence to an existing hypercert.\n *\n * @param hypercertUri - AT-URI of the hypercert\n * @param evidence - Array of evidence items to add\n * @returns Promise resolving to update result\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @remarks\n * Evidence is appended to existing evidence, not replaced.\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addEvidence(hypercertUri, [\n * { uri: \"https://example.com/report.pdf\", description: \"Impact report\" },\n * { uri: \"https://example.com/data.csv\", description: \"Raw data\" },\n * ]);\n * ```\n */\n async addEvidence(hypercertUri: string, evidence: HypercertEvidence[]): Promise<UpdateResult> {\n try {\n const existing = await this.get(hypercertUri);\n const existingEvidence = (existing.record.evidence as HypercertEvidence[]) || [];\n const updatedEvidence = [...existingEvidence, ...evidence];\n\n const result = await this.update({\n uri: hypercertUri,\n updates: { evidence: updatedEvidence },\n });\n\n this.emit(\"evidenceAdded\", { uri: result.uri, cid: result.cid });\n return result;\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add evidence: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a contribution record.\n *\n * @param params - Contribution parameters\n * @param params.hypercertUri - Optional hypercert to link (can be standalone)\n * @param params.contributors - Array of contributor DIDs\n * @param params.role - Role of the contributors (e.g., \"coordinator\", \"implementer\")\n * @param params.description - Optional description of the contribution\n * @returns Promise resolving to contribution record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addContribution({\n * hypercertUri: hypercertUri,\n * contributors: [\"did:plc:alice\", \"did:plc:bob\"],\n * role: \"implementer\",\n * description: \"On-ground implementation team\",\n * });\n * ```\n */\n async addContribution(params: {\n hypercertUri?: string;\n contributors: string[];\n role: string;\n description?: string;\n }): Promise<CreateResult> {\n try {\n const createdAt = new Date().toISOString();\n const contributionRecord: HypercertContribution = {\n $type: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n contributors: params.contributors,\n role: params.role,\n createdAt,\n description: params.description,\n hypercert: { uri: \"\", cid: \"\" }, // Will be set below if hypercertUri provided\n };\n\n if (params.hypercertUri) {\n const hypercert = await this.get(params.hypercertUri);\n contributionRecord.hypercert = { uri: hypercert.uri, cid: hypercert.cid };\n }\n\n const validation = validate(contributionRecord, HYPERCERT_COLLECTIONS.CONTRIBUTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid contribution record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n record: contributionRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create contribution\");\n }\n\n this.emit(\"contributionCreated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to add contribution: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Creates a measurement record for a hypercert.\n *\n * Measurements quantify the impact claimed in a hypercert with\n * specific metrics and values.\n *\n * @param params - Measurement parameters\n * @param params.hypercertUri - AT-URI of the hypercert being measured\n * @param params.measurers - DIDs of entities who performed the measurement\n * @param params.metric - Name of the metric (e.g., \"CO2 Reduced\", \"Trees Planted\")\n * @param params.value - Measured value with units (e.g., \"100 tons\", \"10000\")\n * @param params.methodUri - Optional URI describing the measurement methodology\n * @param params.evidenceUris - Optional URIs to supporting evidence\n * @returns Promise resolving to measurement record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addMeasurement({\n * hypercertUri: hypercertUri,\n * measurers: [\"did:plc:auditor\"],\n * metric: \"Carbon Offset\",\n * value: \"150 tons CO2e\",\n * methodUri: \"https://example.com/methodology\",\n * evidenceUris: [\"https://example.com/audit-report\"],\n * });\n * ```\n */\n async addMeasurement(params: {\n hypercertUri: string;\n measurers: string[];\n metric: string;\n value: string;\n methodUri?: string;\n evidenceUris?: string[];\n }): Promise<CreateResult> {\n try {\n const hypercert = await this.get(params.hypercertUri);\n const createdAt = new Date().toISOString();\n\n const measurementRecord: HypercertMeasurement = {\n $type: HYPERCERT_COLLECTIONS.MEASUREMENT,\n hypercert: { uri: hypercert.uri, cid: hypercert.cid },\n measurers: params.measurers,\n metric: params.metric,\n value: params.value,\n createdAt,\n measurementMethodURI: params.methodUri,\n evidenceURI: params.evidenceUris,\n };\n\n const validation = validate(measurementRecord, HYPERCERT_COLLECTIONS.MEASUREMENT, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid measurement record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.MEASUREMENT,\n record: measurementRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create measurement\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add measurement: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates an evaluation record for a hypercert or other subject.\n *\n * Evaluations provide third-party assessments of impact claims.\n *\n * @param params - Evaluation parameters\n * @param params.subjectUri - AT-URI of the record being evaluated\n * @param params.evaluators - DIDs of evaluating entities\n * @param params.summary - Summary of the evaluation findings\n * @returns Promise resolving to evaluation record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addEvaluation({\n * subjectUri: hypercertUri,\n * evaluators: [\"did:plc:evaluator-org\"],\n * summary: \"Verified impact claims through site visit and data analysis\",\n * });\n * ```\n */\n async addEvaluation(params: { subjectUri: string; evaluators: string[]; summary: string }): Promise<CreateResult> {\n try {\n const subject = await this.get(params.subjectUri);\n const createdAt = new Date().toISOString();\n\n const evaluationRecord: HypercertEvaluation = {\n $type: HYPERCERT_COLLECTIONS.EVALUATION,\n subject: { uri: subject.uri, cid: subject.cid },\n evaluators: params.evaluators,\n summary: params.summary,\n createdAt,\n };\n\n const validation = validate(evaluationRecord, HYPERCERT_COLLECTIONS.EVALUATION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid evaluation record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.EVALUATION,\n record: evaluationRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create evaluation\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add evaluation: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a collection of hypercerts.\n *\n * Collections group related hypercerts with optional weights\n * for relative importance.\n *\n * @param params - Collection parameters\n * @param params.title - Collection title\n * @param params.claims - Array of hypercert references with weights\n * @param params.shortDescription - Optional short description\n * @param params.coverPhoto - Optional cover image blob\n * @returns Promise resolving to collection record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * const collection = await repo.hypercerts.createCollection({\n * title: \"Climate Projects 2024\",\n * shortDescription: \"Our climate impact portfolio\",\n * claims: [\n * { uri: hypercert1Uri, cid: hypercert1Cid, weight: \"0.5\" },\n * { uri: hypercert2Uri, cid: hypercert2Cid, weight: \"0.3\" },\n * { uri: hypercert3Uri, cid: hypercert3Cid, weight: \"0.2\" },\n * ],\n * coverPhoto: coverImageBlob,\n * });\n * ```\n */\n async createCollection(params: {\n title: string;\n claims: Array<{ uri: string; cid: string; weight: string }>;\n shortDescription?: string;\n coverPhoto?: Blob;\n }): Promise<CreateResult> {\n try {\n const createdAt = new Date().toISOString();\n\n let coverPhotoRef: JsonBlobRef | undefined;\n if (params.coverPhoto) {\n const arrayBuffer = await params.coverPhoto.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.coverPhoto.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n coverPhotoRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n }\n }\n\n const collectionRecord: Record<string, unknown> = {\n $type: HYPERCERT_COLLECTIONS.COLLECTION,\n title: params.title,\n claims: params.claims.map((c) => ({ claim: { uri: c.uri, cid: c.cid }, weight: c.weight })),\n createdAt,\n };\n\n if (params.shortDescription) {\n collectionRecord.shortDescription = params.shortDescription;\n }\n\n if (coverPhotoRef) {\n collectionRecord.coverPhoto = coverPhotoRef;\n }\n\n const validation = validate(collectionRecord, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid collection record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n record: collectionRecord,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create collection\");\n }\n\n this.emit(\"collectionCreated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create collection: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a collection by its AT-URI.\n *\n * @param uri - AT-URI of the collection\n * @returns Promise resolving to collection URI, CID, and parsed record\n * @throws {@link ValidationError} if the URI format is invalid or record doesn't match schema\n * @throws {@link NetworkError} if the record cannot be fetched\n *\n * @example\n * ```typescript\n * const { record } = await repo.hypercerts.getCollection(collectionUri);\n * console.log(`Collection: ${record.title}`);\n * console.log(`Contains ${record.claims.length} hypercerts`);\n * ```\n */\n async getCollection(uri: string): Promise<{ uri: string; cid: string; record: HypercertCollection }> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get collection\");\n }\n\n // Validate with lexicon registry (more lenient - doesn't require $type)\n const validation = validate(result.data.value, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid collection record format: ${validation.error?.message}`);\n }\n\n return {\n uri: result.data.uri,\n cid: result.data.cid ?? \"\",\n record: result.data.value as HypercertCollection,\n };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get collection: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Lists collections in the repository with pagination.\n *\n * @param params - Optional pagination parameters\n * @returns Promise resolving to paginated list of collections\n * @throws {@link NetworkError} if the list operation fails\n *\n * @example\n * ```typescript\n * const { records } = await repo.hypercerts.listCollections();\n * for (const { record } of records) {\n * console.log(`${record.title}: ${record.claims.length} claims`);\n * }\n * ```\n */\n async listCollections(\n params?: ListParams,\n ): Promise<PaginatedList<{ uri: string; cid: string; record: HypercertCollection }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n limit: params?.limit,\n cursor: params?.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list collections\");\n }\n\n return {\n records:\n result.data.records?.map((r) => ({\n uri: r.uri,\n cid: r.cid,\n record: r.value as HypercertCollection,\n })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to list collections: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n}\n","/**\n * CollaboratorOperationsImpl - SDS collaborator management operations.\n *\n * This module provides the implementation for managing collaborator\n * access on Shared Data Server (SDS) repositories.\n *\n * @packageDocumentation\n */\n\nimport { NetworkError } from \"../core/errors.js\";\nimport type { CollaboratorPermissions, Session } from \"../core/types.js\";\nimport type { CollaboratorOperations, GrantAccessParams } from \"./interfaces.js\";\nimport type { RepositoryAccessGrant, RepositoryRole } from \"./types.js\";\n\n/**\n * Implementation of collaborator operations for SDS access control.\n *\n * This class manages access permissions for shared repositories on\n * Shared Data Servers (SDS). It provides role-based access control\n * with predefined permission sets.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.collaborators} on an SDS-connected repository.\n *\n * **Role Hierarchy**:\n * - `viewer`: Read-only access\n * - `editor`: Read + Create + Update\n * - `admin`: All permissions except ownership transfer\n * - `owner`: Full control including ownership management\n *\n * **SDS API Endpoints Used**:\n * - `com.sds.repo.grantAccess`: Grant access to a user\n * - `com.sds.repo.revokeAccess`: Revoke access from a user\n * - `com.sds.repo.listCollaborators`: List all collaborators\n * - `com.sds.repo.getPermissions`: Get current user's permissions\n * - `com.sds.repo.transferOwnership`: Transfer repository ownership\n *\n * @example\n * ```typescript\n * // Get SDS repository\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Grant editor access\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:new-user\",\n * role: \"editor\",\n * });\n *\n * // List all collaborators\n * const collaborators = await sdsRepo.collaborators.list();\n *\n * // Check specific user\n * const hasAccess = await sdsRepo.collaborators.hasAccess(\"did:plc:someone\");\n * const role = await sdsRepo.collaborators.getRole(\"did:plc:someone\");\n * ```\n *\n * @internal\n */\nexport class CollaboratorOperationsImpl implements CollaboratorOperations {\n /**\n * Creates a new CollaboratorOperationsImpl.\n *\n * @param session - Authenticated OAuth session with fetchHandler\n * @param repoDid - DID of the repository to manage\n * @param serverUrl - SDS server URL\n *\n * @internal\n */\n constructor(\n private session: Session,\n private repoDid: string,\n private serverUrl: string,\n ) {}\n\n /**\n * Converts a role to its corresponding permissions object.\n *\n * @param role - The role to convert\n * @returns Permission flags for the role\n * @internal\n */\n private roleToPermissions(role: RepositoryRole): CollaboratorPermissions {\n switch (role) {\n case \"viewer\":\n return { read: true, create: false, update: false, delete: false, admin: false, owner: false };\n case \"editor\":\n return { read: true, create: true, update: true, delete: false, admin: false, owner: false };\n case \"admin\":\n return { read: true, create: true, update: true, delete: true, admin: true, owner: false };\n case \"owner\":\n return { read: true, create: true, update: true, delete: true, admin: true, owner: true };\n }\n }\n\n /**\n * Determines the role from a permissions object.\n *\n * @param permissions - The permissions to analyze\n * @returns The highest role matching the permissions\n * @internal\n */\n private permissionsToRole(permissions: CollaboratorPermissions): RepositoryRole {\n if (permissions.owner) return \"owner\";\n if (permissions.admin) return \"admin\";\n if (permissions.create || permissions.update) return \"editor\";\n return \"viewer\";\n }\n\n /**\n * Normalizes permissions from SDS API format to SDK format.\n *\n * The SDS API returns permissions as an object with boolean flags\n * (e.g., `{ read: true, create: true, update: false, ... }`).\n * This method ensures all expected fields are present with default values.\n *\n * @param permissions - Permissions object from SDS API\n * @returns Normalized permission flags object\n * @internal\n */\n private parsePermissions(permissions: CollaboratorPermissions): CollaboratorPermissions {\n return {\n read: permissions.read ?? false,\n create: permissions.create ?? false,\n update: permissions.update ?? false,\n delete: permissions.delete ?? false,\n admin: permissions.admin ?? false,\n owner: permissions.owner ?? false,\n };\n }\n\n /**\n * Grants repository access to a user.\n *\n * @param params - Grant parameters\n * @param params.userDid - DID of the user to grant access to\n * @param params.role - Role to assign (determines permissions)\n * @throws {@link NetworkError} if the grant operation fails\n *\n * @remarks\n * If the user already has access, their permissions are updated\n * to the new role.\n *\n * @example\n * ```typescript\n * // Grant viewer access\n * await repo.collaborators.grant({\n * userDid: \"did:plc:viewer-user\",\n * role: \"viewer\",\n * });\n *\n * // Upgrade to editor\n * await repo.collaborators.grant({\n * userDid: \"did:plc:viewer-user\",\n * role: \"editor\",\n * });\n * ```\n */\n async grant(params: GrantAccessParams): Promise<void> {\n const permissions = this.roleToPermissions(params.role);\n\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.grantAccess`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n userDid: params.userDid,\n permissions,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to grant access: ${response.statusText}`);\n }\n }\n\n /**\n * Revokes repository access from a user.\n *\n * @param params - Revoke parameters\n * @param params.userDid - DID of the user to revoke access from\n * @throws {@link NetworkError} if the revoke operation fails\n *\n * @remarks\n * - Cannot revoke access from the repository owner\n * - Revoked access is recorded with a `revokedAt` timestamp\n *\n * @example\n * ```typescript\n * await repo.collaborators.revoke({\n * userDid: \"did:plc:former-collaborator\",\n * });\n * ```\n */\n async revoke(params: { userDid: string }): Promise<void> {\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.revokeAccess`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n userDid: params.userDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to revoke access: ${response.statusText}`);\n }\n }\n\n /**\n * Lists all collaborators on the repository.\n *\n * @param params - Optional pagination parameters\n * @param params.limit - Maximum number of results (1-100, default 50)\n * @param params.cursor - Pagination cursor from previous response\n * @returns Promise resolving to collaborators and optional cursor\n * @throws {@link NetworkError} if the list operation fails\n *\n * @remarks\n * The list includes both active and revoked collaborators.\n * Check `revokedAt` to filter active collaborators.\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await repo.collaborators.list({ limit: 10 });\n * console.log(`Found ${page1.collaborators.length} collaborators`);\n *\n * // Get next page if available\n * if (page1.cursor) {\n * const page2 = await repo.collaborators.list({ limit: 10, cursor: page1.cursor });\n * }\n *\n * // Filter active collaborators\n * const active = page1.collaborators.filter(c => !c.revokedAt);\n * ```\n */\n async list(params?: { limit?: number; cursor?: string }): Promise<{\n collaborators: RepositoryAccessGrant[];\n cursor?: string;\n }> {\n const queryParams = new URLSearchParams({\n repo: this.repoDid,\n });\n\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n\n if (params?.cursor) {\n queryParams.set(\"cursor\", params.cursor);\n }\n\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.repo.listCollaborators?${queryParams.toString()}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to list collaborators: ${response.statusText}`);\n }\n\n const data = await response.json();\n const collaborators = (data.collaborators || []).map(\n (c: {\n userDid: string;\n permissions: CollaboratorPermissions; // SDS API returns object with boolean flags\n grantedBy: string;\n grantedAt: string;\n revokedAt?: string;\n }) => {\n const permissions = this.parsePermissions(c.permissions);\n return {\n userDid: c.userDid,\n role: this.permissionsToRole(permissions),\n permissions: permissions,\n grantedBy: c.grantedBy,\n grantedAt: c.grantedAt,\n revokedAt: c.revokedAt,\n };\n },\n );\n\n return {\n collaborators,\n cursor: data.cursor,\n };\n }\n\n /**\n * Checks if a user has any access to the repository.\n *\n * @param userDid - DID of the user to check\n * @returns Promise resolving to `true` if user has active access\n *\n * @remarks\n * Returns `false` if:\n * - User was never granted access\n * - User's access was revoked\n * - The list operation fails (error is suppressed)\n *\n * @example\n * ```typescript\n * if (await repo.collaborators.hasAccess(\"did:plc:someone\")) {\n * console.log(\"User has access\");\n * }\n * ```\n */\n async hasAccess(userDid: string): Promise<boolean> {\n try {\n const { collaborators } = await this.list();\n return collaborators.some((c) => c.userDid === userDid && !c.revokedAt);\n } catch {\n return false;\n }\n }\n\n /**\n * Gets the role assigned to a user.\n *\n * @param userDid - DID of the user to check\n * @returns Promise resolving to the user's role, or `null` if no active access\n *\n * @example\n * ```typescript\n * const role = await repo.collaborators.getRole(\"did:plc:someone\");\n * if (role === \"admin\" || role === \"owner\") {\n * // User can manage other collaborators\n * }\n * ```\n */\n async getRole(userDid: string): Promise<RepositoryRole | null> {\n const { collaborators } = await this.list();\n const collab = collaborators.find((c) => c.userDid === userDid && !c.revokedAt);\n return collab?.role ?? null;\n }\n\n /**\n * Gets the current user's permissions for this repository.\n *\n * @returns Promise resolving to the permission flags\n * @throws {@link NetworkError} if the request fails\n *\n * @remarks\n * This is useful for checking what actions the current user can perform\n * before attempting operations that might fail due to insufficient permissions.\n *\n * @example\n * ```typescript\n * const permissions = await repo.collaborators.getPermissions();\n *\n * if (permissions.admin) {\n * // Show admin UI\n * console.log(\"You can manage collaborators\");\n * }\n *\n * if (permissions.create) {\n * console.log(\"You can create records\");\n * }\n * ```\n *\n * @example Conditional UI rendering\n * ```typescript\n * const permissions = await repo.collaborators.getPermissions();\n *\n * // Show/hide UI elements based on permissions\n * const canEdit = permissions.update;\n * const canDelete = permissions.delete;\n * const isAdmin = permissions.admin;\n * const isOwner = permissions.owner;\n * ```\n */\n async getPermissions(): Promise<CollaboratorPermissions> {\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.repo.getPermissions?repo=${encodeURIComponent(this.repoDid)}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to get permissions: ${response.statusText}`);\n }\n\n const data = await response.json();\n return data.permissions as CollaboratorPermissions;\n }\n\n /**\n * Transfers repository ownership to another user.\n *\n * @param params - Transfer parameters\n * @param params.newOwnerDid - DID of the user to transfer ownership to\n * @throws {@link NetworkError} if the transfer fails\n *\n * @remarks\n * **IMPORTANT**: This action is irreversible. Once ownership is transferred:\n * - The new owner gains full control of the repository\n * - Your role will be changed to admin (or specified role)\n * - You cannot transfer ownership back without the new owner's approval\n *\n * **Requirements**:\n * - You must be the current owner\n * - The new owner must have an existing account\n * - The new owner will be notified of the ownership transfer\n *\n * @example\n * ```typescript\n * // Transfer ownership to another user\n * await repo.collaborators.transferOwnership({\n * newOwnerDid: \"did:plc:new-owner\",\n * });\n *\n * console.log(\"Ownership transferred successfully\");\n * // You are now an admin, not the owner\n * ```\n *\n * @example With confirmation\n * ```typescript\n * const confirmTransfer = await askUser(\n * \"Are you sure you want to transfer ownership? This cannot be undone.\"\n * );\n *\n * if (confirmTransfer) {\n * await repo.collaborators.transferOwnership({\n * newOwnerDid: \"did:plc:new-owner\",\n * });\n * }\n * ```\n */\n async transferOwnership(params: { newOwnerDid: string }): Promise<void> {\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.transferOwnership`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n newOwner: params.newOwnerDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to transfer ownership: ${response.statusText}`);\n }\n }\n}\n","/**\n * OrganizationOperationsImpl - SDS organization management operations.\n *\n * This module provides the implementation for creating and managing\n * organizations on Shared Data Server (SDS) instances.\n *\n * @packageDocumentation\n */\n\nimport { NetworkError, ValidationError } from \"../core/errors.js\";\nimport type { CollaboratorPermissions, Session } from \"../core/types.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport type { CreateOrganizationParams, OrganizationOperations } from \"./interfaces.js\";\nimport type { OrganizationInfo } from \"./types.js\";\n\n/**\n * Implementation of organization operations for SDS management.\n *\n * Organizations on SDS provide a way to create shared repositories\n * that multiple users can collaborate on. Each organization has:\n *\n * - A unique DID (Decentralized Identifier)\n * - A handle for human-readable identification\n * - An owner and optional collaborators\n * - Its own repository for storing records\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.organizations} on an SDS-connected repository.\n *\n * **SDS API Endpoints Used**:\n * - `com.sds.organization.create`: Create a new organization\n * - `com.sds.organization.list`: List accessible organizations\n *\n * **Access Types**:\n * - `\"owner\"`: User created or owns the organization\n * - `\"collaborator\"`: User was invited with specific permissions\n *\n * @example\n * ```typescript\n * // Get SDS repository\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Create an organization\n * const org = await sdsRepo.organizations.create({\n * name: \"My Team\",\n * description: \"A team for impact projects\",\n * });\n *\n * // List organizations you have access to\n * const orgs = await sdsRepo.organizations.list();\n *\n * // Get specific organization\n * const orgInfo = await sdsRepo.organizations.get(org.did);\n * ```\n *\n * @internal\n */\nexport class OrganizationOperationsImpl implements OrganizationOperations {\n /**\n * Creates a new OrganizationOperationsImpl.\n *\n * @param session - Authenticated OAuth session with fetchHandler\n * @param _repoDid - DID of the user's repository (reserved for future use)\n * @param serverUrl - SDS server URL\n * @param _logger - Optional logger for debugging (reserved for future use)\n *\n * @internal\n */\n constructor(\n private session: Session,\n private _repoDid: string,\n private serverUrl: string,\n private _logger?: LoggerInterface,\n ) {}\n\n /**\n * Creates a new organization.\n *\n * @param params - Organization parameters\n * @param params.name - Display name for the organization\n * @param params.description - Optional description of the organization's purpose\n * @param params.handle - Optional custom handle. If not provided, one is auto-generated.\n * @returns Promise resolving to the created organization info\n * @throws {@link NetworkError} if organization creation fails\n *\n * @remarks\n * The creating user automatically becomes the owner with full permissions.\n *\n * **Handle Format**: Handles are typically formatted as\n * `{name}.sds.{domain}` (e.g., \"my-team.sds.hypercerts.org\").\n * If you provide a custom handle, it must be unique on the SDS.\n *\n * @example Basic organization\n * ```typescript\n * const org = await repo.organizations.create({\n * name: \"Climate Action Team\",\n * });\n * console.log(`Created org: ${org.did}`);\n * ```\n *\n * @example With description and custom handle\n * ```typescript\n * const org = await repo.organizations.create({\n * name: \"Reforestation Initiative\",\n * description: \"Coordinating tree planting projects worldwide\",\n * handle: \"reforestation\",\n * });\n * ```\n */\n async create(params: CreateOrganizationParams): Promise<OrganizationInfo> {\n const userDid = this.session.did || this.session.sub;\n if (!userDid) {\n throw new NetworkError(\"No authenticated user found\");\n }\n\n if (!params.handlePrefix) {\n throw new ValidationError(\"Missing handlePrefix\");\n }\n if (!params.name) {\n throw new ValidationError(\"Missing name\");\n }\n\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.create`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n ...params,\n creatorDid: userDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to create organization: ${response.statusText}`);\n }\n\n const data = await response.json();\n return {\n did: data.did,\n handle: data.handle,\n name: data.name,\n description: data.description,\n createdAt: data.createdAt || new Date().toISOString(),\n accessType: data.accessType || \"owner\",\n permissions: data.permissions || {\n read: true,\n create: true,\n update: true,\n delete: true,\n admin: true,\n owner: true,\n },\n };\n }\n\n /**\n * Gets an organization by its DID.\n *\n * @param did - The organization's DID\n * @returns Promise resolving to organization info, or `null` if not found\n *\n * @remarks\n * This method searches through the user's accessible organizations.\n * If the organization exists but the user doesn't have access,\n * it will return `null`.\n *\n * @example\n * ```typescript\n * const org = await repo.organizations.get(\"did:plc:org123\");\n * if (org) {\n * console.log(`Found: ${org.name}`);\n * console.log(`Your role: ${org.accessType}`);\n * } else {\n * console.log(\"Organization not found or no access\");\n * }\n * ```\n */\n async get(did: string): Promise<OrganizationInfo | null> {\n try {\n const { organizations } = await this.list();\n return organizations.find((o) => o.did === did) ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * Lists organizations the current user has access to.\n *\n * @param params - Optional pagination parameters\n * @param params.limit - Maximum number of results (1-100, default 50)\n * @param params.cursor - Pagination cursor from previous response\n * @returns Promise resolving to organizations and optional cursor\n * @throws {@link NetworkError} if the list operation fails\n *\n * @remarks\n * Returns organizations where the user is either:\n * - The owner\n * - A collaborator with any permission level\n *\n * The `accessType` field indicates the user's relationship to each organization.\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await repo.organizations.list({ limit: 20 });\n * console.log(`Found ${page1.organizations.length} organizations`);\n *\n * // Get next page if available\n * if (page1.cursor) {\n * const page2 = await repo.organizations.list({ limit: 20, cursor: page1.cursor });\n * }\n *\n * // Filter by access type\n * const owned = page1.organizations.filter(o => o.accessType === \"owner\");\n * const shared = page1.organizations.filter(o => o.accessType === \"shared\");\n * ```\n *\n * @example Display organization details\n * ```typescript\n * const { organizations } = await repo.organizations.list();\n *\n * for (const org of organizations) {\n * console.log(`${org.name} (@${org.handle})`);\n * console.log(` DID: ${org.did}`);\n * console.log(` Access: ${org.accessType}`);\n * if (org.description) {\n * console.log(` Description: ${org.description}`);\n * }\n * }\n * ```\n */\n async list(params?: { limit?: number; cursor?: string }): Promise<{\n organizations: OrganizationInfo[];\n cursor?: string;\n }> {\n const userDid = this.session.did || this.session.sub;\n if (!userDid) {\n throw new NetworkError(\"No authenticated user found\");\n }\n\n const queryParams = new URLSearchParams({\n userDid,\n });\n\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n\n if (params?.cursor) {\n queryParams.set(\"cursor\", params.cursor);\n }\n\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.organization.list?${queryParams.toString()}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to list organizations: ${response.statusText}`);\n }\n\n const data = await response.json();\n const organizations = (data.organizations || []).map(\n (r: {\n did: string;\n handle: string;\n name: string;\n description?: string;\n createdAt?: string;\n accessType: \"owner\" | \"shared\" | \"none\";\n permissions: CollaboratorPermissions;\n }) => ({\n did: r.did,\n handle: r.handle,\n name: r.name,\n description: r.description,\n createdAt: r.createdAt || new Date().toISOString(),\n accessType: r.accessType,\n permissions: r.permissions,\n }),\n );\n\n return {\n organizations,\n cursor: data.cursor,\n };\n }\n}\n","/**\n * Repository - Unified fluent API for ATProto repository operations.\n *\n * This module provides the main interface for interacting with AT Protocol\n * data servers (PDS and SDS) through a consistent, fluent API.\n *\n * @packageDocumentation\n */\n\nimport { SDSRequiredError } from \"../core/errors.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport type { Session } from \"../core/types.js\";\nimport { ConfigurableAgent } from \"../agent/ConfigurableAgent.js\";\nimport type { Agent } from \"@atproto/api\";\n\n// Types\nexport type {\n RepositoryOptions,\n CreateResult,\n UpdateResult,\n PaginatedList,\n ListParams,\n RepositoryRole,\n RepositoryAccessGrant,\n OrganizationInfo,\n ProgressStep,\n} from \"./types.js\";\n\n// Interfaces\nexport type {\n RecordOperations,\n BlobOperations,\n ProfileOperations,\n HypercertOperations,\n HypercertEvents,\n CollaboratorOperations,\n OrganizationOperations,\n CreateHypercertParams,\n CreateHypercertResult,\n} from \"./interfaces.js\";\n\n// Implementations\nimport { RecordOperationsImpl } from \"./RecordOperationsImpl.js\";\nimport { BlobOperationsImpl } from \"./BlobOperationsImpl.js\";\nimport { ProfileOperationsImpl } from \"./ProfileOperationsImpl.js\";\nimport { HypercertOperationsImpl } from \"./HypercertOperationsImpl.js\";\nimport { CollaboratorOperationsImpl } from \"./CollaboratorOperationsImpl.js\";\nimport { OrganizationOperationsImpl } from \"./OrganizationOperationsImpl.js\";\n\nimport type {\n RecordOperations,\n BlobOperations,\n ProfileOperations,\n HypercertOperations,\n CollaboratorOperations,\n OrganizationOperations,\n} from \"./interfaces.js\";\n\n/**\n * Repository provides a fluent API for AT Protocol data operations.\n *\n * This class is the primary interface for working with data in the AT Protocol\n * ecosystem. It provides organized access to:\n *\n * - **Records**: Low-level CRUD operations for any AT Protocol record type\n * - **Blobs**: Binary data upload and retrieval (images, files)\n * - **Profile**: User profile management\n * - **Hypercerts**: High-level hypercert creation and management\n * - **Collaborators**: Access control for shared repositories (SDS only)\n * - **Organizations**: Organization management (SDS only)\n *\n * @remarks\n * The Repository uses lazy initialization for operation handlers - they are\n * created only when first accessed. This improves performance when you only\n * need a subset of operations.\n *\n * **PDS vs SDS:**\n * - **PDS (Personal Data Server)**: User's own data storage. All operations\n * except collaborators and organizations are available.\n * - **SDS (Shared Data Server)**: Collaborative data storage with access\n * control. All operations including collaborators and organizations.\n *\n * @example Basic usage\n * ```typescript\n * // Get a repository from the SDK\n * const repo = sdk.repository(session);\n *\n * // Access user profile\n * const profile = await repo.profile.get();\n *\n * // Create a hypercert\n * const result = await repo.hypercerts.create({\n * title: \"My Impact\",\n * description: \"Description of the impact\",\n * workScope: \"Climate Action\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: {\n * name: \"Attribution\",\n * type: \"license\",\n * description: \"CC-BY-4.0\",\n * },\n * });\n * ```\n *\n * @example Working with a different user's repository\n * ```typescript\n * // Get the current user's repo\n * const myRepo = sdk.repository(session);\n *\n * // Get another user's repo (read-only for most operations)\n * const otherRepo = myRepo.repo(\"did:plc:other-user-did\");\n * const theirProfile = await otherRepo.profile.get();\n * ```\n *\n * @example SDS operations\n * ```typescript\n * // Get SDS repository for collaborator features\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Manage collaborators\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:collaborator\",\n * role: \"editor\",\n * });\n *\n * // List organizations\n * const orgs = await sdsRepo.organizations.list();\n * ```\n *\n * @see {@link ATProtoSDK.repository} for creating Repository instances\n */\nexport class Repository {\n private session: Session;\n private serverUrl: string;\n private repoDid: string;\n private logger?: LoggerInterface;\n private agent: Agent;\n private _isSDS: boolean;\n\n // Lazily initialized operations\n private _records?: RecordOperationsImpl;\n private _blobs?: BlobOperationsImpl;\n private _profile?: ProfileOperationsImpl;\n private _hypercerts?: HypercertOperationsImpl;\n private _collaborators?: CollaboratorOperationsImpl;\n private _organizations?: OrganizationOperationsImpl;\n\n /**\n * Creates a new Repository instance.\n *\n * @param session - Authenticated OAuth session\n * @param serverUrl - Base URL of the AT Protocol server\n * @param repoDid - DID of the repository to operate on\n * @param isSDS - Whether this is a Shared Data Server\n * @param logger - Optional logger for debugging\n *\n * @remarks\n * This constructor is typically not called directly. Use\n * {@link ATProtoSDK.repository} to create Repository instances.\n *\n * @internal\n */\n constructor(session: Session, serverUrl: string, repoDid: string, isSDS: boolean, logger?: LoggerInterface) {\n this.session = session;\n this.serverUrl = serverUrl;\n this.repoDid = repoDid;\n this._isSDS = isSDS;\n this.logger = logger;\n\n // Create a ConfigurableAgent that routes requests to the specified server URL\n // This allows routing to PDS, SDS, or any custom server while maintaining\n // the OAuth session's authentication\n this.agent = new ConfigurableAgent(session, serverUrl);\n }\n\n /**\n * The DID (Decentralized Identifier) of this repository.\n *\n * This is the user or organization that owns the repository data.\n *\n * @example\n * ```typescript\n * console.log(`Working with repo: ${repo.did}`);\n * // Output: Working with repo: did:plc:abc123xyz...\n * ```\n */\n get did(): string {\n return this.repoDid;\n }\n\n /**\n * Whether this repository is on a Shared Data Server (SDS).\n *\n * SDS servers support additional features like collaborators and\n * organizations. Attempting to use these features on a PDS will\n * throw {@link SDSRequiredError}.\n *\n * @example\n * ```typescript\n * if (repo.isSDS) {\n * const collaborators = await repo.collaborators.list();\n * }\n * ```\n */\n get isSDS(): boolean {\n return this._isSDS;\n }\n\n /**\n * Gets the server URL this repository connects to.\n *\n * @returns The base URL of the AT Protocol server\n *\n * @example\n * ```typescript\n * console.log(repo.getServerUrl());\n * // Output: https://bsky.social or https://sds.hypercerts.org\n * ```\n */\n getServerUrl(): string {\n return this.serverUrl;\n }\n\n /**\n * Creates a Repository instance for a different DID on the same server.\n *\n * This allows you to read data from other users' repositories while\n * maintaining your authenticated session.\n *\n * @param did - The DID of the repository to access\n * @returns A new Repository instance for the specified DID\n *\n * @remarks\n * Write operations on another user's repository will typically fail\n * unless you have been granted collaborator access (SDS only).\n *\n * @example\n * ```typescript\n * // Read another user's profile\n * const otherRepo = repo.repo(\"did:plc:other-user\");\n * const profile = await otherRepo.profile.get();\n *\n * // List their public hypercerts\n * const hypercerts = await otherRepo.hypercerts.list();\n * ```\n */\n repo(did: string): Repository {\n return new Repository(this.session, this.serverUrl, did, this._isSDS, this.logger);\n }\n\n /**\n * Low-level record operations for CRUD on any AT Protocol record type.\n *\n * Use this for direct access to AT Protocol records when the high-level\n * APIs don't meet your needs.\n *\n * @returns {@link RecordOperations} interface for record CRUD\n *\n * @example\n * ```typescript\n * // Create a custom record\n * const result = await repo.records.create({\n * collection: \"org.example.myRecord\",\n * record: { foo: \"bar\" },\n * });\n *\n * // List records in a collection\n * const list = await repo.records.list({\n * collection: \"org.example.myRecord\",\n * limit: 50,\n * });\n *\n * // Get a specific record\n * const record = await repo.records.get({\n * collection: \"org.example.myRecord\",\n * rkey: \"abc123\",\n * });\n * ```\n */\n get records(): RecordOperations {\n if (!this._records) {\n this._records = new RecordOperationsImpl(this.agent, this.repoDid);\n }\n return this._records;\n }\n\n /**\n * Blob operations for uploading and retrieving binary data.\n *\n * Blobs are used for images, files, and other binary content associated\n * with records.\n *\n * @returns {@link BlobOperations} interface for blob management\n *\n * @example\n * ```typescript\n * // Upload an image\n * const imageBlob = new Blob([imageData], { type: \"image/png\" });\n * const uploadResult = await repo.blobs.upload(imageBlob);\n *\n * // The ref can be used in records\n * console.log(uploadResult.ref.$link); // CID of the blob\n *\n * // Retrieve a blob by CID\n * const { data, mimeType } = await repo.blobs.get(cid);\n * ```\n */\n get blobs(): BlobOperations {\n if (!this._blobs) {\n this._blobs = new BlobOperationsImpl(this.agent, this.repoDid, this.serverUrl);\n }\n return this._blobs;\n }\n\n /**\n * Profile operations for managing user profiles.\n *\n * @returns {@link ProfileOperations} interface for profile management\n *\n * @example\n * ```typescript\n * // Get current profile\n * const profile = await repo.profile.get();\n * console.log(profile.displayName);\n *\n * // Update profile\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"Updated bio\",\n * avatar: avatarBlob, // Optional: update avatar image\n * });\n * ```\n */\n get profile(): ProfileOperations {\n if (!this._profile) {\n this._profile = new ProfileOperationsImpl(this.agent, this.repoDid, this.serverUrl);\n }\n return this._profile;\n }\n\n /**\n * High-level hypercert operations.\n *\n * Provides a convenient API for creating and managing hypercerts,\n * including related records like locations, contributions, and evidence.\n *\n * @returns {@link HypercertOperations} interface with EventEmitter capabilities\n *\n * @example Creating a hypercert\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"Climate Action Project\",\n * description: \"Reduced carbon emissions by 1000 tons\",\n * workScope: \"Climate Action\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-06-30\",\n * rights: {\n * name: \"Public Domain\",\n * type: \"license\",\n * description: \"CC0 - No Rights Reserved\",\n * },\n * image: imageBlob, // Optional cover image\n * location: {\n * value: \"San Francisco, CA\",\n * name: \"SF Bay Area\",\n * },\n * });\n * console.log(`Created: ${result.hypercertUri}`);\n * ```\n *\n * @example Listening to events\n * ```typescript\n * repo.hypercerts.on(\"recordCreated\", ({ uri, cid }) => {\n * console.log(`Record created: ${uri}`);\n * });\n * ```\n */\n get hypercerts(): HypercertOperations {\n if (!this._hypercerts) {\n this._hypercerts = new HypercertOperationsImpl(this.agent, this.repoDid, this.serverUrl, this.logger);\n }\n return this._hypercerts;\n }\n\n /**\n * Collaborator operations for managing repository access.\n *\n * **SDS Only**: This property throws {@link SDSRequiredError} if accessed\n * on a PDS repository.\n *\n * @returns {@link CollaboratorOperations} interface for access control\n * @throws {@link SDSRequiredError} if not connected to an SDS server\n *\n * @example\n * ```typescript\n * // Ensure we're on SDS\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Grant editor access\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:new-collaborator\",\n * role: \"editor\",\n * });\n *\n * // List all collaborators\n * const collaborators = await sdsRepo.collaborators.list();\n *\n * // Check access\n * const hasAccess = await sdsRepo.collaborators.hasAccess(\"did:plc:someone\");\n *\n * // Revoke access\n * await sdsRepo.collaborators.revoke({ userDid: \"did:plc:former-collaborator\" });\n * ```\n */\n get collaborators(): CollaboratorOperations {\n if (!this._isSDS) {\n throw new SDSRequiredError(\"Collaborator operations are only available on SDS servers\");\n }\n if (!this._collaborators) {\n this._collaborators = new CollaboratorOperationsImpl(this.session, this.repoDid, this.serverUrl);\n }\n return this._collaborators;\n }\n\n /**\n * Organization operations for creating and managing organizations.\n *\n * **SDS Only**: This property throws {@link SDSRequiredError} if accessed\n * on a PDS repository.\n *\n * @returns {@link OrganizationOperations} interface for organization management\n * @throws {@link SDSRequiredError} if not connected to an SDS server\n *\n * @example\n * ```typescript\n * // Ensure we're on SDS\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Create an organization\n * const org = await sdsRepo.organizations.create({\n * name: \"My Organization\",\n * description: \"A team working on impact certificates\",\n * handle: \"my-org\", // Optional custom handle\n * });\n *\n * // List organizations you have access to\n * const orgs = await sdsRepo.organizations.list();\n *\n * // Get specific organization\n * const orgInfo = await sdsRepo.organizations.get(org.did);\n * ```\n */\n get organizations(): OrganizationOperations {\n if (!this._isSDS) {\n throw new SDSRequiredError(\"Organization operations are only available on SDS servers\");\n }\n if (!this._organizations) {\n this._organizations = new OrganizationOperationsImpl(this.session, this.repoDid, this.serverUrl, this.logger);\n }\n return this._organizations;\n }\n}\n","import { z } from \"zod\";\nimport type { SessionStore, StateStore, CacheInterface, LoggerInterface } from \"./interfaces.js\";\n\n/**\n * Zod schema for OAuth configuration validation.\n *\n * @remarks\n * All URLs must be valid and use HTTPS in production. The `jwkPrivate` field\n * should contain the private key in JWK (JSON Web Key) format as a string.\n */\nexport const OAuthConfigSchema = z.object({\n /**\n * URL to the OAuth client metadata JSON document.\n * This document describes your application to the authorization server.\n *\n * @see https://atproto.com/specs/oauth#client-metadata\n */\n clientId: z.string().url(),\n\n /**\n * URL where users are redirected after authentication.\n * Must match one of the redirect URIs in your client metadata.\n */\n redirectUri: z.string().url(),\n\n /**\n * OAuth scopes to request, space-separated.\n *\n * Can be a string of space-separated permissions or use the permission system:\n *\n * @example Using presets\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n * scope: ScopePresets.EMAIL_AND_PROFILE\n * ```\n *\n * @example Building custom scopes\n * ```typescript\n * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';\n * scope: buildScope(\n * new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .build()\n * )\n * ```\n *\n * @example Legacy scopes\n * ```typescript\n * scope: \"atproto transition:generic\"\n * ```\n *\n * @see https://atproto.com/specs/permission for permission details\n */\n scope: z.string().min(1, \"OAuth scope is required\"),\n\n /**\n * URL to your public JWKS (JSON Web Key Set) endpoint.\n * Used by the authorization server to verify your client's signatures.\n */\n jwksUri: z.string().url(),\n\n /**\n * Private JWK (JSON Web Key) as a JSON string.\n * Used for signing DPoP proofs and client assertions.\n *\n * @remarks\n * This should be kept secret and never exposed to clients.\n * Typically loaded from environment variables or a secrets manager.\n */\n jwkPrivate: z.string(),\n});\n\n/**\n * Zod schema for server URL configuration.\n *\n * @remarks\n * At least one server (PDS or SDS) should be configured for the SDK to be useful.\n */\nexport const ServerConfigSchema = z.object({\n /**\n * Personal Data Server URL - the user's own AT Protocol server.\n * This is the primary server for user data operations.\n *\n * @example \"https://bsky.social\"\n */\n pds: z.string().url().optional(),\n\n /**\n * Shared Data Server URL - for collaborative data storage.\n * Required for collaborator and organization operations.\n *\n * @example \"https://sds.hypercerts.org\"\n */\n sds: z.string().url().optional(),\n});\n\n/**\n * Zod schema for timeout configuration.\n *\n * @remarks\n * All timeout values are in milliseconds.\n */\nexport const TimeoutConfigSchema = z.object({\n /**\n * Timeout for fetching PDS metadata during identity resolution.\n * @default 5000 (5 seconds, set by OAuthClient)\n */\n pdsMetadata: z.number().positive().optional(),\n\n /**\n * Timeout for general API requests to PDS/SDS.\n * @default 30000 (30 seconds)\n */\n apiRequests: z.number().positive().optional(),\n});\n\n/**\n * Zod schema for SDK configuration validation.\n *\n * @remarks\n * This schema validates only the primitive/serializable parts of the configuration.\n * Storage interfaces ({@link SessionStore}, {@link StateStore}) cannot be validated\n * with Zod as they are runtime objects.\n */\nexport const ATProtoSDKConfigSchema = z.object({\n oauth: OAuthConfigSchema,\n servers: ServerConfigSchema.optional(),\n timeouts: TimeoutConfigSchema.optional(),\n});\n\n/**\n * Configuration options for the ATProto SDK.\n *\n * This interface defines all configuration needed to initialize the SDK,\n * including OAuth credentials, server endpoints, and optional customizations.\n *\n * @example Minimal configuration\n * ```typescript\n * const config: ATProtoSDKConfig = {\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: {\n * pds: \"https://bsky.social\",\n * },\n * };\n * ```\n *\n * @example Full configuration with custom storage\n * ```typescript\n * const config: ATProtoSDKConfig = {\n * oauth: { ... },\n * servers: {\n * pds: \"https://bsky.social\",\n * sds: \"https://sds.hypercerts.org\",\n * },\n * storage: {\n * sessionStore: new RedisSessionStore(redisClient),\n * stateStore: new RedisStateStore(redisClient),\n * },\n * timeouts: {\n * pdsMetadata: 5000,\n * apiRequests: 30000,\n * },\n * logger: console,\n * };\n * ```\n */\nexport interface ATProtoSDKConfig {\n /**\n * OAuth 2.0 configuration for authentication.\n *\n * Required fields for the OAuth flow with DPoP (Demonstrating Proof of Possession).\n * Your application must host the client metadata and JWKS endpoints.\n *\n * @see https://atproto.com/specs/oauth for AT Protocol OAuth specification\n */\n oauth: z.infer<typeof OAuthConfigSchema>;\n\n /**\n * Server URLs for PDS and SDS connections.\n *\n * - **PDS**: Personal Data Server - user's own data storage\n * - **SDS**: Shared Data Server - collaborative storage with access control\n */\n servers?: z.infer<typeof ServerConfigSchema>;\n\n /**\n * Storage adapters for persisting OAuth sessions and state.\n *\n * If not provided, in-memory implementations are used automatically.\n * **Warning**: In-memory storage is lost on process restart - use persistent\n * storage (Redis, database, etc.) in production.\n *\n * @example\n * ```typescript\n * storage: {\n * sessionStore: new RedisSessionStore(redis),\n * stateStore: new RedisStateStore(redis),\n * }\n * ```\n */\n storage?: {\n /**\n * Persistent storage for OAuth sessions.\n * Sessions contain access tokens, refresh tokens, and DPoP keys.\n */\n sessionStore?: SessionStore;\n\n /**\n * Temporary storage for OAuth state during the authorization flow.\n * State is short-lived and used for PKCE and CSRF protection.\n */\n stateStore?: StateStore;\n };\n\n /**\n * Custom fetch implementation for HTTP requests.\n *\n * Use this to add custom headers, logging, or to use a different HTTP client.\n * Must be compatible with the standard Fetch API.\n *\n * @example\n * ```typescript\n * fetch: async (url, init) => {\n * console.log(`Fetching: ${url}`);\n * return globalThis.fetch(url, init);\n * }\n * ```\n */\n fetch?: typeof fetch;\n\n /**\n * Timeout configuration for network requests.\n * Values are in milliseconds.\n */\n timeouts?: z.infer<typeof TimeoutConfigSchema>;\n\n /**\n * Cache for profiles, metadata, and other frequently accessed data.\n *\n * Implementing caching can significantly reduce API calls and improve performance.\n * The SDK does not provide a default cache - you must implement {@link CacheInterface}.\n */\n cache?: CacheInterface;\n\n /**\n * Logger for debugging and observability.\n *\n * The logger receives debug, info, warn, and error messages from the SDK.\n * Compatible with `console` or any logger implementing {@link LoggerInterface}.\n *\n * @example\n * ```typescript\n * logger: console\n * // or\n * logger: pino()\n * // or\n * logger: winston.createLogger({ ... })\n * ```\n */\n logger?: LoggerInterface;\n}\n","import { OAuthClient } from \"../auth/OAuthClient.js\";\nimport { Repository } from \"../repository/Repository.js\";\nimport type { RepositoryOptions } from \"../repository/types.js\";\nimport { InMemorySessionStore } from \"../storage/InMemorySessionStore.js\";\nimport { InMemoryStateStore } from \"../storage/InMemoryStateStore.js\";\nimport type { ATProtoSDKConfig } from \"./config.js\";\nimport { ATProtoSDKConfigSchema } from \"./config.js\";\nimport { ValidationError, NetworkError } from \"./errors.js\";\nimport type { Session } from \"./types.js\";\n\n/**\n * Options for the OAuth authorization flow.\n */\nexport interface AuthorizeOptions {\n /**\n * OAuth scope string to request specific permissions.\n * Overrides the default scope configured in {@link ATProtoSDKConfig.oauth.scope}.\n *\n * Can use the permission system for type-safe scope building.\n *\n * @example Using presets\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n *\n * // Request email and profile access\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.EMAIL_AND_PROFILE\n * });\n *\n * // Request full posting capabilities\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.POSTING_APP\n * });\n * ```\n *\n * @example Building custom scopes\n * ```typescript\n * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';\n *\n * const scope = buildScope(\n * new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .blob(['image/*'])\n * .build()\n * );\n *\n * await sdk.authorize(\"user.bsky.social\", { scope });\n * ```\n *\n * @example Legacy scopes\n * ```typescript\n * // Request read-only access\n * await sdk.authorize(\"user.bsky.social\", { scope: \"atproto\" });\n *\n * // Request full access (legacy)\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: \"atproto transition:generic\"\n * });\n * ```\n */\n scope?: string;\n}\n\n/**\n * Main ATProto SDK class providing OAuth authentication and repository access.\n *\n * This is the primary entry point for interacting with AT Protocol servers.\n * It handles the OAuth 2.0 flow with DPoP (Demonstrating Proof of Possession)\n * and provides access to repository operations for managing records, blobs,\n * and profiles.\n *\n * @example Basic usage with OAuth flow\n * ```typescript\n * import { ATProtoSDK, InMemorySessionStore, InMemoryStateStore } from \"@hypercerts-org/sdk\";\n *\n * const sdk = new ATProtoSDK({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: {\n * pds: \"https://bsky.social\",\n * sds: \"https://sds.hypercerts.org\",\n * },\n * });\n *\n * // Start OAuth flow - redirect user to this URL\n * const authUrl = await sdk.authorize(\"user.bsky.social\");\n *\n * // After user returns, handle the callback\n * const session = await sdk.callback(new URLSearchParams(window.location.search));\n *\n * // Get a repository to work with data\n * const repo = sdk.repository(session);\n * ```\n *\n * @example Restoring an existing session\n * ```typescript\n * // Restore a previous session by DID\n * const session = await sdk.restoreSession(\"did:plc:abc123...\");\n * if (session) {\n * const repo = sdk.repository(session);\n * // Continue working with the restored session\n * }\n * ```\n *\n * @see {@link ATProtoSDKConfig} for configuration options\n * @see {@link Repository} for data operations\n * @see {@link OAuthClient} for OAuth implementation details\n */\nexport class ATProtoSDK {\n private oauthClient: OAuthClient;\n private config: ATProtoSDKConfig;\n private logger?: ATProtoSDKConfig[\"logger\"];\n\n /**\n * Creates a new ATProto SDK instance.\n *\n * @param config - SDK configuration including OAuth credentials, server URLs, and optional storage adapters\n * @throws {@link ValidationError} if the configuration is invalid (e.g., malformed URLs, missing required fields)\n *\n * @remarks\n * If no storage adapters are provided, in-memory implementations are used.\n * These are suitable for development and testing but **not recommended for production**\n * as sessions will be lost on restart.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses in-memory storage)\n * const sdk = new ATProtoSDK({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: privateKeyJwk,\n * },\n * servers: { pds: \"https://bsky.social\" },\n * });\n * ```\n */\n constructor(config: ATProtoSDKConfig) {\n // Validate configuration\n const validationResult = ATProtoSDKConfigSchema.safeParse(config);\n if (!validationResult.success) {\n throw new ValidationError(`Invalid SDK configuration: ${validationResult.error.message}`, validationResult.error);\n }\n\n // Apply defaults for optional storage\n const configWithDefaults: ATProtoSDKConfig = {\n ...config,\n storage: {\n sessionStore: config.storage?.sessionStore ?? new InMemorySessionStore(),\n stateStore: config.storage?.stateStore ?? new InMemoryStateStore(),\n },\n };\n\n this.config = configWithDefaults;\n this.logger = config.logger;\n\n // Initialize OAuth client\n this.oauthClient = new OAuthClient(configWithDefaults);\n\n this.logger?.info(\"ATProto SDK initialized\");\n }\n\n /**\n * Initiates the OAuth authorization flow.\n *\n * This method starts the OAuth 2.0 authorization flow by resolving the user's\n * identity and generating an authorization URL. The user should be redirected\n * to this URL to authenticate.\n *\n * @param identifier - The user's ATProto identifier. Can be:\n * - A handle (e.g., `\"user.bsky.social\"`)\n * - A DID (e.g., `\"did:plc:abc123...\"`)\n * - A PDS URL (e.g., `\"https://bsky.social\"`)\n * @param options - Optional authorization settings\n * @returns A Promise resolving to the authorization URL to redirect the user to\n * @throws {@link ValidationError} if the identifier is empty or invalid\n * @throws {@link NetworkError} if the identity cannot be resolved\n *\n * @example\n * ```typescript\n * // Using a handle\n * const authUrl = await sdk.authorize(\"alice.bsky.social\");\n *\n * // Using a DID directly\n * const authUrl = await sdk.authorize(\"did:plc:abc123xyz\");\n *\n * // With custom scope\n * const authUrl = await sdk.authorize(\"alice.bsky.social\", {\n * scope: \"atproto transition:generic\"\n * });\n *\n * // Redirect user to authUrl\n * window.location.href = authUrl;\n * ```\n */\n async authorize(identifier: string, options?: AuthorizeOptions): Promise<string> {\n if (!identifier || !identifier.trim()) {\n throw new ValidationError(\"ATProto identifier is required\");\n }\n\n return this.oauthClient.authorize(identifier.trim(), options);\n }\n\n /**\n * Handles the OAuth callback and exchanges the authorization code for tokens.\n *\n * Call this method when the user is redirected back to your application\n * after authenticating. It validates the OAuth state, exchanges the\n * authorization code for access/refresh tokens, and creates a session.\n *\n * @param params - URL search parameters from the callback URL\n * @returns A Promise resolving to the authenticated OAuth session\n * @throws {@link AuthenticationError} if the callback parameters are invalid or the code exchange fails\n * @throws {@link ValidationError} if required parameters are missing\n *\n * @example\n * ```typescript\n * // In your callback route handler\n * const params = new URLSearchParams(window.location.search);\n * // params contains: code, state, iss (issuer)\n *\n * const session = await sdk.callback(params);\n * console.log(`Authenticated as ${session.did}`);\n *\n * // Store the DID to restore the session later\n * localStorage.setItem(\"userDid\", session.did);\n * ```\n */\n async callback(params: URLSearchParams): Promise<Session> {\n return this.oauthClient.callback(params);\n }\n\n /**\n * Restores an existing OAuth session by DID.\n *\n * Use this method to restore a previously authenticated session, typically\n * on application startup. The method retrieves the stored session and\n * automatically refreshes expired tokens if needed.\n *\n * @param did - The user's Decentralized Identifier (DID), e.g., `\"did:plc:abc123...\"`\n * @returns A Promise resolving to the restored session, or `null` if no session exists\n * @throws {@link ValidationError} if the DID is empty\n * @throws {@link SessionExpiredError} if the session cannot be refreshed\n *\n * @example\n * ```typescript\n * // On application startup\n * const savedDid = localStorage.getItem(\"userDid\");\n * if (savedDid) {\n * const session = await sdk.restoreSession(savedDid);\n * if (session) {\n * // User is still authenticated\n * const repo = sdk.repository(session);\n * } else {\n * // Session not found, user needs to re-authenticate\n * const authUrl = await sdk.authorize(savedDid);\n * }\n * }\n * ```\n */\n async restoreSession(did: string): Promise<Session | null> {\n if (!did || !did.trim()) {\n throw new ValidationError(\"DID is required\");\n }\n\n return this.oauthClient.restore(did.trim());\n }\n\n /**\n * Revokes an OAuth session, logging the user out.\n *\n * This method invalidates the session's tokens and removes it from storage.\n * After revocation, the session can no longer be used or restored.\n *\n * @param did - The user's DID to revoke the session for\n * @throws {@link ValidationError} if the DID is empty\n *\n * @example\n * ```typescript\n * // Log out the user\n * await sdk.revokeSession(session.did);\n * localStorage.removeItem(\"userDid\");\n * ```\n */\n async revokeSession(did: string): Promise<void> {\n if (!did || !did.trim()) {\n throw new ValidationError(\"DID is required\");\n }\n\n return this.oauthClient.revoke(did.trim());\n }\n\n /**\n * Gets the account email address from the authenticated session.\n *\n * This method retrieves the email address associated with the user's account\n * by calling the `com.atproto.server.getSession` endpoint. The email will only\n * be returned if the appropriate OAuth scope was granted during authorization.\n *\n * Required OAuth scopes:\n * - **Granular permissions**: `account:email?action=read` or `account:email`\n * - **Transitional permissions**: `transition:email`\n *\n * @param session - An authenticated OAuth session\n * @returns A Promise resolving to email info, or `null` if permission not granted\n * @throws {@link ValidationError} if the session is invalid\n * @throws {@link NetworkError} if the API request fails\n *\n * @example Using granular permissions\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n *\n * // Authorize with email scope\n * const authUrl = await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.EMAIL_READ\n * });\n *\n * // After callback...\n * const emailInfo = await sdk.getAccountEmail(session);\n * if (emailInfo) {\n * console.log(`Email: ${emailInfo.email}`);\n * console.log(`Confirmed: ${emailInfo.emailConfirmed}`);\n * } else {\n * console.log(\"Email permission not granted\");\n * }\n * ```\n *\n * @example Using transitional permissions (legacy)\n * ```typescript\n * // Authorize with transition:email scope\n * const authUrl = await sdk.authorize(\"user.bsky.social\", {\n * scope: \"atproto transition:email\"\n * });\n *\n * // After callback...\n * const emailInfo = await sdk.getAccountEmail(session);\n * ```\n */\n async getAccountEmail(session: Session): Promise<{ email: string; emailConfirmed: boolean } | null> {\n if (!session) {\n throw new ValidationError(\"Session is required\");\n }\n\n try {\n // Determine PDS URL from session or config\n const pdsUrl = this.config.servers?.pds;\n if (!pdsUrl) {\n throw new ValidationError(\"PDS server URL not configured\");\n }\n\n // Call com.atproto.server.getSession endpoint using session's fetchHandler\n // which automatically includes proper authorization with DPoP\n const response = await session.fetchHandler(\"/xrpc/com.atproto.server.getSession\", {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to get session info: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as {\n email?: string;\n emailConfirmed?: boolean;\n did: string;\n handle: string;\n };\n\n // Return null if email not present (permission not granted)\n if (!data.email) {\n return null;\n }\n\n return {\n email: data.email,\n emailConfirmed: data.emailConfirmed ?? false,\n };\n } catch (error) {\n this.logger?.error(\"Failed to get account email\", { error });\n if (error instanceof ValidationError || error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to get account email: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Creates a repository instance for data operations.\n *\n * The repository provides a fluent API for working with AT Protocol data\n * including records, blobs, profiles, and domain-specific operations like\n * hypercerts and collaborators.\n *\n * @param session - An authenticated OAuth session\n * @param options - Repository configuration options\n * @returns A {@link Repository} instance configured for the specified server\n * @throws {@link ValidationError} if the session is invalid or server URL is not configured\n *\n * @remarks\n * - **PDS (Personal Data Server)**: User's own data storage, default for most operations\n * - **SDS (Shared Data Server)**: Shared data storage with collaborator support\n *\n * @example Using default PDS\n * ```typescript\n * const repo = sdk.repository(session);\n * const profile = await repo.profile.get();\n * ```\n *\n * @example Using configured SDS\n * ```typescript\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n * const collaborators = await sdsRepo.collaborators.list();\n * ```\n *\n * @example Using custom server URL\n * ```typescript\n * const customRepo = sdk.repository(session, {\n * serverUrl: \"https://custom.atproto.server\"\n * });\n * ```\n */\n repository(session: Session, options?: RepositoryOptions): Repository {\n if (!session) {\n throw new ValidationError(\"Session is required\");\n }\n\n // Determine server URL\n let serverUrl: string;\n let isSDS = false;\n\n if (options?.serverUrl) {\n // Custom URL provided\n serverUrl = options.serverUrl;\n // Check if it matches configured SDS\n isSDS = this.config.servers?.sds === serverUrl;\n } else if (options?.server === \"sds\") {\n // Use configured SDS\n if (!this.config.servers?.sds) {\n throw new ValidationError(\"SDS server URL not configured\");\n }\n serverUrl = this.config.servers.sds;\n isSDS = true;\n } else if (options?.server === \"pds\" || !options?.server) {\n // Use configured PDS (default)\n if (!this.config.servers?.pds) {\n throw new ValidationError(\"PDS server URL not configured\");\n }\n serverUrl = this.config.servers.pds;\n isSDS = false;\n } else {\n // Custom server string (treat as URL)\n serverUrl = options.server;\n isSDS = this.config.servers?.sds === serverUrl;\n }\n\n // Get repository DID (default to session DID)\n const repoDid = session.did || session.sub;\n\n return new Repository(session, serverUrl, repoDid, isSDS, this.logger);\n }\n\n /**\n * The configured PDS (Personal Data Server) URL.\n *\n * @returns The PDS URL if configured, otherwise `undefined`\n */\n get pdsUrl(): string | undefined {\n return this.config.servers?.pds;\n }\n\n /**\n * The configured SDS (Shared Data Server) URL.\n *\n * @returns The SDS URL if configured, otherwise `undefined`\n */\n get sdsUrl(): string | undefined {\n return this.config.servers?.sds;\n }\n}\n\n/**\n * Factory function to create an ATProto SDK instance.\n *\n * This is a convenience function equivalent to `new ATProtoSDK(config)`.\n *\n * @param config - SDK configuration\n * @returns A new {@link ATProtoSDK} instance\n *\n * @example\n * ```typescript\n * import { createATProtoSDK } from \"@hypercerts-org/sdk\";\n *\n * const sdk = createATProtoSDK({\n * oauth: { ... },\n * servers: { pds: \"https://bsky.social\" },\n * });\n * ```\n */\nexport function createATProtoSDK(config: ATProtoSDKConfig): ATProtoSDK {\n return new ATProtoSDK(config);\n}\n","import type { OAuthSession } from \"@atproto/oauth-client-node\";\nimport { z } from \"zod\";\n\n/**\n * Decentralized Identifier (DID) - a unique, persistent identifier for AT Protocol users.\n *\n * DIDs are the canonical identifier for users in the AT Protocol ecosystem.\n * Unlike handles which can change, DIDs remain constant for the lifetime of an account.\n *\n * @remarks\n * AT Protocol supports multiple DID methods:\n * - `did:plc:` - PLC (Public Ledger of Credentials) DIDs, most common for Bluesky users\n * - `did:web:` - Web DIDs, resolved via HTTPS\n *\n * @example\n * ```typescript\n * const did: DID = \"did:plc:ewvi7nxzyoun6zhxrhs64oiz\";\n * const webDid: DID = \"did:web:example.com\";\n * ```\n *\n * @see https://atproto.com/specs/did for DID specification\n */\nexport type DID = string;\n\n/**\n * OAuth session with DPoP (Demonstrating Proof of Possession) support.\n *\n * This type represents an authenticated user session. It wraps the\n * `@atproto/oauth-client-node` OAuthSession and contains:\n * - Access token for API requests\n * - Refresh token for obtaining new access tokens\n * - DPoP key pair for proof-of-possession\n * - User's DID and other identity information\n *\n * @remarks\n * Sessions are managed by the SDK and automatically refresh when tokens expire.\n * Store the user's DID to restore sessions later with {@link ATProtoSDK.restoreSession}.\n *\n * Key properties from OAuthSession:\n * - `did` or `sub`: The user's DID\n * - `handle`: The user's handle (e.g., \"user.bsky.social\")\n *\n * @example\n * ```typescript\n * const session = await sdk.callback(params);\n *\n * // Access user identity\n * console.log(`Logged in as: ${session.did}`);\n *\n * // Use session for repository operations\n * const repo = sdk.repository(session);\n * ```\n *\n * @see https://atproto.com/specs/oauth for OAuth specification\n */\nexport type Session = OAuthSession;\n\n/**\n * Zod schema for collaborator permissions in SDS repositories.\n *\n * Defines the granular permissions a collaborator can have on a shared repository.\n * Permissions follow a hierarchical model where higher-level permissions\n * typically imply lower-level ones.\n */\nexport const CollaboratorPermissionsSchema = z.object({\n /**\n * Can read/view records in the repository.\n * This is the most basic permission level.\n */\n read: z.boolean(),\n\n /**\n * Can create new records in the repository.\n * Typically implies `read` permission.\n */\n create: z.boolean(),\n\n /**\n * Can modify existing records in the repository.\n * Typically implies `read` and `create` permissions.\n */\n update: z.boolean(),\n\n /**\n * Can delete records from the repository.\n * Typically implies `read`, `create`, and `update` permissions.\n */\n delete: z.boolean(),\n\n /**\n * Can manage collaborators and their permissions.\n * Administrative permission that allows inviting/removing collaborators.\n */\n admin: z.boolean(),\n\n /**\n * Full ownership of the repository.\n * Owners have all permissions and cannot be removed by other admins.\n * There must always be at least one owner.\n */\n owner: z.boolean(),\n});\n\n/**\n * Collaborator permissions for SDS (Shared Data Server) repositories.\n *\n * These permissions control what actions a collaborator can perform\n * on records within a shared repository.\n *\n * @example\n * ```typescript\n * // Read-only collaborator\n * const readOnlyPerms: CollaboratorPermissions = {\n * read: true,\n * create: false,\n * update: false,\n * delete: false,\n * admin: false,\n * owner: false,\n * };\n *\n * // Editor collaborator\n * const editorPerms: CollaboratorPermissions = {\n * read: true,\n * create: true,\n * update: true,\n * delete: false,\n * admin: false,\n * owner: false,\n * };\n *\n * // Admin collaborator\n * const adminPerms: CollaboratorPermissions = {\n * read: true,\n * create: true,\n * update: true,\n * delete: true,\n * admin: true,\n * owner: false,\n * };\n * ```\n */\nexport type CollaboratorPermissions = z.infer<typeof CollaboratorPermissionsSchema>;\n\n/**\n * Zod schema for SDS organization data.\n *\n * Organizations are top-level entities in SDS that can own repositories\n * and have multiple collaborators with different permission levels.\n */\nexport const OrganizationSchema = z.object({\n /**\n * The organization's DID - unique identifier.\n * Format: \"did:plc:...\" or \"did:web:...\"\n */\n did: z.string(),\n\n /**\n * The organization's handle - human-readable identifier.\n * Format: \"orgname.sds.hypercerts.org\" or similar\n */\n handle: z.string(),\n\n /**\n * Display name for the organization.\n */\n name: z.string(),\n\n /**\n * Optional description of the organization's purpose.\n */\n description: z.string().optional(),\n\n /**\n * ISO 8601 timestamp when the organization was created.\n * Format: \"2024-01-15T10:30:00.000Z\"\n */\n createdAt: z.string(),\n\n /**\n * The current user's permissions within this organization.\n */\n permissions: CollaboratorPermissionsSchema,\n\n /**\n * How the current user relates to this organization.\n * - `\"owner\"`: User created or owns the organization\n * - `\"shared\"`: User was invited to collaborate (has permissions)\n * - `\"none\"`: User has no access to this organization\n */\n accessType: z.enum([\"owner\", \"shared\", \"none\"]),\n});\n\n/**\n * SDS Organization entity.\n *\n * Represents an organization on a Shared Data Server. Organizations\n * provide a way to group repositories and manage access for teams.\n *\n * @example\n * ```typescript\n * const org: Organization = {\n * did: \"did:plc:org123abc\",\n * handle: \"my-team.sds.hypercerts.org\",\n * name: \"My Team\",\n * description: \"A team working on impact certificates\",\n * createdAt: \"2024-01-15T10:30:00.000Z\",\n * permissions: {\n * read: true,\n * create: true,\n * update: true,\n * delete: true,\n * admin: true,\n * owner: true,\n * },\n * accessType: \"owner\",\n * };\n * ```\n */\nexport type Organization = z.infer<typeof OrganizationSchema>;\n\n/**\n * Zod schema for collaborator data.\n *\n * Represents a user who has been granted access to a shared repository\n * or organization with specific permissions.\n */\nexport const CollaboratorSchema = z.object({\n /**\n * The collaborator's DID - their unique identifier.\n * Format: \"did:plc:...\" or \"did:web:...\"\n */\n userDid: z.string(),\n\n /**\n * The permissions granted to this collaborator.\n */\n permissions: CollaboratorPermissionsSchema,\n\n /**\n * DID of the user who granted these permissions.\n * Useful for audit trails.\n */\n grantedBy: z.string(),\n\n /**\n * ISO 8601 timestamp when permissions were granted.\n * Format: \"2024-01-15T10:30:00.000Z\"\n */\n grantedAt: z.string(),\n\n /**\n * ISO 8601 timestamp when permissions were revoked, if applicable.\n * Undefined if the collaborator is still active.\n */\n revokedAt: z.string().optional(),\n});\n\n/**\n * Collaborator information for SDS repositories.\n *\n * Represents a user who has been granted access to collaborate on\n * a shared repository or organization.\n *\n * @example\n * ```typescript\n * const collaborator: Collaborator = {\n * userDid: \"did:plc:user456def\",\n * permissions: {\n * read: true,\n * create: true,\n * update: true,\n * delete: false,\n * admin: false,\n * owner: false,\n * },\n * grantedBy: \"did:plc:owner123abc\",\n * grantedAt: \"2024-02-01T14:00:00.000Z\",\n * };\n * ```\n */\nexport type Collaborator = z.infer<typeof CollaboratorSchema>;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/lib/url-utils.ts","../src/core/errors.ts","../src/storage/InMemorySessionStore.ts","../src/storage/InMemoryStateStore.ts","../src/auth/permissions.ts","../src/auth/OAuthClient.ts","../src/agent/ConfigurableAgent.ts","../src/repository/LexiconRegistry.ts","../src/repository/RecordOperationsImpl.ts","../src/repository/BlobOperationsImpl.ts","../src/repository/ProfileOperationsImpl.ts","../src/lexicons.ts","../src/repository/HypercertOperationsImpl.ts","../src/repository/CollaboratorOperationsImpl.ts","../src/repository/OrganizationOperationsImpl.ts","../src/repository/Repository.ts","../src/core/config.ts","../src/core/SDK.ts","../src/repository/BaseOperations.ts","../src/lexicons/utils.ts","../src/lexicons/builders.ts","../src/lexicons/sidecar.ts","../src/core/types.ts"],"sourcesContent":["/**\n * Type guard to check if a URL is a loopback address.\n *\n * Loopback addresses are used for local development and testing.\n * They include localhost, 127.0.0.1, and [::1] (IPv6 loopback).\n *\n * @param url - The URL to check\n * @returns True if the URL is a loopback address\n *\n * @example\n * ```typescript\n * isLoopbackUrl('http://localhost:3000'); // true\n * isLoopbackUrl('http://127.0.0.1:8080'); // true\n * isLoopbackUrl('http://[::1]:3000'); // true\n * isLoopbackUrl('http://example.com'); // false\n * isLoopbackUrl('https://localhost:3000'); // false (must be http)\n * ```\n */\nexport function isLoopbackUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"http:\") {\n return false;\n }\n const hostname = parsed.hostname.toLowerCase();\n return hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n } catch {\n return false;\n }\n}\n","/**\n * Base error class for all SDK errors.\n *\n * All errors thrown by the Hypercerts SDK extend this class, making it easy\n * to catch and handle SDK-specific errors.\n *\n * @example Catching all SDK errors\n * ```typescript\n * try {\n * await sdk.authorize(\"user.bsky.social\");\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * console.error(`SDK Error [${error.code}]: ${error.message}`);\n * console.error(`HTTP Status: ${error.status}`);\n * }\n * }\n * ```\n *\n * @example Checking error codes\n * ```typescript\n * try {\n * await repo.records.get(collection, rkey);\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * switch (error.code) {\n * case \"AUTHENTICATION_ERROR\":\n * // Redirect to login\n * break;\n * case \"VALIDATION_ERROR\":\n * // Show form errors\n * break;\n * case \"NETWORK_ERROR\":\n * // Retry or show offline message\n * break;\n * }\n * }\n * }\n * ```\n */\nexport class ATProtoSDKError extends Error {\n /**\n * Creates a new SDK error.\n *\n * @param message - Human-readable error description\n * @param code - Machine-readable error code for programmatic handling\n * @param status - HTTP status code associated with this error type\n * @param cause - The underlying error that caused this error, if any\n */\n constructor(\n message: string,\n public code: string,\n public status?: number,\n public cause?: unknown,\n ) {\n super(message);\n this.name = \"ATProtoSDKError\";\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when authentication fails.\n *\n * This error indicates problems with the OAuth flow, invalid credentials,\n * or failed token exchanges. Common causes:\n * - Invalid authorization code\n * - Expired or invalid state parameter\n * - Revoked or invalid tokens\n * - User denied authorization\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.callback(params);\n * } catch (error) {\n * if (error instanceof AuthenticationError) {\n * // Clear any stored state and redirect to login\n * console.error(\"Authentication failed:\", error.message);\n * }\n * }\n * ```\n */\nexport class AuthenticationError extends ATProtoSDKError {\n /**\n * Creates an authentication error.\n *\n * @param message - Description of what went wrong during authentication\n * @param cause - The underlying error (e.g., from the OAuth client)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"AUTHENTICATION_ERROR\", 401, cause);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Error thrown when a session has expired and cannot be refreshed.\n *\n * This typically occurs when:\n * - The refresh token has expired (usually after extended inactivity)\n * - The user has revoked access to your application\n * - The PDS has invalidated all sessions for the user\n *\n * When this error occurs, the user must re-authenticate.\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.restoreSession(did);\n * } catch (error) {\n * if (error instanceof SessionExpiredError) {\n * // Clear stored session and prompt user to log in again\n * localStorage.removeItem(\"userDid\");\n * window.location.href = \"/login\";\n * }\n * }\n * ```\n */\nexport class SessionExpiredError extends ATProtoSDKError {\n /**\n * Creates a session expired error.\n *\n * @param message - Description of why the session expired\n * @param cause - The underlying error from the token refresh attempt\n */\n constructor(message: string = \"Session expired\", cause?: unknown) {\n super(message, \"SESSION_EXPIRED\", 401, cause);\n this.name = \"SessionExpiredError\";\n }\n}\n\n/**\n * Error thrown when input validation fails.\n *\n * This error indicates that provided data doesn't meet the required format\n * or constraints. Common causes:\n * - Missing required fields\n * - Invalid URL formats\n * - Invalid DID format\n * - Schema validation failures for records\n * - Invalid configuration values\n *\n * @example\n * ```typescript\n * try {\n * await sdk.authorize(\"\"); // Empty identifier\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Invalid input:\", error.message);\n * // Show validation error to user\n * }\n * }\n * ```\n *\n * @example With Zod validation cause\n * ```typescript\n * try {\n * await repo.records.create(collection, record);\n * } catch (error) {\n * if (error instanceof ValidationError && error.cause) {\n * // error.cause may be a ZodError with detailed field errors\n * const zodError = error.cause as ZodError;\n * zodError.errors.forEach(e => {\n * console.error(`Field ${e.path.join(\".\")}: ${e.message}`);\n * });\n * }\n * }\n * ```\n */\nexport class ValidationError extends ATProtoSDKError {\n /**\n * Creates a validation error.\n *\n * @param message - Description of what validation failed\n * @param cause - The underlying validation error (e.g., ZodError)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"VALIDATION_ERROR\", 400, cause);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Error thrown when a network request fails.\n *\n * This error indicates connectivity issues or server unavailability.\n * Common causes:\n * - No internet connection\n * - DNS resolution failure\n * - Server timeout\n * - Server returned 5xx error\n * - TLS/SSL errors\n *\n * These errors are typically transient and may succeed on retry.\n *\n * @example\n * ```typescript\n * try {\n * await repo.records.list(collection);\n * } catch (error) {\n * if (error instanceof NetworkError) {\n * // Implement retry logic or show offline indicator\n * console.error(\"Network error:\", error.message);\n * await retryWithBackoff(() => repo.records.list(collection));\n * }\n * }\n * ```\n */\nexport class NetworkError extends ATProtoSDKError {\n /**\n * Creates a network error.\n *\n * @param message - Description of the network failure\n * @param cause - The underlying error (e.g., fetch error, timeout)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"NETWORK_ERROR\", 503, cause);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Error thrown when an SDS-only operation is attempted on a PDS.\n *\n * Certain operations are only available on Shared Data Servers (SDS),\n * such as collaborator management and organization operations.\n * This error is thrown when these operations are attempted on a\n * Personal Data Server (PDS).\n *\n * @example\n * ```typescript\n * const pdsRepo = sdk.repository(session); // Default is PDS\n *\n * try {\n * // This will throw SDSRequiredError\n * await pdsRepo.collaborators.list();\n * } catch (error) {\n * if (error instanceof SDSRequiredError) {\n * // Switch to SDS for this operation\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n * const collaborators = await sdsRepo.collaborators.list();\n * }\n * }\n * ```\n */\nexport class SDSRequiredError extends ATProtoSDKError {\n /**\n * Creates an SDS required error.\n *\n * @param message - Description of which operation requires SDS\n * @param cause - Any underlying error\n */\n constructor(message: string = \"This operation requires a Shared Data Server (SDS)\", cause?: unknown) {\n super(message, \"SDS_REQUIRED\", 400, cause);\n this.name = \"SDSRequiredError\";\n }\n}\n","import type { SessionStore } from \"../core/interfaces.js\";\nimport type { NodeSavedSession } from \"@atproto/oauth-client-node\";\n\n/**\n * In-memory implementation of the SessionStore interface.\n *\n * This store keeps OAuth sessions in memory using a Map. It's intended\n * for development, testing, and simple use cases where session persistence\n * across restarts is not required.\n *\n * @remarks\n * **Warning**: This implementation is **not suitable for production** because:\n * - Sessions are lost when the process restarts\n * - Sessions cannot be shared across multiple server instances\n * - No automatic cleanup of expired sessions\n *\n * For production, implement {@link SessionStore} with a persistent backend:\n * - **Redis**: Good for distributed systems, supports TTL\n * - **PostgreSQL/MySQL**: Good for existing database infrastructure\n * - **MongoDB**: Good for document-based storage\n *\n * @example Basic usage\n * ```typescript\n * import { InMemorySessionStore } from \"@hypercerts-org/sdk/storage\";\n *\n * const sessionStore = new InMemorySessionStore();\n *\n * const sdk = new ATProtoSDK({\n * oauth: { ... },\n * storage: {\n * sessionStore, // Will warn in logs for production\n * },\n * });\n * ```\n *\n * @example Testing usage\n * ```typescript\n * const sessionStore = new InMemorySessionStore();\n *\n * // After tests, clean up\n * sessionStore.clear();\n * ```\n *\n * @see {@link SessionStore} for the interface definition\n * @see {@link InMemoryStateStore} for the corresponding state store\n */\nexport class InMemorySessionStore implements SessionStore {\n /**\n * Internal storage for sessions, keyed by DID.\n * @internal\n */\n private sessions = new Map<string, NodeSavedSession>();\n\n /**\n * Retrieves a session by DID.\n *\n * @param did - The user's Decentralized Identifier\n * @returns Promise resolving to the session, or `undefined` if not found\n *\n * @example\n * ```typescript\n * const session = await sessionStore.get(\"did:plc:abc123\");\n * if (session) {\n * console.log(\"Session found\");\n * }\n * ```\n */\n async get(did: string): Promise<NodeSavedSession | undefined> {\n return this.sessions.get(did);\n }\n\n /**\n * Stores or updates a session.\n *\n * @param did - The user's DID to use as the key\n * @param session - The session data to store\n *\n * @remarks\n * If a session already exists for the DID, it is overwritten.\n *\n * @example\n * ```typescript\n * await sessionStore.set(\"did:plc:abc123\", sessionData);\n * ```\n */\n async set(did: string, session: NodeSavedSession): Promise<void> {\n this.sessions.set(did, session);\n }\n\n /**\n * Deletes a session by DID.\n *\n * @param did - The DID of the session to delete\n *\n * @remarks\n * If no session exists for the DID, this is a no-op.\n *\n * @example\n * ```typescript\n * await sessionStore.del(\"did:plc:abc123\");\n * ```\n */\n async del(did: string): Promise<void> {\n this.sessions.delete(did);\n }\n\n /**\n * Clears all stored sessions.\n *\n * This is primarily useful for testing to ensure a clean state\n * between test runs.\n *\n * @remarks\n * This method is synchronous (not async) for convenience in test cleanup.\n *\n * @example\n * ```typescript\n * // In test teardown\n * afterEach(() => {\n * sessionStore.clear();\n * });\n * ```\n */\n clear(): void {\n this.sessions.clear();\n }\n}\n","import type { StateStore } from \"../core/interfaces.js\";\nimport type { NodeSavedState } from \"@atproto/oauth-client-node\";\n\n/**\n * In-memory implementation of the StateStore interface.\n *\n * This store keeps OAuth state parameters in memory using a Map. State is\n * used during the OAuth authorization flow for CSRF protection and PKCE.\n *\n * @remarks\n * **Warning**: This implementation is **not suitable for production** because:\n * - State is lost when the process restarts (breaking in-progress OAuth flows)\n * - State cannot be shared across multiple server instances\n * - No automatic cleanup of expired state (memory leak potential)\n *\n * For production, implement {@link StateStore} with a persistent backend\n * that supports TTL (time-to-live):\n * - **Redis**: Ideal choice with built-in TTL support\n * - **Database with cleanup job**: PostgreSQL/MySQL with periodic cleanup\n *\n * **State Lifecycle**:\n * 1. Created when user starts OAuth flow (`authorize()`)\n * 2. Retrieved and validated during callback\n * 3. Deleted after successful or failed callback\n * 4. Should expire after ~15 minutes if callback never happens\n *\n * @example Basic usage\n * ```typescript\n * import { InMemoryStateStore } from \"@hypercerts-org/sdk/storage\";\n *\n * const stateStore = new InMemoryStateStore();\n *\n * const sdk = new ATProtoSDK({\n * oauth: { ... },\n * storage: {\n * stateStore, // Will warn in logs for production\n * },\n * });\n * ```\n *\n * @example Testing usage\n * ```typescript\n * const stateStore = new InMemoryStateStore();\n *\n * // After tests, clean up\n * stateStore.clear();\n * ```\n *\n * @see {@link StateStore} for the interface definition\n * @see {@link InMemorySessionStore} for the corresponding session store\n */\nexport class InMemoryStateStore implements StateStore {\n /**\n * Internal storage for OAuth state, keyed by state string.\n * @internal\n */\n private states = new Map<string, NodeSavedState>();\n\n /**\n * Retrieves OAuth state by key.\n *\n * @param key - The state key (random string from authorization URL)\n * @returns Promise resolving to the state, or `undefined` if not found\n *\n * @remarks\n * The key is a cryptographically random string generated during\n * the authorization request. It's included in the callback URL\n * and used to retrieve the associated PKCE verifier and other data.\n *\n * @example\n * ```typescript\n * // During OAuth callback\n * const state = await stateStore.get(params.get(\"state\")!);\n * if (!state) {\n * throw new Error(\"Invalid or expired state\");\n * }\n * ```\n */\n async get(key: string): Promise<NodeSavedState | undefined> {\n return this.states.get(key);\n }\n\n /**\n * Stores OAuth state temporarily.\n *\n * @param key - The state key to use for storage\n * @param state - The OAuth state data (includes PKCE verifier, etc.)\n *\n * @remarks\n * In production implementations, state should be stored with a TTL\n * of approximately 10-15 minutes to prevent stale state accumulation.\n *\n * @example\n * ```typescript\n * // Called internally by OAuthClient during authorize()\n * await stateStore.set(stateKey, {\n * // PKCE code verifier, redirect URI, etc.\n * });\n * ```\n */\n async set(key: string, state: NodeSavedState): Promise<void> {\n this.states.set(key, state);\n }\n\n /**\n * Deletes OAuth state by key.\n *\n * @param key - The state key to delete\n *\n * @remarks\n * Called after the OAuth callback is processed (whether successful or not)\n * to clean up the temporary state.\n *\n * @example\n * ```typescript\n * // After processing callback\n * await stateStore.del(stateKey);\n * ```\n */\n async del(key: string): Promise<void> {\n this.states.delete(key);\n }\n\n /**\n * Clears all stored state.\n *\n * This is primarily useful for testing to ensure a clean state\n * between test runs.\n *\n * @remarks\n * This method is synchronous (not async) for convenience in test cleanup.\n * In production, be careful using this as it will invalidate all\n * in-progress OAuth flows.\n *\n * @example\n * ```typescript\n * // In test teardown\n * afterEach(() => {\n * stateStore.clear();\n * });\n * ```\n */\n clear(): void {\n this.states.clear();\n }\n}\n","/**\n * OAuth Scopes and Granular Permissions\n *\n * This module provides type-safe, Zod-validated OAuth scope and permission management\n * for the ATProto SDK. It supports both legacy transitional scopes and the new\n * granular permissions model.\n *\n * @see https://atproto.com/specs/oauth\n * @see https://atproto.com/specs/permission\n *\n * @module auth/permissions\n */\n\nimport { z } from \"zod\";\n\n/**\n * Base OAuth scope - required for all sessions\n *\n * @constant\n */\nexport const ATPROTO_SCOPE = \"atproto\" as const;\n\n/**\n * Transitional OAuth scopes for legacy compatibility.\n *\n * These scopes provide broad access and are maintained for backwards compatibility.\n * New applications should use granular permissions instead.\n *\n * @deprecated Use granular permissions (account:*, repo:*, etc.) for better control\n * @constant\n */\nexport const TRANSITION_SCOPES = {\n /** Broad PDS permissions including record creation, blob uploads, and preferences */\n GENERIC: \"transition:generic\",\n /** Direct messages access (requires transition:generic) */\n CHAT: \"transition:chat.bsky\",\n /** Email address and confirmation status */\n EMAIL: \"transition:email\",\n} as const;\n\n/**\n * Zod schema for transitional scopes.\n *\n * Validates that a scope string is one of the known transitional scopes.\n *\n * @example\n * ```typescript\n * TransitionScopeSchema.parse('transition:email'); // Valid\n * TransitionScopeSchema.parse('invalid'); // Throws ZodError\n * ```\n */\nexport const TransitionScopeSchema = z\n .enum([\"transition:generic\", \"transition:chat.bsky\", \"transition:email\"])\n .describe(\"Legacy transitional OAuth scopes\");\n\n/**\n * Type for transitional scopes inferred from schema.\n */\nexport type TransitionScope = z.infer<typeof TransitionScopeSchema>;\n\n/**\n * Zod schema for account permission attributes.\n *\n * Account attributes specify what aspect of the account is being accessed.\n */\nexport const AccountAttrSchema = z.enum([\"email\", \"repo\"]);\n\n/**\n * Type for account attributes inferred from schema.\n */\nexport type AccountAttr = z.infer<typeof AccountAttrSchema>;\n\n/**\n * Zod schema for account actions.\n *\n * Account actions specify the level of access (read-only or management).\n */\nexport const AccountActionSchema = z.enum([\"read\", \"manage\"]);\n\n/**\n * Type for account actions inferred from schema.\n */\nexport type AccountAction = z.infer<typeof AccountActionSchema>;\n\n/**\n * Zod schema for repository actions.\n *\n * Repository actions specify what operations can be performed on records.\n */\nexport const RepoActionSchema = z.enum([\"create\", \"update\", \"delete\"]);\n\n/**\n * Type for repository actions inferred from schema.\n */\nexport type RepoAction = z.infer<typeof RepoActionSchema>;\n\n/**\n * Zod schema for identity permission attributes.\n *\n * Identity attributes specify what identity information can be managed.\n */\nexport const IdentityAttrSchema = z.enum([\"handle\", \"*\"]);\n\n/**\n * Type for identity attributes inferred from schema.\n */\nexport type IdentityAttr = z.infer<typeof IdentityAttrSchema>;\n\n/**\n * Zod schema for MIME type patterns.\n *\n * Validates MIME type strings used in blob permissions.\n * Supports standard MIME types and wildcard patterns per ATProto spec.\n *\n * **References:**\n * - ATProto Permission Spec: https://atproto.com/specs/permission (blob resource)\n * - RFC 2045 (MIME): https://www.rfc-editor.org/rfc/rfc2045 (token definition)\n * - IANA Media Types: https://www.iana.org/assignments/media-types/\n *\n * **Implementation:**\n * This is a \"good enough\" validation that allows common real-world MIME types:\n * - Type: letters, digits (e.g., \"3gpp\")\n * - Subtype: letters, digits, hyphens, plus signs, dots, underscores, wildcards\n * - Examples: \"image/png\", \"application/vnd.api+json\", \"video/*\", \"clue_info+xml\"\n *\n * Note: We use a simplified regex rather than full RFC 2045 token validation\n * for practicality. Zod v4 has native MIME support (z.file().mime()) but would\n * require a larger migration effort.\n *\n * @example\n * ```typescript\n * MimeTypeSchema.parse('image/*'); // Valid - wildcard\n * MimeTypeSchema.parse('video/mp4'); // Valid - standard\n * MimeTypeSchema.parse('application/vnd.api+json'); // Valid - with dots/plus\n * MimeTypeSchema.parse('invalid'); // Throws ZodError\n * ```\n */\nexport const MimeTypeSchema = z\n .string()\n .regex(\n /^[a-z0-9]+\\/[a-z0-9*+._-]+$/i,\n 'Invalid MIME type pattern. Expected format: type/subtype (e.g., \"image/*\", \"video/mp4\", \"application/vnd.api+json\")',\n );\n\n/**\n * Zod schema for NSID (Namespaced Identifier).\n *\n * NSIDs are reverse-DNS style identifiers used throughout ATProto\n * (e.g., \"app.bsky.feed.post\" or \"com.example.myrecord\").\n *\n * Official ATProto NSID spec requires:\n * - Each segment must be 1-63 characters\n * - Authority segments (all but last) can contain hyphens, but not at boundaries\n * - Name segment (last) must start with a letter and contain only alphanumerics\n * - Hyphens only allowed in authority segments, not in the name segment\n *\n * @see https://atproto.com/specs/nsid\n *\n * @example\n * ```typescript\n * NsidSchema.parse('app.bsky.feed.post'); // Valid\n * NsidSchema.parse('com.example.myrecord'); // Valid\n * NsidSchema.parse('InvalidNSID'); // Throws ZodError\n * ```\n */\nexport const NsidSchema = z\n .string()\n .regex(\n /^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\\.[a-zA-Z]([a-zA-Z0-9]{0,62})?)$/,\n 'Invalid NSID format. Expected reverse-DNS format (e.g., \"app.bsky.feed.post\")',\n );\n\n/**\n * Zod schema for account permission.\n *\n * Account permissions control access to account-level information like email\n * and repository management.\n *\n * @example Without action (read-only)\n * ```typescript\n * const input = { type: 'account', attr: 'email' };\n * AccountPermissionSchema.parse(input); // Returns: \"account:email\"\n * ```\n *\n * @example With action\n * ```typescript\n * const input = { type: 'account', attr: 'email', action: 'manage' };\n * AccountPermissionSchema.parse(input); // Returns: \"account:email?action=manage\"\n * ```\n */\nexport const AccountPermissionSchema = z\n .object({\n type: z.literal(\"account\"),\n attr: AccountAttrSchema,\n action: AccountActionSchema.optional(),\n })\n .transform(({ attr, action }) => {\n let perm = `account:${attr}`;\n if (action) {\n perm += `?action=${action}`;\n }\n return perm;\n });\n\n/**\n * Input type for account permission (before transform).\n */\nexport type AccountPermissionInput = z.input<typeof AccountPermissionSchema>;\n\n/**\n * Zod schema for repository permission.\n *\n * Repository permissions control write access to records by collection type.\n * The collection must be a valid NSID or wildcard (*).\n *\n * @example Without actions (all actions allowed)\n * ```typescript\n * const input = { type: 'repo', collection: 'app.bsky.feed.post' };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:app.bsky.feed.post\"\n * ```\n *\n * @example With specific actions\n * ```typescript\n * const input = {\n * type: 'repo',\n * collection: 'app.bsky.feed.post',\n * actions: ['create', 'update']\n * };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:app.bsky.feed.post?action=create&action=update\"\n * ```\n *\n * @example With wildcard collection\n * ```typescript\n * const input = { type: 'repo', collection: '*', actions: ['delete'] };\n * RepoPermissionSchema.parse(input); // Returns: \"repo:*?action=delete\"\n * ```\n */\nexport const RepoPermissionSchema = z\n .object({\n type: z.literal(\"repo\"),\n collection: NsidSchema.or(z.literal(\"*\")),\n actions: z.array(RepoActionSchema).optional(),\n })\n .transform(({ collection, actions }) => {\n let perm = `repo:${collection}`;\n if (actions && actions.length > 0) {\n const params = actions.map((a) => `action=${a}`).join(\"&\");\n perm += `?${params}`;\n }\n return perm;\n });\n\n/**\n * Input type for repository permission (before transform).\n */\nexport type RepoPermissionInput = z.input<typeof RepoPermissionSchema>;\n\n/**\n * Zod schema for blob permission.\n *\n * Blob permissions control media file uploads constrained by MIME type patterns.\n *\n * @example Single MIME type\n * ```typescript\n * const input = { type: 'blob', mimeTypes: ['image/*'] };\n * BlobPermissionSchema.parse(input); // Returns: \"blob:image/*\"\n * ```\n *\n * @example Multiple MIME types\n * ```typescript\n * const input = { type: 'blob', mimeTypes: ['image/*', 'video/*'] };\n * BlobPermissionSchema.parse(input); // Returns: \"blob?accept=image/*&accept=video/*\"\n * ```\n */\nexport const BlobPermissionSchema = z\n .object({\n type: z.literal(\"blob\"),\n mimeTypes: z.array(MimeTypeSchema).min(1, \"At least one MIME type required\"),\n })\n .transform(({ mimeTypes }) => {\n if (mimeTypes.length === 1) {\n return `blob:${mimeTypes[0]}`;\n }\n const accepts = mimeTypes.map((t) => `accept=${encodeURIComponent(t)}`).join(\"&\");\n return `blob?${accepts}`;\n });\n\n/**\n * Input type for blob permission (before transform).\n */\nexport type BlobPermissionInput = z.input<typeof BlobPermissionSchema>;\n\n/**\n * Zod schema for RPC permission.\n *\n * RPC permissions control authenticated API calls to remote services.\n * At least one of lexicon or aud must be restricted (both cannot be wildcards).\n *\n * @example Specific lexicon with wildcard audience\n * ```typescript\n * const input = {\n * type: 'rpc',\n * lexicon: 'com.atproto.repo.createRecord',\n * aud: '*'\n * };\n * RpcPermissionSchema.parse(input);\n * // Returns: \"rpc:com.atproto.repo.createRecord?aud=*\"\n * ```\n *\n * @example With specific audience\n * ```typescript\n * const input = {\n * type: 'rpc',\n * lexicon: 'com.atproto.repo.createRecord',\n * aud: 'did:web:api.example.com',\n * inheritAud: true\n * };\n * RpcPermissionSchema.parse(input);\n * // Returns: \"rpc:com.atproto.repo.createRecord?aud=did%3Aweb%3Aapi.example.com&inheritAud=true\"\n * ```\n */\nexport const RpcPermissionSchema = z\n .object({\n type: z.literal(\"rpc\"),\n lexicon: NsidSchema.or(z.literal(\"*\")),\n aud: z.string().min(1, \"Audience is required\"),\n inheritAud: z.boolean().optional(),\n })\n .refine(\n ({ lexicon, aud }) => lexicon !== \"*\" || aud !== \"*\",\n \"At least one of lexicon or aud must be restricted (wildcards cannot both be used)\",\n )\n .transform(({ lexicon, aud, inheritAud }) => {\n let perm = `rpc:${lexicon}?aud=${encodeURIComponent(aud)}`;\n if (inheritAud) {\n perm += \"&inheritAud=true\";\n }\n return perm;\n });\n\n/**\n * Input type for RPC permission (before transform).\n */\nexport type RpcPermissionInput = z.input<typeof RpcPermissionSchema>;\n\n/**\n * Zod schema for identity permission.\n *\n * Identity permissions control access to DID documents and handles.\n *\n * @example Handle management\n * ```typescript\n * const input = { type: 'identity', attr: 'handle' };\n * IdentityPermissionSchema.parse(input); // Returns: \"identity:handle\"\n * ```\n *\n * @example All identity attributes\n * ```typescript\n * const input = { type: 'identity', attr: '*' };\n * IdentityPermissionSchema.parse(input); // Returns: \"identity:*\"\n * ```\n */\nexport const IdentityPermissionSchema = z\n .object({\n type: z.literal(\"identity\"),\n attr: IdentityAttrSchema,\n })\n .transform(({ attr }) => `identity:${attr}`);\n\n/**\n * Input type for identity permission (before transform).\n */\nexport type IdentityPermissionInput = z.input<typeof IdentityPermissionSchema>;\n\n/**\n * Zod schema for permission set inclusion.\n *\n * Include permissions reference permission sets bundled under a single NSID.\n *\n * @example Without audience\n * ```typescript\n * const input = { type: 'include', nsid: 'com.example.authBasicFeatures' };\n * IncludePermissionSchema.parse(input);\n * // Returns: \"include:com.example.authBasicFeatures\"\n * ```\n *\n * @example With audience\n * ```typescript\n * const input = {\n * type: 'include',\n * nsid: 'com.example.authBasicFeatures',\n * aud: 'did:web:api.example.com'\n * };\n * IncludePermissionSchema.parse(input);\n * // Returns: \"include:com.example.authBasicFeatures?aud=did%3Aweb%3Aapi.example.com\"\n * ```\n */\nexport const IncludePermissionSchema = z\n .object({\n type: z.literal(\"include\"),\n nsid: NsidSchema,\n aud: z.string().optional(),\n })\n .transform(({ nsid, aud }) => {\n let perm = `include:${nsid}`;\n if (aud) {\n perm += `?aud=${encodeURIComponent(aud)}`;\n }\n return perm;\n });\n\n/**\n * Input type for include permission (before transform).\n */\nexport type IncludePermissionInput = z.input<typeof IncludePermissionSchema>;\n\n/**\n * Union schema for all permission types.\n *\n * This schema accepts any of the supported permission types and validates\n * them according to their specific rules.\n */\nexport const PermissionSchema = z.union([\n AccountPermissionSchema,\n RepoPermissionSchema,\n BlobPermissionSchema,\n RpcPermissionSchema,\n IdentityPermissionSchema,\n IncludePermissionSchema,\n]);\n\n/**\n * Input type for any permission (before transform).\n */\nexport type PermissionInput = z.input<typeof PermissionSchema>;\n\n/**\n * Output type for any permission (after transform).\n */\nexport type Permission = z.output<typeof PermissionSchema>;\n\n/**\n * Fluent builder for constructing OAuth permission arrays.\n *\n * This class provides a convenient, type-safe way to build arrays of permissions\n * using method chaining.\n *\n * @example Basic usage\n * ```typescript\n * const builder = new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .blob(['image/*', 'video/*']);\n *\n * const permissions = builder.build();\n * // Returns: ['account:email?action=read', 'repo:app.bsky.feed.post?action=create&action=update', 'blob:image/*,video/*']\n * ```\n *\n * @example With transitional scopes\n * ```typescript\n * const builder = new PermissionBuilder()\n * .transition('email')\n * .transition('generic');\n *\n * const scopes = builder.build();\n * // Returns: ['transition:email', 'transition:generic']\n * ```\n */\nexport class PermissionBuilder {\n private permissions: string[] = [];\n\n /**\n * Add a transitional scope.\n *\n * @param scope - The transitional scope name ('email', 'generic', or 'chat.bsky')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.transition('email').transition('generic');\n * ```\n */\n transition(scope: \"email\" | \"generic\" | \"chat.bsky\"): this {\n const fullScope = `transition:${scope}`;\n const validated = TransitionScopeSchema.parse(fullScope);\n this.permissions.push(validated);\n return this;\n }\n\n /**\n * Add an account permission.\n *\n * @param attr - The account attribute ('email' or 'repo')\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountEmail('read').accountRepo('manage');\n * ```\n */\n account(attr: z.infer<typeof AccountAttrSchema>, action?: z.infer<typeof AccountActionSchema>): this {\n const permission = AccountPermissionSchema.parse({\n type: \"account\",\n attr,\n action,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Convenience method for account:email permission.\n *\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountEmail('read');\n * ```\n */\n accountEmail(action?: z.infer<typeof AccountActionSchema>): this {\n return this.account(\"email\", action);\n }\n\n /**\n * Convenience method for account:repo permission.\n *\n * @param action - Optional action ('read' or 'manage')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.accountRepo('manage');\n * ```\n */\n accountRepo(action?: z.infer<typeof AccountActionSchema>): this {\n return this.account(\"repo\", action);\n }\n\n /**\n * Add a repository permission.\n *\n * @param collection - The NSID of the collection or '*' for all\n * @param actions - Optional array of actions ('create', 'update', 'delete')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repo('app.bsky.feed.post', ['create', 'update']);\n * ```\n */\n repo(collection: string, actions?: z.infer<typeof RepoActionSchema>[]): this {\n const permission = RepoPermissionSchema.parse({\n type: \"repo\",\n collection,\n actions,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Convenience method for repository write permissions (create + update).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoWrite('app.bsky.feed.post');\n * ```\n */\n repoWrite(collection: string): this {\n return this.repo(collection, [\"create\", \"update\"]);\n }\n\n /**\n * Convenience method for repository read permission (no actions).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoRead('app.bsky.feed.post');\n * ```\n */\n repoRead(collection: string): this {\n return this.repo(collection, []);\n }\n\n /**\n * Convenience method for full repository permissions (create + update + delete).\n *\n * @param collection - The NSID of the collection or '*' for all\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.repoFull('app.bsky.feed.post');\n * ```\n */\n repoFull(collection: string): this {\n return this.repo(collection, [\"create\", \"update\", \"delete\"]);\n }\n\n /**\n * Add a blob permission.\n *\n * @param mimeTypes - Array of MIME types or a single MIME type\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.blob(['image/*', 'video/*']);\n * builder.blob('image/*');\n * ```\n */\n blob(mimeTypes: string | string[]): this {\n const types = Array.isArray(mimeTypes) ? mimeTypes : [mimeTypes];\n const permission = BlobPermissionSchema.parse({\n type: \"blob\",\n mimeTypes: types,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an RPC permission.\n *\n * @param lexicon - The NSID of the lexicon or '*' for all\n * @param aud - The audience (DID or URL)\n * @param inheritAud - Whether to inherit audience\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.rpc('com.atproto.repo.createRecord', 'did:web:api.example.com');\n * ```\n */\n rpc(lexicon: string, aud: string, inheritAud?: boolean): this {\n const permission = RpcPermissionSchema.parse({\n type: \"rpc\",\n lexicon,\n aud,\n inheritAud,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an identity permission.\n *\n * @param attr - The identity attribute ('handle' or '*')\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.identity('handle');\n * ```\n */\n identity(attr: z.infer<typeof IdentityAttrSchema>): this {\n const permission = IdentityPermissionSchema.parse({\n type: \"identity\",\n attr,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add an include permission.\n *\n * @param nsid - The NSID of the scope set to include\n * @param aud - Optional audience restriction\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.include('com.example.authBasicFeatures');\n * ```\n */\n include(nsid: string, aud?: string): this {\n const permission = IncludePermissionSchema.parse({\n type: \"include\",\n nsid,\n aud,\n });\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add a custom permission string directly (bypasses validation).\n *\n * Use this for testing or special cases where you need to add\n * a permission that doesn't fit the standard types.\n *\n * @param permission - The permission string\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.custom('atproto');\n * ```\n */\n custom(permission: string): this {\n this.permissions.push(permission);\n return this;\n }\n\n /**\n * Add the base atproto scope.\n *\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.atproto();\n * ```\n */\n atproto(): this {\n this.permissions.push(ATPROTO_SCOPE);\n return this;\n }\n\n /**\n * Build and return the array of permission strings.\n *\n * @returns Array of permission strings\n *\n * @example\n * ```typescript\n * const permissions = builder.build();\n * ```\n */\n build(): string[] {\n return [...this.permissions];\n }\n\n /**\n * Clear all permissions from the builder.\n *\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * builder.clear().accountEmail('read');\n * ```\n */\n clear(): this {\n this.permissions = [];\n return this;\n }\n\n /**\n * Get the current number of permissions.\n *\n * @returns The number of permissions\n *\n * @example\n * ```typescript\n * const count = builder.count();\n * ```\n */\n count(): number {\n return this.permissions.length;\n }\n}\n\n/**\n * Build a scope string from an array of permissions.\n *\n * This is a convenience function that joins permission strings with spaces,\n * which is the standard format for OAuth scope parameters.\n *\n * @param permissions - Array of permission strings\n * @returns Space-separated scope string\n *\n * @example\n * ```typescript\n * const permissions = ['account:email?action=read', 'repo:app.bsky.feed.post'];\n * const scope = buildScope(permissions);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post\"\n * ```\n */\nexport function buildScope(permissions: string[]): string {\n return permissions.join(\" \");\n}\n\n/**\n * Pre-built scope presets for common use cases.\n *\n * These presets provide ready-to-use permission sets for typical application scenarios.\n */\nexport const ScopePresets = {\n /**\n * Email access scope - allows reading user's email address.\n *\n * Includes:\n * - account:email?action=read\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.EMAIL_READ;\n * // Use in OAuth flow to request email access\n * ```\n */\n EMAIL_READ: buildScope(new PermissionBuilder().accountEmail(\"read\").build()),\n\n /**\n * Profile read scope - allows reading user's profile.\n *\n * Includes:\n * - repo:app.bsky.actor.profile (read-only)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.PROFILE_READ;\n * ```\n */\n PROFILE_READ: buildScope(new PermissionBuilder().repoRead(\"app.bsky.actor.profile\").build()),\n\n /**\n * Profile write scope - allows updating user's profile.\n *\n * Includes:\n * - repo:app.bsky.actor.profile (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.PROFILE_WRITE;\n * ```\n */\n PROFILE_WRITE: buildScope(new PermissionBuilder().repoWrite(\"app.bsky.actor.profile\").build()),\n\n /**\n * Post creation scope - allows creating and updating posts.\n *\n * Includes:\n * - repo:app.bsky.feed.post (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.POST_WRITE;\n * ```\n */\n POST_WRITE: buildScope(new PermissionBuilder().repoWrite(\"app.bsky.feed.post\").build()),\n\n /**\n * Social interactions scope - allows liking, reposting, and following.\n *\n * Includes:\n * - repo:app.bsky.feed.like (create + update)\n * - repo:app.bsky.feed.repost (create + update)\n * - repo:app.bsky.graph.follow (create + update)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.SOCIAL_WRITE;\n * ```\n */\n SOCIAL_WRITE: buildScope(\n new PermissionBuilder()\n .repoWrite(\"app.bsky.feed.like\")\n .repoWrite(\"app.bsky.feed.repost\")\n .repoWrite(\"app.bsky.graph.follow\")\n .build(),\n ),\n\n /**\n * Media upload scope - allows uploading images and videos.\n *\n * Includes:\n * - blob permissions for image/* and video/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.MEDIA_UPLOAD;\n * ```\n */\n MEDIA_UPLOAD: buildScope(new PermissionBuilder().blob([\"image/*\", \"video/*\"]).build()),\n\n /**\n * Image upload only scope - allows uploading images.\n *\n * Includes:\n * - blob:image/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.IMAGE_UPLOAD;\n * ```\n */\n IMAGE_UPLOAD: buildScope(new PermissionBuilder().blob(\"image/*\").build()),\n\n /**\n * Posting app scope - full posting capabilities including media.\n *\n * Includes:\n * - repo:app.bsky.feed.post (create + update)\n * - repo:app.bsky.feed.like (create + update)\n * - repo:app.bsky.feed.repost (create + update)\n * - blob permissions for image/* and video/*\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.POSTING_APP;\n * ```\n */\n POSTING_APP: buildScope(\n new PermissionBuilder()\n .repoWrite(\"app.bsky.feed.post\")\n .repoWrite(\"app.bsky.feed.like\")\n .repoWrite(\"app.bsky.feed.repost\")\n .blob([\"image/*\", \"video/*\"])\n .build(),\n ),\n\n /**\n * Read-only app scope - allows reading all repository data.\n *\n * Includes:\n * - repo:* (read-only, no actions)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.READ_ONLY;\n * ```\n */\n READ_ONLY: buildScope(new PermissionBuilder().repoRead(\"*\").build()),\n\n /**\n * Full access scope - allows all repository operations.\n *\n * Includes:\n * - repo:* (create + update + delete)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.FULL_ACCESS;\n * ```\n */\n FULL_ACCESS: buildScope(new PermissionBuilder().repoFull(\"*\").build()),\n\n /**\n * Email + Profile scope - common combination for user identification.\n *\n * Includes:\n * - account:email?action=read\n * - repo:app.bsky.actor.profile (read-only)\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.EMAIL_AND_PROFILE;\n * ```\n */\n EMAIL_AND_PROFILE: buildScope(\n new PermissionBuilder().accountEmail(\"read\").repoRead(\"app.bsky.actor.profile\").build(),\n ),\n\n /**\n * Transitional email scope (legacy).\n *\n * Uses the transitional scope format for backward compatibility.\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.TRANSITION_EMAIL;\n * ```\n */\n TRANSITION_EMAIL: buildScope(new PermissionBuilder().transition(\"email\").build()),\n\n /**\n * Transitional generic scope (legacy).\n *\n * Uses the transitional scope format for backward compatibility.\n *\n * @example\n * ```typescript\n * const scope = ScopePresets.TRANSITION_GENERIC;\n * ```\n */\n TRANSITION_GENERIC: buildScope(new PermissionBuilder().transition(\"generic\").build()),\n} as const;\n\n/**\n * Parse a scope string into an array of individual permissions.\n *\n * This splits a space-separated scope string into individual permission strings.\n *\n * @param scope - Space-separated scope string\n * @returns Array of permission strings\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post\";\n * const permissions = parseScope(scope);\n * // Returns: ['account:email?action=read', 'repo:app.bsky.feed.post']\n * ```\n */\nexport function parseScope(scope: string): string[] {\n return scope.trim().split(/\\s+/).filter(Boolean);\n}\n\n/**\n * Helper function to match MIME type patterns with wildcard support.\n *\n * Implements MIME type matching for blob permissions per ATProto spec.\n *\n * **Reference:**\n * - ATProto Permission Spec: https://atproto.com/specs/permission\n * Supports \"MIME types or partial MIME type glob patterns\"\n *\n * **Supported patterns:**\n * - Exact matches: \"image/png\" matches \"image/png\"\n * - Type wildcards: \"image/*\" matches \"image/png\", \"image/jpeg\", etc.\n * - Full wildcards: `*` `/` `*` matches any MIME type\n *\n * @param pattern - The MIME type pattern (may contain wildcards)\n * @param mimeType - The actual MIME type to check\n * @returns True if the MIME type matches the pattern\n *\n * @example\n * ```typescript\n * matchMimePattern(\"image/*\", \"image/png\"); // true\n * matchMimePattern(\"*\" + \"/\" + \"*\", \"video/mp4\"); // true - matches any MIME\n * matchMimePattern(\"image/*\", \"video/mp4\"); // false\n * ```\n */\nfunction matchMimePattern(pattern: string, mimeType: string): boolean {\n if (pattern === \"*/*\") return true;\n if (pattern === mimeType) return true;\n\n const [patternType, patternSubtype] = pattern.split(\"/\");\n const [mimeTypeType] = mimeType.split(\"/\");\n\n if (patternSubtype === \"*\" && patternType === mimeTypeType) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if a scope string contains a specific permission.\n *\n * Implements permission matching per ATProto OAuth spec with support for\n * exact matching and limited wildcard patterns.\n *\n * **References:**\n * - ATProto Permission Spec: https://atproto.com/specs/permission\n * - ATProto OAuth Spec: https://atproto.com/specs/oauth\n *\n * **Supported wildcards (per spec):**\n * - `repo:*` - Matches any repository collection (e.g., `repo:app.bsky.feed.post`)\n * - `rpc:*` - Matches any RPC lexicon (but aud cannot also be wildcard)\n * - `blob:image/*` - MIME type wildcards (e.g., matches `blob:image/png`, `blob:image/jpeg`)\n * - `blob:` + wildcard MIME - Matches any MIME type (using `*` + `/` + `*` pattern)\n * - `identity:*` - Full control of DID document and handle (spec allows `*` as attr value)\n *\n * **NOT supported (per spec):**\n * - `account:*` - Account attr does not support wildcards (only `email` and `repo` allowed)\n * - `include:*` - Include NSID does not support wildcards\n * - Partial wildcards like `com.example.*` are not supported\n *\n * @param scope - Space-separated scope string\n * @param permission - The permission to check for\n * @returns True if the scope contains the permission\n *\n * @example Exact matching\n * ```typescript\n * const scope = \"account:email repo:app.bsky.feed.post\";\n * hasPermission(scope, \"account:email\"); // true\n * hasPermission(scope, \"account:repo\"); // false\n * ```\n *\n * @example Wildcard matching\n * ```typescript\n * const scope = \"repo:* blob:image/* identity:*\";\n * hasPermission(scope, \"repo:app.bsky.feed.post\"); // true\n * hasPermission(scope, \"blob:image/png\"); // true\n * hasPermission(scope, \"blob:video/mp4\"); // false\n * hasPermission(scope, \"identity:handle\"); // true\n * ```\n */\nexport function hasPermission(scope: string, permission: string): boolean {\n const permissions = parseScope(scope);\n\n // 1. Check exact match first\n if (permissions.includes(permission)) {\n return true;\n }\n\n // 2. Check wildcard matches (only those supported by ATProto spec)\n for (const scopePermission of permissions) {\n // repo:* - Wildcard for repository collections\n // Spec: \"Wildcard (*) is allowed in scope string syntax\"\n if (scopePermission.startsWith(\"repo:*\") && permission.startsWith(\"repo:\")) {\n return true;\n }\n\n // rpc:* - Wildcard for RPC lexicons\n // Spec: \"Wildcard (*) is allowed in scope string syntax for lxm parameter\"\n if (scopePermission.startsWith(\"rpc:*\") && permission.startsWith(\"rpc:\")) {\n return true;\n }\n\n // blob MIME wildcards - image/*, video/*, or full wildcard\n // Spec: \"MIME types or partial MIME type glob patterns\"\n if (scopePermission.startsWith(\"blob:\") && permission.startsWith(\"blob:\")) {\n const scopeMime = scopePermission.substring(5).split(\"?\")[0]; // Remove \"blob:\" prefix and query params\n const permMime = permission.substring(5).split(\"?\")[0];\n\n if (matchMimePattern(scopeMime, permMime)) {\n return true;\n }\n }\n\n // identity:* - Full control of DID document and handle\n // Spec: \"* - Full control of DID document and handle\" (as attr value)\n if (scopePermission === \"identity:*\" && permission.startsWith(\"identity:\")) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a scope string contains all of the specified permissions.\n *\n * @param scope - Space-separated scope string\n * @param requiredPermissions - Array of permissions to check for\n * @returns True if the scope contains all required permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post blob:image/*\";\n * hasAllPermissions(scope, [\"account:email?action=read\", \"blob:image/*\"]); // true\n * hasAllPermissions(scope, [\"account:email?action=read\", \"account:repo\"]); // false\n * ```\n */\nexport function hasAllPermissions(scope: string, requiredPermissions: string[]): boolean {\n const permissions = parseScope(scope);\n return requiredPermissions.every((required) => permissions.includes(required));\n}\n\n/**\n * Check if a scope string contains any of the specified permissions.\n *\n * @param scope - Space-separated scope string\n * @param checkPermissions - Array of permissions to check for\n * @returns True if the scope contains at least one of the permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post\";\n * hasAnyPermission(scope, [\"account:email?action=read\", \"account:repo\"]); // true\n * hasAnyPermission(scope, [\"account:repo\", \"identity:handle\"]); // false\n * ```\n */\nexport function hasAnyPermission(scope: string, checkPermissions: string[]): boolean {\n const permissions = parseScope(scope);\n return checkPermissions.some((check) => permissions.includes(check));\n}\n\n/**\n * Merge multiple scope strings into a single scope string with deduplicated permissions.\n *\n * @param scopes - Array of scope strings to merge\n * @returns Merged scope string with unique permissions\n *\n * @example\n * ```typescript\n * const scope1 = \"account:email?action=read repo:app.bsky.feed.post\";\n * const scope2 = \"repo:app.bsky.feed.post blob:image/*\";\n * const merged = mergeScopes([scope1, scope2]);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post blob:image/*\"\n * ```\n */\nexport function mergeScopes(scopes: string[]): string {\n const allPermissions = scopes.flatMap(parseScope);\n const uniquePermissions = [...new Set(allPermissions)];\n return buildScope(uniquePermissions);\n}\n\n/**\n * Remove specific permissions from a scope string.\n *\n * @param scope - Space-separated scope string\n * @param permissionsToRemove - Array of permissions to remove\n * @returns New scope string without the specified permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read repo:app.bsky.feed.post blob:image/*\";\n * const filtered = removePermissions(scope, [\"blob:image/*\"]);\n * // Returns: \"account:email?action=read repo:app.bsky.feed.post\"\n * ```\n */\nexport function removePermissions(scope: string, permissionsToRemove: string[]): string {\n const permissions = parseScope(scope);\n const filtered = permissions.filter((p) => !permissionsToRemove.includes(p));\n return buildScope(filtered);\n}\n\n/**\n * Validate that all permissions in a scope string are well-formed.\n *\n * This checks that each permission matches expected patterns for transitional\n * or granular permissions. It does NOT validate against the full Zod schemas.\n *\n * @param scope - Space-separated scope string\n * @returns Object with isValid flag and array of invalid permissions\n *\n * @example\n * ```typescript\n * const scope = \"account:email?action=read invalid:permission\";\n * const result = validateScope(scope);\n * // Returns: { isValid: false, invalidPermissions: ['invalid:permission'] }\n * ```\n */\nexport function validateScope(scope: string): {\n isValid: boolean;\n invalidPermissions: string[];\n} {\n const permissions = parseScope(scope);\n const invalidPermissions: string[] = [];\n\n // Pattern for valid permission prefixes\n const validPrefixes = /^(atproto|transition:|account:|repo:|blob:?|rpc:|identity:|include:)/;\n\n for (const permission of permissions) {\n if (!validPrefixes.test(permission)) {\n invalidPermissions.push(permission);\n }\n }\n\n return {\n isValid: invalidPermissions.length === 0,\n invalidPermissions,\n };\n}\n","import { NodeOAuthClient, JoseKey, type NodeSavedSession } from \"@atproto/oauth-client-node\";\nimport type { SessionStore, StateStore, LoggerInterface } from \"../core/interfaces.js\";\nimport type { ATProtoSDKConfig } from \"../core/config.js\";\nimport { isLoopbackUrl } from \"../lib/url-utils.js\";\nimport { AuthenticationError, NetworkError } from \"../core/errors.js\";\nimport { InMemorySessionStore } from \"../storage/InMemorySessionStore.js\";\nimport { InMemoryStateStore } from \"../storage/InMemoryStateStore.js\";\nimport { parseScope, validateScope, ATPROTO_SCOPE } from \"./permissions.js\";\n\n/**\n * Options for the OAuth authorization flow.\n *\n * @internal\n */\ninterface AuthorizeOptions {\n /**\n * OAuth scope string to request specific permissions.\n * Overrides the default scope from the SDK configuration.\n */\n scope?: string;\n}\n\n/**\n * OAuth 2.0 client for AT Protocol authentication with DPoP support.\n *\n * This class wraps the `@atproto/oauth-client-node` library to provide\n * OAuth 2.0 authentication with the following features:\n *\n * - **DPoP (Demonstrating Proof of Possession)**: Binds tokens to cryptographic keys\n * to prevent token theft and replay attacks\n * - **PKCE (Proof Key for Code Exchange)**: Protects against authorization code interception\n * - **Automatic Token Refresh**: Transparently refreshes expired access tokens\n * - **Session Persistence**: Stores sessions in configurable storage backends\n *\n * @remarks\n * This class is typically used internally by {@link ATProtoSDK}. Direct usage\n * is only needed for advanced scenarios.\n *\n * The client uses lazy initialization - the underlying `NodeOAuthClient` is\n * created asynchronously on first use. This allows the constructor to return\n * synchronously while deferring async key parsing.\n *\n * @example Direct usage (advanced)\n * ```typescript\n * import { OAuthClient } from \"@hypercerts-org/sdk\";\n *\n * const client = new OAuthClient({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: { pds: \"https://bsky.social\" },\n * });\n *\n * // Start authorization\n * const authUrl = await client.authorize(\"user.bsky.social\");\n *\n * // Handle callback\n * const session = await client.callback(new URLSearchParams(callbackUrl.search));\n * ```\n *\n * @see {@link ATProtoSDK} for the recommended high-level API\n * @see https://atproto.com/specs/oauth for AT Protocol OAuth specification\n */\nexport class OAuthClient {\n /** The underlying NodeOAuthClient instance (lazily initialized) */\n private client: NodeOAuthClient | null = null;\n\n /** Promise that resolves to the initialized client */\n private clientPromise: Promise<NodeOAuthClient>;\n\n /** SDK configuration */\n private config: ATProtoSDKConfig;\n\n /** Optional logger for debugging */\n private logger?: LoggerInterface;\n\n /**\n * Creates a new OAuth client.\n *\n * @param config - SDK configuration including OAuth credentials and server URLs\n * @throws {@link AuthenticationError} if the JWK private key is not valid JSON\n *\n * @remarks\n * The constructor validates the JWK format synchronously but defers\n * the actual client initialization to the first API call.\n */\n constructor(config: ATProtoSDKConfig) {\n this.config = config;\n this.logger = config.logger;\n\n // Validate JWK format synchronously (before async initialization)\n try {\n JSON.parse(config.oauth.jwkPrivate);\n } catch (error) {\n throw new AuthenticationError(\"Failed to parse JWK private key. Ensure it is valid JSON.\", error);\n }\n\n // Initialize client lazily (async initialization)\n this.clientPromise = this.initializeClient();\n }\n\n /**\n * Initializes the NodeOAuthClient asynchronously.\n *\n * This method is called lazily on first use. It:\n * 1. Parses the JWK private key(s)\n * 2. Builds OAuth client metadata\n * 3. Creates the underlying NodeOAuthClient\n *\n * @returns Promise resolving to the initialized client\n * @internal\n */\n private async initializeClient(): Promise<NodeOAuthClient> {\n if (this.client) {\n return this.client;\n }\n\n // Parse JWK private key (already validated in constructor)\n const privateJWK = JSON.parse(this.config.oauth.jwkPrivate) as {\n keys: Array<{ kid: string; [key: string]: unknown }>;\n };\n\n // Build client metadata\n const clientMetadata = this.buildClientMetadata();\n\n // Convert JWK keys to JoseKey instances (await here)\n const keyset = await Promise.all(\n privateJWK.keys.map((key) =>\n JoseKey.fromImportable(key as unknown as Parameters<typeof JoseKey.fromImportable>[0], key.kid),\n ),\n );\n\n // Create fetch with timeout\n const fetchWithTimeout = this.createFetchWithTimeout(this.config.timeouts?.pdsMetadata ?? 30000);\n\n // Use provided stores or fall back to in-memory implementations\n const stateStore = this.config.storage?.stateStore ?? new InMemoryStateStore();\n const sessionStore = this.config.storage?.sessionStore ?? new InMemorySessionStore();\n\n this.client = new NodeOAuthClient({\n clientMetadata,\n keyset,\n stateStore: this.createStateStoreAdapter(stateStore),\n sessionStore: this.createSessionStoreAdapter(sessionStore),\n handleResolver: this.config.servers?.pds,\n fetch: this.config.fetch ?? fetchWithTimeout,\n });\n\n return this.client;\n }\n\n /**\n * Gets the OAuth client instance, initializing if needed.\n *\n * @returns Promise resolving to the initialized client\n * @internal\n */\n private async getClient(): Promise<NodeOAuthClient> {\n return this.clientPromise;\n }\n\n /**\n * Detects if a URL is a loopback address (localhost or 127.0.0.1 or [::1]).\n *\n * @param urlString - The URL to check\n * @returns True if the URL is an HTTP loopback address\n * @internal\n */\n private isLoopbackUrl(urlString: string): boolean {\n try {\n const url = new URL(urlString);\n if (url.protocol !== \"http:\") {\n return false;\n }\n const hostname = url.hostname.toLowerCase();\n return hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n } catch {\n return false;\n }\n }\n\n /**\n * Builds OAuth client metadata from configuration.\n *\n * The metadata describes your application to the authorization server\n * and must match what's published at your `clientId` URL.\n *\n * @returns OAuth client metadata object\n * @internal\n *\n * @remarks\n * Key metadata fields:\n * - `client_id`: URL to your client metadata JSON\n * - `redirect_uris`: Where to redirect after auth (must match config)\n * - `dpop_bound_access_tokens`: Always true for AT Protocol\n * - `token_endpoint_auth_method`: Uses private_key_jwt for security\n */\n private buildClientMetadata() {\n const clientIdUrl = new URL(this.config.oauth.clientId);\n\n // Detect and warn about loopback configuration\n const isDevelopment = isLoopbackUrl(this.config.oauth.clientId) || isLoopbackUrl(this.config.oauth.redirectUri);\n\n if (isDevelopment && !this.config.oauth.developmentMode) {\n this.logger?.warn(\"Using HTTP loopback URLs without explicit developmentMode flag\", {\n clientId: this.config.oauth.clientId,\n redirectUri: this.config.oauth.redirectUri,\n note: \"This is suitable for local development only. For production, use HTTPS URLs.\",\n recommendation: \"Set oauth.developmentMode: true to suppress this warning.\",\n });\n }\n\n if (isDevelopment) {\n this.logger?.info(\"Running in development mode with loopback URLs\", {\n clientId: this.config.oauth.clientId,\n redirectUri: this.config.oauth.redirectUri,\n note: \"Authorization server must support loopback clients (optional per AT Protocol spec)\",\n });\n }\n\n const metadata = {\n client_id: this.config.oauth.clientId,\n client_name: \"ATProto SDK Client\",\n client_uri: clientIdUrl.origin,\n redirect_uris: [this.config.oauth.redirectUri] as [string, ...string[]],\n scope: this.config.oauth.scope,\n grant_types: [\"authorization_code\", \"refresh_token\"] as [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"] as [\"code\"],\n application_type: \"web\" as const,\n token_endpoint_auth_method: \"private_key_jwt\" as const,\n token_endpoint_auth_signing_alg: \"ES256\",\n dpop_bound_access_tokens: true,\n jwks_uri: this.config.oauth.jwksUri,\n } as const;\n\n // Validate scope before returning metadata\n this.validateClientMetadataScope(metadata.scope);\n\n return metadata;\n }\n\n /**\n * Validates the OAuth scope in client metadata and logs warnings/suggestions.\n *\n * This method:\n * 1. Checks if the scope is well-formed using permission utilities\n * 2. Detects mixing of transitional and granular permissions\n * 3. Logs warnings for missing `atproto` scope\n * 4. Suggests migration to granular permissions for transitional scopes\n *\n * @param scope - The OAuth scope string to validate\n * @internal\n */\n private validateClientMetadataScope(scope: string): void {\n // Parse the scope into individual permissions\n const permissions = parseScope(scope);\n\n // Validate well-formedness\n const validation = validateScope(scope);\n if (!validation.isValid) {\n this.logger?.error(\"Invalid OAuth scope detected\", {\n invalidPermissions: validation.invalidPermissions,\n scope,\n });\n }\n\n // Check for atproto scope\n const hasAtproto = permissions.includes(ATPROTO_SCOPE);\n if (!hasAtproto) {\n this.logger?.warn(\"OAuth scope missing 'atproto' - basic API access may be limited\", {\n scope,\n suggestion: \"Add 'atproto' to your scope for basic API access\",\n });\n }\n\n // Detect transitional scopes\n const transitionalScopes = permissions.filter((p) => p.startsWith(\"transition:\"));\n const granularScopes = permissions.filter(\n (p) =>\n p.startsWith(\"account:\") ||\n p.startsWith(\"repo:\") ||\n p.startsWith(\"blob\") ||\n p.startsWith(\"rpc:\") ||\n p.startsWith(\"identity:\") ||\n p.startsWith(\"include:\"),\n );\n\n // Log info about transitional scopes\n if (transitionalScopes.length > 0) {\n this.logger?.info(\"Using transitional OAuth scopes (legacy)\", {\n transitionalScopes,\n note: \"Transitional scopes are supported but granular permissions are recommended\",\n });\n\n // Suggest migration to granular permissions\n if (transitionalScopes.includes(\"transition:email\")) {\n this.logger?.info(\"Consider migrating 'transition:email' to granular permissions\", {\n suggestion: \"Use: account:email?action=read\",\n example: \"import { ScopePresets } from '@hypercerts-org/sdk-core'; scope: ScopePresets.EMAIL_READ\",\n });\n }\n if (transitionalScopes.includes(\"transition:generic\")) {\n this.logger?.info(\"Consider migrating 'transition:generic' to granular permissions\", {\n suggestion: \"Use specific permissions like: repo:* account:repo?action=read\",\n example: \"import { ScopePresets } from '@hypercerts-org/sdk-core'; scope: ScopePresets.FULL_ACCESS\",\n });\n }\n }\n\n // Warn if mixing transitional and granular\n if (transitionalScopes.length > 0 && granularScopes.length > 0) {\n this.logger?.warn(\"Mixing transitional and granular OAuth scopes\", {\n transitionalScopes,\n granularScopes,\n note: \"While supported, it's recommended to use either transitional or granular permissions consistently\",\n });\n }\n }\n\n /**\n * Creates a fetch handler with timeout support.\n *\n * @param timeoutMs - Request timeout in milliseconds\n * @returns A fetch function that aborts after the timeout\n * @internal\n */\n private createFetchWithTimeout(timeoutMs: number): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(input, {\n ...init,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(`Request timeout after ${timeoutMs}ms`, error);\n }\n throw new NetworkError(\"Network request failed\", error);\n }\n };\n }\n\n /**\n * Creates a state store adapter compatible with NodeOAuthClient.\n *\n * @param store - The StateStore implementation to adapt\n * @returns An adapter compatible with NodeOAuthClient\n * @internal\n */\n private createStateStoreAdapter(store: StateStore): import(\"@atproto/oauth-client-node\").NodeSavedStateStore {\n return {\n get: (key: string) => store.get(key),\n set: (key: string, value: import(\"@atproto/oauth-client-node\").NodeSavedState) => store.set(key, value),\n del: (key: string) => store.del(key),\n };\n }\n\n /**\n * Creates a session store adapter compatible with NodeOAuthClient.\n *\n * @param store - The SessionStore implementation to adapt\n * @returns An adapter compatible with NodeOAuthClient\n * @internal\n */\n private createSessionStoreAdapter(store: SessionStore): import(\"@atproto/oauth-client-node\").NodeSavedSessionStore {\n return {\n get: (did: string) => store.get(did),\n set: (did: string, session: NodeSavedSession) => store.set(did, session),\n del: (did: string) => store.del(did),\n };\n }\n\n /**\n * Initiates the OAuth authorization flow.\n *\n * This method resolves the user's identity from their identifier,\n * generates PKCE codes, creates OAuth state, and returns an\n * authorization URL to redirect the user to.\n *\n * @param identifier - The user's ATProto identifier. Accepts:\n * - Handle (e.g., `\"alice.bsky.social\"`)\n * - DID (e.g., `\"did:plc:abc123...\"`)\n * - PDS URL (e.g., `\"https://bsky.social\"`)\n * @param options - Optional authorization settings\n * @returns A Promise resolving to the authorization URL\n * @throws {@link AuthenticationError} if authorization setup fails\n * @throws {@link NetworkError} if identity resolution fails\n *\n * @example\n * ```typescript\n * // Get authorization URL\n * const authUrl = await client.authorize(\"user.bsky.social\");\n *\n * // Redirect user (in a web app)\n * window.location.href = authUrl;\n *\n * // Or return to client (in an API)\n * res.json({ authUrl });\n * ```\n */\n async authorize(identifier: string, options?: AuthorizeOptions): Promise<string> {\n try {\n this.logger?.debug(\"Initiating OAuth authorization\", { identifier });\n\n const client = await this.getClient();\n const scope = options?.scope ?? this.config.oauth.scope;\n const authUrl = await client.authorize(identifier, { scope });\n\n this.logger?.debug(\"Authorization URL generated\", { identifier });\n // Convert URL to string if needed\n return typeof authUrl === \"string\" ? authUrl : authUrl.toString();\n } catch (error) {\n this.logger?.error(\"Authorization failed\", { identifier, error });\n if (error instanceof NetworkError || error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Failed to initiate authorization: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Handles the OAuth callback and exchanges the authorization code for tokens.\n *\n * Call this method when the user is redirected back to your application.\n * It validates the state, exchanges the code for tokens, and creates\n * a persistent session.\n *\n * @param params - URL search parameters from the callback. Expected parameters:\n * - `code`: The authorization code\n * - `state`: The state parameter (for CSRF protection)\n * - `iss`: The issuer (authorization server URL)\n * @returns A Promise resolving to the authenticated OAuth session\n * @throws {@link AuthenticationError} if:\n * - The callback contains an OAuth error\n * - The state is invalid or expired\n * - The code exchange fails\n * - Session persistence fails\n *\n * @example\n * ```typescript\n * // In your callback route handler\n * app.get(\"/callback\", async (req, res) => {\n * const params = new URLSearchParams(req.url.split(\"?\")[1]);\n *\n * try {\n * const session = await client.callback(params);\n * // Store DID for session restoration\n * req.session.userDid = session.sub;\n * res.redirect(\"/dashboard\");\n * } catch (error) {\n * res.redirect(\"/login?error=auth_failed\");\n * }\n * });\n * ```\n *\n * @remarks\n * After successful token exchange, this method verifies that the session\n * was properly persisted by attempting to restore it. This ensures the\n * storage backend is working correctly.\n */\n async callback(params: URLSearchParams): Promise<import(\"@atproto/oauth-client\").OAuthSession> {\n try {\n this.logger?.debug(\"Processing OAuth callback\");\n\n // Check for OAuth errors\n const error = params.get(\"error\");\n if (error) {\n const errorDescription = params.get(\"error_description\");\n throw new AuthenticationError(errorDescription || error);\n }\n\n const client = await this.getClient();\n const result = await client.callback(params);\n const session = result.session;\n const did = session.sub;\n\n this.logger?.info(\"OAuth callback successful\", { did });\n\n // Verify session can be restored (validates persistence)\n try {\n const restored = await client.restore(did);\n if (!restored) {\n throw new AuthenticationError(\"OAuth session was not persisted\");\n }\n this.logger?.debug(\"Session verified and restorable\", { did });\n } catch (restoreError) {\n this.logger?.error(\"Failed to verify persisted session\", {\n did,\n error: restoreError,\n });\n throw new AuthenticationError(\"Failed to persist OAuth session\", restoreError);\n }\n\n return session;\n } catch (error) {\n this.logger?.error(\"OAuth callback failed\", { error });\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `OAuth callback failed: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Restores an OAuth session by DID.\n *\n * Use this method to restore a previously authenticated session.\n * The method automatically refreshes expired access tokens using\n * the stored refresh token.\n *\n * @param did - The user's Decentralized Identifier (e.g., `\"did:plc:abc123...\"`)\n * @returns A Promise resolving to the session, or `null` if not found\n * @throws {@link AuthenticationError} if session restoration fails (not for missing sessions)\n * @throws {@link NetworkError} if token refresh requires network and fails\n *\n * @example\n * ```typescript\n * // On application startup or request\n * const userDid = req.session.userDid;\n * if (userDid) {\n * const session = await client.restore(userDid);\n * if (session) {\n * // Session restored, user is authenticated\n * req.atprotoSession = session;\n * } else {\n * // No session found, user needs to log in\n * delete req.session.userDid;\n * }\n * }\n * ```\n *\n * @remarks\n * Token refresh is handled automatically by the underlying OAuth client.\n * If the refresh token has expired or been revoked, this method will\n * throw an {@link AuthenticationError}.\n */\n async restore(did: string): Promise<import(\"@atproto/oauth-client\").OAuthSession | null> {\n try {\n this.logger?.debug(\"Restoring session\", { did });\n\n const client = await this.getClient();\n const session = await client.restore(did);\n\n if (session) {\n this.logger?.debug(\"Session restored\", { did });\n } else {\n this.logger?.debug(\"No session found\", { did });\n }\n\n return session;\n } catch (error) {\n this.logger?.error(\"Failed to restore session\", { did, error });\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new AuthenticationError(\n `Failed to restore session: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Revokes an OAuth session.\n *\n * This method invalidates the session's tokens both locally and\n * (if supported) on the authorization server. After revocation,\n * the session cannot be restored.\n *\n * @param did - The user's DID to revoke\n * @throws {@link AuthenticationError} if revocation fails\n *\n * @example\n * ```typescript\n * // Log out endpoint\n * app.post(\"/logout\", async (req, res) => {\n * const userDid = req.session.userDid;\n * if (userDid) {\n * await client.revoke(userDid);\n * delete req.session.userDid;\n * }\n * res.redirect(\"/\");\n * });\n * ```\n *\n * @remarks\n * Even if revocation fails on the server, the local session is\n * removed. The error is thrown to inform you that remote revocation\n * may not have succeeded.\n */\n async revoke(did: string): Promise<void> {\n try {\n this.logger?.debug(\"Revoking session\", { did });\n\n const client = await this.getClient();\n await client.revoke(did);\n\n this.logger?.info(\"Session revoked\", { did });\n } catch (error) {\n this.logger?.error(\"Failed to revoke session\", { did, error });\n throw new AuthenticationError(\n `Failed to revoke session: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n}\n","/**\n * ConfigurableAgent - Agent with configurable service URL routing.\n *\n * This module provides an Agent extension that allows routing requests to\n * a specific server URL, overriding the default URL from the OAuth session.\n *\n * @packageDocumentation\n */\n\nimport { Agent } from \"@atproto/api\";\nimport type { Session } from \"../core/types.js\";\n\n/**\n * FetchHandler type - function that makes HTTP requests with authentication.\n * Takes a pathname and request init, returns a Response promise.\n */\ntype FetchHandler = (pathname: string, init: RequestInit) => Promise<Response>;\n\n/**\n * Agent subclass that routes requests to a configurable service URL.\n *\n * The standard Agent uses the service URL embedded in the OAuth session's\n * fetch handler. This class allows overriding that URL to route requests\n * to different servers (e.g., PDS vs SDS, or multiple SDS instances).\n *\n * @remarks\n * This is particularly useful for:\n * - Routing to a Shared Data Server (SDS) while authenticated via PDS\n * - Supporting multiple SDS instances for different organizations\n * - Testing against different server environments\n *\n * @example Basic usage\n * ```typescript\n * const session = await sdk.authorize(\"user.bsky.social\");\n *\n * // Create agent routing to SDS instead of session's default PDS\n * const sdsAgent = new ConfigurableAgent(session, \"https://sds.hypercerts.org\");\n *\n * // All requests will now go to the SDS\n * await sdsAgent.com.atproto.repo.createRecord({...});\n * ```\n *\n * @example Multiple SDS instances\n * ```typescript\n * // Route to organization A's SDS\n * const orgAAgent = new ConfigurableAgent(session, \"https://sds-org-a.example.com\");\n *\n * // Route to organization B's SDS\n * const orgBAgent = new ConfigurableAgent(session, \"https://sds-org-b.example.com\");\n * ```\n */\nexport class ConfigurableAgent extends Agent {\n private customServiceUrl: string;\n\n /**\n * Creates a ConfigurableAgent that routes to a specific service URL.\n *\n * @param session - OAuth session for authentication\n * @param serviceUrl - Base URL of the server to route requests to\n *\n * @remarks\n * The agent wraps the session's fetch handler to intercept requests and\n * prepend the custom service URL instead of using the session's default.\n */\n constructor(session: Session, serviceUrl: string) {\n // Create a custom fetch handler that uses our service URL\n const customFetchHandler: FetchHandler = async (pathname: string, init: RequestInit) => {\n // Construct the full URL with our custom service\n const url = new URL(pathname, serviceUrl).toString();\n\n // Use the session's fetch handler for authentication (DPoP, etc.)\n return session.fetchHandler(url, init);\n };\n\n // Initialize the parent Agent with our custom fetch handler\n super(customFetchHandler);\n\n this.customServiceUrl = serviceUrl;\n }\n\n /**\n * Gets the service URL this agent routes to.\n *\n * @returns The base URL of the configured service\n */\n getServiceUrl(): string {\n return this.customServiceUrl;\n }\n}\n","/**\n * LexiconRegistry - Manages custom lexicon registration and validation.\n *\n * This module provides a registry for AT Protocol lexicon schemas,\n * allowing developers to register custom lexicons and validate records\n * against registered schemas.\n *\n * @packageDocumentation\n */\n\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport { Lexicons } from \"@atproto/lexicon\";\nimport type { Agent } from \"@atproto/api\";\nimport { ValidationError } from \"../errors.js\";\n\n/**\n * Validation result from lexicon validation.\n */\nexport interface ValidationResult {\n /**\n * Whether the record is valid according to the lexicon.\n */\n valid: boolean;\n\n /**\n * Error message if validation failed.\n */\n error?: string;\n}\n\n/**\n * Registry for managing AT Protocol lexicon schemas.\n *\n * The LexiconRegistry allows developers to:\n * - Register custom lexicon definitions\n * - Validate records against registered schemas\n * - Query registered lexicons\n * - Add lexicons to AT Protocol agents\n *\n * @example Basic usage\n * ```typescript\n * const registry = new LexiconRegistry();\n *\n * // Register a custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: {\n * main: {\n * type: \"record\",\n * key: \"tid\",\n * record: {\n * type: \"object\",\n * required: [\"$type\", \"title\"],\n * properties: {\n * \"$type\": { type: \"string\", const: \"org.myapp.customRecord\" },\n * title: { type: \"string\" }\n * }\n * }\n * }\n * }\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", {\n * $type: \"org.myapp.customRecord\",\n * title: \"My Record\"\n * });\n *\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n */\nexport class LexiconRegistry {\n private lexicons: Lexicons;\n private registeredIds: Set<string>;\n\n /**\n * Creates a new LexiconRegistry instance.\n *\n * @param initialLexicons - Optional array of lexicons to register on initialization\n */\n constructor(initialLexicons?: LexiconDoc[]) {\n this.lexicons = new Lexicons();\n this.registeredIds = new Set();\n\n if (initialLexicons && initialLexicons.length > 0) {\n this.registerMany(initialLexicons);\n }\n }\n\n /**\n * Registers a single lexicon definition.\n *\n * @param lexicon - The lexicon document to register\n * @throws {Error} If the lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... }\n * });\n * ```\n */\n register(lexicon: LexiconDoc): void {\n if (!lexicon.id) {\n throw new Error(\"Lexicon must have an id\");\n }\n\n if (this.registeredIds.has(lexicon.id)) {\n throw new Error(`Lexicon ${lexicon.id} is already registered`);\n }\n\n try {\n // Check if the lexicon already exists in the internal store\n // (e.g., after unregister which only removes from registeredIds)\n const existingLexicon = this.lexicons.get(lexicon.id);\n\n if (!existingLexicon) {\n // Lexicon is truly new, add it to the store\n this.lexicons.add(lexicon);\n }\n\n // Always add to registeredIds (re-enable if previously unregistered)\n this.registeredIds.add(lexicon.id);\n } catch (error) {\n throw new Error(\n `Failed to register lexicon ${lexicon.id}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Registers multiple lexicon definitions at once.\n *\n * @param lexicons - Array of lexicon documents to register\n * @throws {Error} If any lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * registry.registerMany([lexicon1, lexicon2, lexicon3]);\n * ```\n */\n registerMany(lexicons: LexiconDoc[]): void {\n for (const lexicon of lexicons) {\n this.register(lexicon);\n }\n }\n\n /**\n * Registers a lexicon from a JSON object.\n *\n * This is a convenience method for registering lexicons loaded from JSON files.\n *\n * @param lexiconJson - The lexicon as a plain JavaScript object\n * @throws {ValidationError} If the lexicon is not a valid object\n * @throws {Error} If the lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * import customLexicon from \"./custom-lexicon.json\";\n * registry.registerFromJSON(customLexicon);\n * ```\n */\n registerFromJSON(lexiconJson: unknown): void {\n // Validate that input is an object and not null\n if (typeof lexiconJson !== \"object\" || lexiconJson === null) {\n throw new ValidationError(\"Lexicon JSON must be a valid object\");\n }\n\n // Now we can safely cast to LexiconDoc and register\n this.register(lexiconJson as LexiconDoc);\n }\n\n /**\n * Unregisters a lexicon by its NSID.\n *\n * @param nsid - The NSID of the lexicon to unregister\n * @returns True if the lexicon was unregistered, false if it wasn't registered\n *\n * @example\n * ```typescript\n * registry.unregister(\"org.myapp.customRecord\");\n * ```\n */\n unregister(nsid: string): boolean {\n if (!this.registeredIds.has(nsid)) {\n return false;\n }\n\n this.registeredIds.delete(nsid);\n // Note: Lexicons class doesn't have a remove method,\n // so we can't actually remove from the internal store.\n // We track removal in our Set for isRegistered checks.\n return true;\n }\n\n /**\n * Checks if a lexicon is registered.\n *\n * @param nsid - The NSID to check\n * @returns True if the lexicon is registered\n *\n * @example\n * ```typescript\n * if (registry.isRegistered(\"org.myapp.customRecord\")) {\n * // Lexicon is available\n * }\n * ```\n */\n isRegistered(nsid: string): boolean {\n return this.registeredIds.has(nsid);\n }\n\n /**\n * Gets a lexicon definition by its NSID.\n *\n * @param nsid - The NSID of the lexicon to retrieve\n * @returns The lexicon document, or undefined if not found\n *\n * @example\n * ```typescript\n * const lexicon = registry.get(\"org.myapp.customRecord\");\n * if (lexicon) {\n * console.log(lexicon.defs);\n * }\n * ```\n */\n get(nsid: string): LexiconDoc | undefined {\n if (!this.isRegistered(nsid)) {\n return undefined;\n }\n\n return this.lexicons.get(nsid);\n }\n\n /**\n * Gets all registered lexicon NSIDs.\n *\n * @returns Array of registered NSIDs\n *\n * @example\n * ```typescript\n * const registered = registry.getAll();\n * console.log(`Registered lexicons: ${registered.join(\", \")}`);\n * ```\n */\n getAll(): string[] {\n return Array.from(this.registeredIds);\n }\n\n /**\n * Validates a record against a registered lexicon.\n *\n * @param nsid - The collection NSID to validate against\n * @param record - The record data to validate\n * @returns Validation result with success status and optional error message\n *\n * @example\n * ```typescript\n * const result = registry.validate(\"org.myapp.customRecord\", {\n * $type: \"org.myapp.customRecord\",\n * title: \"My Record\"\n * });\n *\n * if (!result.valid) {\n * console.error(`Validation failed: ${result.error}`);\n * }\n * ```\n */\n validate(nsid: string, record: unknown): ValidationResult {\n if (!this.isRegistered(nsid)) {\n return {\n valid: false,\n error: `Lexicon ${nsid} is not registered`,\n };\n }\n\n try {\n this.lexicons.assertValidRecord(nsid, record);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Validation failed\",\n };\n }\n }\n\n /**\n * Adds all registered lexicons to an AT Protocol Agent.\n *\n * This method is currently a no-op as the AT Protocol Agent\n * doesn't provide a public API for adding lexicons at runtime.\n * Lexicons must be registered with the server.\n *\n * This method is kept for future compatibility if the API\n * adds support for client-side lexicon registration.\n *\n * @param _agent - The AT Protocol Agent (currently unused)\n *\n * @example\n * ```typescript\n * const agent = new Agent(session);\n * registry.addToAgent(agent);\n * // Reserved for future use\n * ```\n */\n addToAgent(_agent: Agent): void {\n // No-op: AT Protocol Agent doesn't support client-side lexicon addition\n // Lexicons are validated client-side via this registry,\n // but server-side validation is performed by the PDS/SDS\n }\n\n /**\n * Gets the underlying Lexicons instance.\n *\n * This provides direct access to the AT Protocol Lexicons object\n * for advanced use cases.\n *\n * @returns The internal Lexicons instance\n *\n * @example\n * ```typescript\n * const lexicons = registry.getLexicons();\n * // Use lexicons directly for advanced operations\n * ```\n */\n getLexicons(): Lexicons {\n return this.lexicons;\n }\n}\n","/**\n * RecordOperationsImpl - Low-level record CRUD operations.\n *\n * This module provides the implementation for direct AT Protocol\n * record operations (create, read, update, delete, list).\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError, ValidationError } from \"../errors.js\";\nimport type { RecordOperations } from \"./interfaces.js\";\nimport type { CreateResult, UpdateResult, PaginatedList } from \"./types.js\";\nimport type { LexiconRegistry } from \"./LexiconRegistry.js\";\n\n/**\n * Implementation of low-level AT Protocol record operations.\n *\n * This class provides direct access to the AT Protocol repository API\n * for CRUD operations on records. It handles:\n *\n * - Lexicon validation before create/update operations\n * - Error mapping to SDK error types\n * - Response normalization\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.records}.\n *\n * All operations are performed against the repository DID specified\n * at construction time. To operate on a different repository, create\n * a new Repository instance using {@link Repository.repo}.\n *\n * @example\n * ```typescript\n * // Access through Repository\n * const repo = sdk.repository(session);\n *\n * // Create a record\n * const { uri, cid } = await repo.records.create({\n * collection: \"org.example.myRecord\",\n * record: { title: \"Hello\", createdAt: new Date().toISOString() },\n * });\n *\n * // Update the record\n * const rkey = uri.split(\"/\").pop()!;\n * await repo.records.update({\n * collection: \"org.example.myRecord\",\n * rkey,\n * record: { title: \"Updated\", createdAt: new Date().toISOString() },\n * });\n * ```\n *\n * @internal\n */\nexport class RecordOperationsImpl implements RecordOperations {\n /**\n * Creates a new RecordOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository to operate on\n * @param lexiconRegistry - Optional registry for validating records against lexicon schemas\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private lexiconRegistry?: LexiconRegistry,\n ) {}\n\n /**\n * Creates a new record in the specified collection.\n *\n * @param params - Creation parameters\n * @param params.collection - NSID of the collection (e.g., \"org.hypercerts.hypercert\")\n * @param params.record - Record data conforming to the collection's lexicon schema\n * @param params.rkey - Optional record key. If not provided, a TID (timestamp-based ID)\n * is automatically generated by the server.\n * @param params.skipValidation - Optional flag to skip lexicon validation (default: false)\n * @returns Promise resolving to the created record's URI and CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @remarks\n * The record is validated against the collection's lexicon before sending\n * to the server if the collection is registered in the LexiconRegistry.\n * If no lexicon is registered for the collection, validation is skipped\n * (allowing custom record types). Use `skipValidation: true` to bypass\n * validation even for registered collections.\n *\n * **AT-URI Format**: `at://{did}/{collection}/{rkey}`\n *\n * @example\n * ```typescript\n * const result = await repo.records.create({\n * collection: \"org.hypercerts.hypercert\",\n * record: {\n * title: \"My Hypercert\",\n * description: \"...\",\n * createdAt: new Date().toISOString(),\n * },\n * });\n * console.log(`Created: ${result.uri}`);\n * // Output: Created: at://did:plc:abc123/org.hypercerts.hypercert/xyz789\n * ```\n */\n async create(params: {\n collection: string;\n record: unknown;\n rkey?: string;\n skipValidation?: boolean;\n }): Promise<CreateResult> {\n try {\n // Validate record against registered lexicon if available\n if (!params.skipValidation && this.lexiconRegistry?.isRegistered(params.collection)) {\n const validation = this.lexiconRegistry.validate(params.collection, params.record);\n if (!validation.valid) {\n throw new ValidationError(`Invalid record for collection ${params.collection}: ${validation.error}`);\n }\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: params.collection,\n record: params.record as Record<string, unknown>,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates an existing record (full replacement).\n *\n * @param params - Update parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key (the last segment of the AT-URI)\n * @param params.record - New record data (completely replaces existing record)\n * @param params.skipValidation - Optional flag to skip lexicon validation (default: false)\n * @returns Promise resolving to the updated record's URI and new CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @remarks\n * This is a full replacement operation, not a partial update. The entire\n * record is replaced with the new data. To preserve existing fields,\n * first fetch the record with {@link get}, modify it, then update.\n *\n * The record is validated against the collection's lexicon before sending\n * to the server if the collection is registered in the LexiconRegistry.\n * Use `skipValidation: true` to bypass validation.\n *\n * @example\n * ```typescript\n * // Get existing record\n * const existing = await repo.records.get({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n *\n * // Update with modified data\n * const updated = await repo.records.update({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * record: {\n * ...existing.value,\n * title: \"Updated Title\",\n * },\n * });\n * ```\n */\n async update(params: {\n collection: string;\n rkey: string;\n record: unknown;\n skipValidation?: boolean;\n }): Promise<UpdateResult> {\n try {\n // Validate record against registered lexicon if available\n if (!params.skipValidation && this.lexiconRegistry?.isRegistered(params.collection)) {\n const validation = this.lexiconRegistry.validate(params.collection, params.record);\n if (!validation.valid) {\n throw new ValidationError(`Invalid record for collection ${params.collection}: ${validation.error}`);\n }\n }\n\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n record: params.record as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a single record by collection and key.\n *\n * @param params - Get parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key\n * @returns Promise resolving to the record's URI, CID, and value\n * @throws {@link NetworkError} if the record is not found or request fails\n *\n * @example\n * ```typescript\n * const record = await repo.records.get({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n *\n * console.log(record.uri); // at://did:plc:abc123/org.hypercerts.hypercert/xyz789\n * console.log(record.cid); // bafyrei...\n * console.log(record.value); // { title: \"...\", description: \"...\", ... }\n * ```\n */\n async get(params: { collection: string; rkey: string }): Promise<{ uri: string; cid: string; value: unknown }> {\n try {\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid ?? \"\", value: result.data.value };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to get record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Lists records in a collection with pagination.\n *\n * @param params - List parameters\n * @param params.collection - NSID of the collection\n * @param params.limit - Maximum number of records to return (server may impose its own limit)\n * @param params.cursor - Pagination cursor from a previous response\n * @returns Promise resolving to paginated list of records\n * @throws {@link NetworkError} if the request fails\n *\n * @remarks\n * Records are returned in reverse chronological order (newest first).\n * Use the `cursor` from the response to fetch subsequent pages.\n *\n * @example Paginating through all records\n * ```typescript\n * let cursor: string | undefined;\n * const allRecords = [];\n *\n * do {\n * const page = await repo.records.list({\n * collection: \"org.hypercerts.hypercert\",\n * limit: 100,\n * cursor,\n * });\n * allRecords.push(...page.records);\n * cursor = page.cursor;\n * } while (cursor);\n *\n * console.log(`Total records: ${allRecords.length}`);\n * ```\n */\n async list(params: {\n collection: string;\n limit?: number;\n cursor?: string;\n }): Promise<PaginatedList<{ uri: string; cid: string; value: unknown }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: params.collection,\n limit: params.limit,\n cursor: params.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list records\");\n }\n\n return {\n records: result.data.records?.map((r) => ({ uri: r.uri, cid: r.cid, value: r.value })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to list records: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Deletes a record from a collection.\n *\n * @param params - Delete parameters\n * @param params.collection - NSID of the collection\n * @param params.rkey - Record key to delete\n * @throws {@link NetworkError} if the deletion fails\n *\n * @remarks\n * Deletion is permanent. The record's AT-URI cannot be reused (the same\n * rkey can be used for a new record, but it will have a different CID).\n *\n * @example\n * ```typescript\n * await repo.records.delete({\n * collection: \"org.hypercerts.hypercert\",\n * rkey: \"xyz789\",\n * });\n * ```\n */\n async delete(params: { collection: string; rkey: string }): Promise<void> {\n try {\n const result = await this.agent.com.atproto.repo.deleteRecord({\n repo: this.repoDid,\n collection: params.collection,\n rkey: params.rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to delete record\");\n }\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to delete record: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n}\n","/**\n * BlobOperationsImpl - Blob upload and retrieval operations.\n *\n * This module provides the implementation for AT Protocol blob operations,\n * handling binary data like images and files.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError } from \"../core/errors.js\";\nimport type { BlobOperations } from \"./interfaces.js\";\n\n/**\n * Implementation of blob operations for binary data handling.\n *\n * Blobs in AT Protocol are content-addressed binary objects stored\n * separately from records. They are referenced in records using a\n * blob reference object with a CID ($link).\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.blobs}.\n *\n * **Blob Size Limits**: PDS servers typically impose size limits on blobs.\n * Common limits are:\n * - Images: 1MB\n * - Other files: Varies by server configuration\n *\n * **Supported MIME Types**: Any MIME type is technically supported, but\n * servers may reject certain types. Images (JPEG, PNG, GIF, WebP) are\n * universally supported.\n *\n * @example\n * ```typescript\n * // Upload an image blob\n * const imageBlob = new Blob([imageData], { type: \"image/jpeg\" });\n * const { ref, mimeType, size } = await repo.blobs.upload(imageBlob);\n *\n * // Use the ref in a record\n * await repo.records.create({\n * collection: \"org.example.post\",\n * record: {\n * text: \"Check out this image!\",\n * image: ref, // { $link: \"bafyrei...\" }\n * createdAt: new Date().toISOString(),\n * },\n * });\n * ```\n *\n * @internal\n */\nexport class BlobOperationsImpl implements BlobOperations {\n /**\n * Creates a new BlobOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository (used for blob retrieval)\n * @param _serverUrl - Server URL (reserved for future use)\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n ) {}\n\n /**\n * Uploads a blob to the server.\n *\n * @param blob - The blob to upload (File or Blob object)\n * @returns Promise resolving to blob reference and metadata\n * @throws {@link NetworkError} if the upload fails\n *\n * @remarks\n * The returned `ref` object should be used directly in records to\n * reference the blob. The `$link` property contains the blob's CID.\n *\n * **MIME Type Detection**: If the blob has no type, it defaults to\n * `application/octet-stream`. For best results, always specify the\n * correct MIME type when creating the Blob.\n *\n * @example Uploading an image\n * ```typescript\n * // From a File input\n * const file = fileInput.files[0];\n * const { ref } = await repo.blobs.upload(file);\n *\n * // From raw data\n * const imageBlob = new Blob([uint8Array], { type: \"image/png\" });\n * const { ref, mimeType, size } = await repo.blobs.upload(imageBlob);\n *\n * console.log(`Uploaded ${size} bytes of ${mimeType}`);\n * console.log(`CID: ${ref.$link}`);\n * ```\n *\n * @example Using in a hypercert\n * ```typescript\n * const coverImage = new Blob([imageData], { type: \"image/jpeg\" });\n * const { ref } = await repo.blobs.upload(coverImage);\n *\n * // The ref is used directly in the record\n * await repo.hypercerts.create({\n * title: \"My Hypercert\",\n * // ... other fields\n * image: coverImage, // HypercertOperations handles upload internally\n * });\n * ```\n */\n async upload(blob: Blob): Promise<{ ref: { $link: string }; mimeType: string; size: number }> {\n try {\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n const result = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: blob.type || \"application/octet-stream\",\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to upload blob\");\n }\n\n return {\n ref: { $link: result.data.blob.ref.toString() },\n mimeType: result.data.blob.mimeType,\n size: result.data.blob.size,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to upload blob: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Retrieves a blob by its CID.\n *\n * @param cid - Content Identifier (CID) of the blob, typically from a blob\n * reference's `$link` property\n * @returns Promise resolving to blob data and MIME type\n * @throws {@link NetworkError} if the blob is not found or retrieval fails\n *\n * @remarks\n * The returned data is a Uint8Array which can be converted to other\n * formats as needed (Blob, ArrayBuffer, Base64, etc.).\n *\n * **MIME Type**: The returned MIME type comes from the Content-Type header.\n * If the server doesn't provide one, it defaults to `application/octet-stream`.\n *\n * @example Basic retrieval\n * ```typescript\n * // Get a blob from a record's blob reference\n * const record = await repo.records.get({ collection, rkey });\n * const blobRef = (record.value as any).image;\n *\n * const { data, mimeType } = await repo.blobs.get(blobRef.$link);\n *\n * // Convert to a Blob for use in the browser\n * const blob = new Blob([data], { type: mimeType });\n * const url = URL.createObjectURL(blob);\n * ```\n *\n * @example Displaying an image\n * ```typescript\n * const { data, mimeType } = await repo.blobs.get(imageCid);\n *\n * // Create data URL for <img> src\n * const base64 = btoa(String.fromCharCode(...data));\n * const dataUrl = `data:${mimeType};base64,${base64}`;\n *\n * // Or use object URL\n * const blob = new Blob([data], { type: mimeType });\n * img.src = URL.createObjectURL(blob);\n * ```\n */\n async get(cid: string): Promise<{ data: Uint8Array; mimeType: string }> {\n try {\n const result = await this.agent.com.atproto.sync.getBlob({\n did: this.repoDid,\n cid,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get blob\");\n }\n\n return {\n data: result.data,\n mimeType: result.headers[\"content-type\"] || \"application/octet-stream\",\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get blob: ${error instanceof Error ? error.message : \"Unknown error\"}`, error);\n }\n }\n}\n","/**\n * ProfileOperationsImpl - User profile operations.\n *\n * This module provides the implementation for AT Protocol profile\n * management, including fetching and updating user profiles.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { NetworkError } from \"../core/errors.js\";\nimport type { ProfileOperations } from \"./interfaces.js\";\nimport type { UpdateResult } from \"./types.js\";\n\n/**\n * Implementation of profile operations for user profile management.\n *\n * Profiles in AT Protocol are stored as records in the `app.bsky.actor.profile`\n * collection with the special rkey \"self\". This class provides a convenient\n * API for reading and updating profile data.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.profile}.\n *\n * **Profile Fields**:\n * - `handle`: Read-only, managed by the PDS\n * - `displayName`: User's display name (max 64 chars typically)\n * - `description`: Profile bio (max 256 chars typically)\n * - `avatar`: Profile picture blob reference\n * - `banner`: Banner image blob reference\n * - `website`: User's website URL (may not be available on all servers)\n *\n * @example\n * ```typescript\n * // Get profile\n * const profile = await repo.profile.get();\n * console.log(`${profile.displayName} (@${profile.handle})`);\n *\n * // Update profile\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"Updated bio\",\n * });\n *\n * // Update with new avatar\n * const avatarBlob = new Blob([imageData], { type: \"image/png\" });\n * await repo.profile.update({ avatar: avatarBlob });\n *\n * // Remove a field\n * await repo.profile.update({ website: null });\n * ```\n *\n * @internal\n */\nexport class ProfileOperationsImpl implements ProfileOperations {\n /**\n * Creates a new ProfileOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository/user\n * @param _serverUrl - Server URL (reserved for future use)\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n ) {}\n\n /**\n * Gets the repository's profile.\n *\n * @returns Promise resolving to profile data\n * @throws {@link NetworkError} if the profile cannot be fetched\n *\n * @remarks\n * This method fetches the full profile using the `getProfile` API,\n * which includes resolved information like follower counts on some\n * servers. For hypercerts SDK usage, the basic profile fields are\n * returned.\n *\n * **Note**: The `website` field may not be available on all AT Protocol\n * servers. Standard Bluesky profiles don't include this field.\n *\n * @example\n * ```typescript\n * const profile = await repo.profile.get();\n *\n * console.log(`Handle: @${profile.handle}`);\n * console.log(`Name: ${profile.displayName || \"(not set)\"}`);\n * console.log(`Bio: ${profile.description || \"(no bio)\"}`);\n *\n * if (profile.avatar) {\n * // Avatar is a URL or blob reference\n * console.log(`Avatar: ${profile.avatar}`);\n * }\n * ```\n */\n async get(): Promise<{\n handle: string;\n displayName?: string;\n description?: string;\n avatar?: string;\n banner?: string;\n website?: string;\n }> {\n try {\n const result = await this.agent.getProfile({ actor: this.repoDid });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get profile\");\n }\n\n return {\n handle: result.data.handle,\n displayName: result.data.displayName,\n description: result.data.description,\n avatar: result.data.avatar,\n banner: result.data.banner,\n // Note: website may not be available in standard profile\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to get profile: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates the repository's profile.\n *\n * @param params - Fields to update. Pass `null` to remove a field.\n * Omitted fields are preserved from the existing profile.\n * @returns Promise resolving to update result with new URI and CID\n * @throws {@link NetworkError} if the update fails\n *\n * @remarks\n * This method performs a read-modify-write operation:\n * 1. Fetches the existing profile record\n * 2. Merges in the provided updates\n * 3. Writes the updated profile back\n *\n * **Image Handling**: When providing `avatar` or `banner` as a Blob,\n * the image is automatically uploaded and the blob reference is stored\n * in the profile.\n *\n * **Field Removal**: Pass `null` to explicitly remove a field. Omitting\n * a field (not including it in params) preserves the existing value.\n *\n * @example Update display name and bio\n * ```typescript\n * await repo.profile.update({\n * displayName: \"Alice\",\n * description: \"Building impact certificates\",\n * });\n * ```\n *\n * @example Update avatar image\n * ```typescript\n * // From a file input\n * const file = document.getElementById(\"avatar\").files[0];\n * await repo.profile.update({ avatar: file });\n *\n * // From raw data\n * const response = await fetch(\"https://example.com/my-avatar.png\");\n * const blob = await response.blob();\n * await repo.profile.update({ avatar: blob });\n * ```\n *\n * @example Remove description\n * ```typescript\n * // Removes the description field entirely\n * await repo.profile.update({ description: null });\n * ```\n *\n * @example Multiple updates at once\n * ```typescript\n * const newAvatar = new Blob([avatarData], { type: \"image/png\" });\n * const newBanner = new Blob([bannerData], { type: \"image/jpeg\" });\n *\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"New bio\",\n * avatar: newAvatar,\n * banner: newBanner,\n * });\n * ```\n */\n async update(params: {\n displayName?: string | null;\n description?: string | null;\n avatar?: Blob | null;\n banner?: Blob | null;\n website?: string | null;\n }): Promise<UpdateResult> {\n try {\n // Get existing profile record\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection: \"app.bsky.actor.profile\",\n rkey: \"self\",\n });\n\n const existingProfile = (existing.data.value as Record<string, unknown>) || {};\n\n // Build updated profile\n const updatedProfile: Record<string, unknown> = { ...existingProfile };\n\n if (params.displayName !== undefined) {\n if (params.displayName === null) {\n delete updatedProfile.displayName;\n } else {\n updatedProfile.displayName = params.displayName;\n }\n }\n\n if (params.description !== undefined) {\n if (params.description === null) {\n delete updatedProfile.description;\n } else {\n updatedProfile.description = params.description;\n }\n }\n\n // Handle avatar upload\n if (params.avatar !== undefined) {\n if (params.avatar === null) {\n delete updatedProfile.avatar;\n } else {\n const arrayBuffer = await params.avatar.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.avatar.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n updatedProfile.avatar = uploadResult.data.blob;\n }\n }\n }\n\n // Handle banner upload\n if (params.banner !== undefined) {\n if (params.banner === null) {\n delete updatedProfile.banner;\n } else {\n const arrayBuffer = await params.banner.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.banner.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n updatedProfile.banner = uploadResult.data.blob;\n }\n }\n }\n\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection: \"app.bsky.actor.profile\",\n rkey: \"self\",\n record: updatedProfile,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update profile\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update profile: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n}\n","/**\n * Lexicons entrypoint - Lexicon definitions and registry.\n *\n * This sub-entrypoint exports the lexicon registry and hypercert\n * lexicon constants for working with AT Protocol record schemas.\n *\n * @remarks\n * Import from `@hypercerts-org/sdk/lexicons`:\n *\n * ```typescript\n * import {\n * LexiconRegistry,\n * HYPERCERT_LEXICONS,\n * HYPERCERT_COLLECTIONS,\n * } from \"@hypercerts-org/sdk/lexicons\";\n * ```\n *\n * **Exports**:\n * - {@link LexiconRegistry} - Registry for managing and validating lexicons\n * - {@link HYPERCERT_LEXICONS} - Array of all hypercert lexicon documents\n * - {@link HYPERCERT_COLLECTIONS} - Constants for collection NSIDs\n *\n * @example Using collection constants\n * ```typescript\n * import { HYPERCERT_COLLECTIONS } from \"@hypercerts-org/sdk/lexicons\";\n *\n * // List hypercerts using the correct collection name\n * const records = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.RECORD,\n * });\n *\n * // List contributions\n * const contributions = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n * });\n * ```\n *\n * @example Custom lexicon registration\n * ```typescript\n * import { LexiconRegistry } from \"@hypercerts-org/sdk/lexicons\";\n *\n * const registry = sdk.getLexiconRegistry();\n *\n * // Register custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... },\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", record);\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Import lexicon JSON files and constants from the published package\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport {\n CERTIFIED_DEFS_LEXICON_JSON,\n LOCATION_LEXICON_JSON,\n STRONG_REF_LEXICON_JSON,\n HYPERCERTS_DEFS_LEXICON_JSON,\n ACTIVITY_LEXICON_JSON,\n COLLECTION_LEXICON_JSON,\n CONTRIBUTION_DETAILS_LEXICON_JSON,\n CONTRIBUTOR_INFORMATION_LEXICON_JSON,\n EVALUATION_LEXICON_JSON,\n EVIDENCE_LEXICON_JSON,\n MEASUREMENT_LEXICON_JSON,\n RIGHTS_LEXICON_JSON,\n BADGE_AWARD_LEXICON_JSON,\n BADGE_DEFINITION_LEXICON_JSON,\n BADGE_RESPONSE_LEXICON_JSON,\n FUNDING_RECEIPT_LEXICON_JSON,\n WORK_SCOPE_TAG_LEXICON_JSON,\n // NSID constants\n ACTIVITY_NSID,\n RIGHTS_NSID,\n LOCATION_NSID,\n CONTRIBUTION_DETAILS_NSID,\n CONTRIBUTOR_INFORMATION_NSID,\n MEASUREMENT_NSID,\n EVALUATION_NSID,\n EVIDENCE_NSID,\n COLLECTION_NSID,\n BADGE_AWARD_NSID,\n BADGE_DEFINITION_NSID,\n BADGE_RESPONSE_NSID,\n FUNDING_RECEIPT_NSID,\n WORK_SCOPE_TAG_NSID,\n} from \"@hypercerts-org/lexicon\";\n\n// Export LexiconRegistry for custom lexicon management\nexport { LexiconRegistry } from \"./repository/LexiconRegistry.js\";\nexport type { ValidationResult } from \"./repository/LexiconRegistry.js\";\n\n/**\n * All hypercert-related lexicons for registration with AT Protocol Agent.\n * This array contains all lexicon documents from the published package.\n */\nexport const HYPERCERT_LEXICONS: LexiconDoc[] = [\n CERTIFIED_DEFS_LEXICON_JSON as LexiconDoc,\n LOCATION_LEXICON_JSON as LexiconDoc,\n STRONG_REF_LEXICON_JSON as LexiconDoc,\n HYPERCERTS_DEFS_LEXICON_JSON as LexiconDoc,\n ACTIVITY_LEXICON_JSON as LexiconDoc,\n COLLECTION_LEXICON_JSON as LexiconDoc,\n CONTRIBUTION_DETAILS_LEXICON_JSON as LexiconDoc,\n CONTRIBUTOR_INFORMATION_LEXICON_JSON as LexiconDoc,\n EVALUATION_LEXICON_JSON as LexiconDoc,\n EVIDENCE_LEXICON_JSON as LexiconDoc,\n MEASUREMENT_LEXICON_JSON as LexiconDoc,\n RIGHTS_LEXICON_JSON as LexiconDoc,\n BADGE_AWARD_LEXICON_JSON as LexiconDoc,\n BADGE_DEFINITION_LEXICON_JSON as LexiconDoc,\n BADGE_RESPONSE_LEXICON_JSON as LexiconDoc,\n FUNDING_RECEIPT_LEXICON_JSON as LexiconDoc,\n WORK_SCOPE_TAG_LEXICON_JSON as LexiconDoc,\n];\n\n/**\n * Collection NSIDs (Namespaced Identifiers) for hypercert records.\n *\n * Use these constants when performing record operations to ensure\n * correct collection names.\n */\nexport const HYPERCERT_COLLECTIONS = {\n /**\n * Main hypercert claim record collection.\n */\n CLAIM: ACTIVITY_NSID,\n\n /**\n * Rights record collection.\n */\n RIGHTS: RIGHTS_NSID,\n\n /**\n * Location record collection (shared certified lexicon).\n */\n LOCATION: LOCATION_NSID,\n\n /**\n * Contribution details record collection.\n * For storing details about a specific contribution (role, description, timeframe).\n */\n CONTRIBUTION_DETAILS: CONTRIBUTION_DETAILS_NSID,\n\n /**\n * Contributor information record collection.\n * For storing contributor profile information (identifier, displayName, image).\n */\n CONTRIBUTOR_INFORMATION: CONTRIBUTOR_INFORMATION_NSID,\n\n /**\n * Measurement record collection.\n */\n MEASUREMENT: MEASUREMENT_NSID,\n\n /**\n * Evaluation record collection.\n */\n EVALUATION: EVALUATION_NSID,\n\n /**\n * Evidence record collection.\n */\n EVIDENCE: EVIDENCE_NSID,\n\n /**\n * Collection record collection (groups of hypercerts).\n * Projects are now collections with type='project'.\n */\n COLLECTION: COLLECTION_NSID,\n\n /**\n * Badge award record collection.\n */\n BADGE_AWARD: BADGE_AWARD_NSID,\n\n /**\n * Badge definition record collection.\n */\n BADGE_DEFINITION: BADGE_DEFINITION_NSID,\n\n /**\n * Badge response record collection.\n */\n BADGE_RESPONSE: BADGE_RESPONSE_NSID,\n\n /**\n * Funding receipt record collection.\n */\n FUNDING_RECEIPT: FUNDING_RECEIPT_NSID,\n\n /**\n * Work scope tag record collection.\n * For defining reusable work scope atoms.\n */\n WORK_SCOPE_TAG: WORK_SCOPE_TAG_NSID,\n} as const;\n","/**\n * HypercertOperationsImpl - High-level hypercert operations.\n *\n * This module provides the implementation for creating and managing\n * hypercerts, including related records like rights, locations,\n * contributions, measurements, and evaluations.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { validate } from \"@hypercerts-org/lexicon\";\nimport { EventEmitter } from \"eventemitter3\";\nimport { NetworkError, ValidationError } from \"../errors.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport {\n HYPERCERT_COLLECTIONS,\n type HypercertClaim,\n type HypercertCollection,\n type HypercertContributionDetails,\n type HypercertEvaluation,\n type HypercertEvidence,\n type HypercertLocation,\n type HypercertMeasurement,\n type HypercertRights,\n type JsonBlobRef,\n} from \"../services/hypercerts/types.js\";\nimport type {\n CreateHypercertEvidenceParams,\n AttachLocationParams,\n CreateHypercertParams,\n CreateHypercertResult,\n HypercertEvents,\n HypercertOperations,\n} from \"./interfaces.js\";\nimport type { CreateResult, ListParams, PaginatedList, ProgressStep, UpdateResult } from \"./types.js\";\n\n/**\n * Implementation of high-level hypercert operations.\n *\n * This class provides a convenient API for creating and managing hypercerts\n * with automatic handling of:\n *\n * - Image upload and blob reference management\n * - Rights record creation and linking\n * - Location attachment with optional GeoJSON support\n * - Contribution tracking\n * - Measurement and evaluation records\n * - Hypercert collections\n *\n * The class extends EventEmitter to provide real-time progress notifications\n * during complex operations.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.hypercerts}.\n *\n * **Record Relationships**:\n * - Hypercert → Rights (required, 1:1)\n * - Hypercert → Location (optional, 1:many)\n * - Hypercert → Contribution (optional, 1:many)\n * - Hypercert → Measurement (optional, 1:many)\n * - Hypercert → Evaluation (optional, 1:many)\n * - Collection → Hypercerts (1:many via claims array)\n *\n * @example Creating a hypercert with progress tracking\n * ```typescript\n * repo.hypercerts.on(\"recordCreated\", ({ uri }) => {\n * console.log(`Hypercert created: ${uri}`);\n * });\n *\n * const result = await repo.hypercerts.create({\n * title: \"Climate Impact\",\n * description: \"Reduced emissions by 100 tons\",\n * workScope: \"Climate\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: { name: \"CC-BY\", type: \"license\", description: \"...\" },\n * onProgress: (step) => console.log(`${step.name}: ${step.status}`),\n * });\n * ```\n *\n * @internal\n */\nexport class HypercertOperationsImpl extends EventEmitter<HypercertEvents> implements HypercertOperations {\n /**\n * Creates a new HypercertOperationsImpl.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository to operate on\n * @param _serverUrl - Server URL (reserved for future use)\n * @param logger - Optional logger for debugging\n *\n * @internal\n */\n constructor(\n private agent: Agent,\n private repoDid: string,\n private _serverUrl: string,\n private logger?: LoggerInterface,\n ) {\n super();\n }\n\n /**\n * Emits a progress event to the optional progress handler.\n *\n * @param onProgress - Progress callback from create params\n * @param step - Progress step information\n * @internal\n */\n private emitProgress(onProgress: ((step: ProgressStep) => void) | undefined, step: ProgressStep): void {\n if (onProgress) {\n try {\n onProgress(step);\n } catch (err) {\n this.logger?.error(`Error in progress handler: ${err instanceof Error ? err.message : \"Unknown\"}`);\n }\n }\n }\n\n /**\n * Helper function to upload a blob to the repository, returns a blob reference\n *\n * @param content - Blob to upload\n * @param fallbackContentType | if content.type is empty,we use this\n * @returns BlobRef\n * @throws {@link NetworkError} if upload fails\n * @internal\n */\n\n private async handleBlobUpload(content: Blob, fallbackContentType: string) {\n const arrayBuffer = await content.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: content.type || fallbackContentType,\n });\n if (!uploadResult.success) {\n throw new NetworkError(\"Failed to upload blob\");\n }\n return uploadResult.data.blob;\n }\n\n /**\n * Uploads an image blob and returns a blob reference.\n *\n * @param image - Image blob to upload\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to blob reference or undefined\n * @throws {@link NetworkError} if upload fails\n * @internal\n */\n private async uploadImageBlob(\n image: Blob,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<JsonBlobRef | undefined> {\n this.emitProgress(onProgress, { name: \"uploadImage\", status: \"start\" });\n try {\n const arrayBuffer = await image.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: image.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n const blobRef: JsonBlobRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n this.emitProgress(onProgress, {\n name: \"uploadImage\",\n status: \"success\",\n data: { size: image.size },\n });\n return blobRef;\n }\n throw new NetworkError(\"Image upload succeeded but returned no blob reference\");\n } catch (error) {\n this.emitProgress(onProgress, { name: \"uploadImage\", status: \"error\", error: error as Error });\n throw new NetworkError(`Failed to upload image: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a rights record for a hypercert.\n *\n * @param rights - Rights data\n * @param createdAt - ISO timestamp for creation\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to rights URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if creation fails\n * @internal\n */\n private async createRightsRecord(\n rights: { name: string; type: string; description: string },\n createdAt: string,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<{ uri: string; cid: string }> {\n this.emitProgress(onProgress, { name: \"createRights\", status: \"start\" });\n const rightsRecord: HypercertRights = {\n $type: HYPERCERT_COLLECTIONS.RIGHTS,\n rightsName: rights.name,\n rightsType: rights.type,\n rightsDescription: rights.description,\n createdAt,\n };\n\n const rightsValidation = validate(rightsRecord, HYPERCERT_COLLECTIONS.RIGHTS, \"main\", false);\n if (!rightsValidation.success) {\n throw new ValidationError(`Invalid rights record: ${rightsValidation.error?.message}`);\n }\n\n const rightsResult = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.RIGHTS,\n record: rightsRecord as Record<string, unknown>,\n });\n\n if (!rightsResult.success) {\n throw new NetworkError(\"Failed to create rights record\");\n }\n\n const uri = rightsResult.data.uri;\n const cid = rightsResult.data.cid;\n this.emit(\"rightsCreated\", { uri, cid });\n this.emitProgress(onProgress, {\n name: \"createRights\",\n status: \"success\",\n data: { uri },\n });\n\n return { uri, cid };\n }\n\n /**\n * Creates the main hypercert record.\n *\n * @param params - Hypercert creation parameters\n * @param rightsUri - URI of the associated rights record\n * @param rightsCid - CID of the associated rights record\n * @param imageBlobRef - Optional image blob reference\n * @param createdAt - ISO timestamp for creation\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to hypercert URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if creation fails\n * @internal\n */\n private async createHypercertRecord(\n params: CreateHypercertParams,\n rightsUri: string,\n rightsCid: string,\n imageBlobRef: JsonBlobRef | undefined,\n createdAt: string,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<{ uri: string; cid: string }> {\n this.emitProgress(onProgress, { name: \"createHypercert\", status: \"start\" });\n const hypercertRecord: Record<string, unknown> = {\n $type: HYPERCERT_COLLECTIONS.CLAIM,\n title: params.title,\n shortDescription: params.shortDescription,\n description: params.description,\n workScope: params.workScope,\n startDate: params.startDate,\n endDate: params.endDate,\n rights: { uri: rightsUri, cid: rightsCid },\n createdAt,\n };\n\n if (imageBlobRef) {\n hypercertRecord.image = imageBlobRef;\n }\n\n const hypercertValidation = validate(hypercertRecord, HYPERCERT_COLLECTIONS.CLAIM, \"main\", false);\n if (!hypercertValidation.success) {\n throw new ValidationError(`Invalid hypercert record: ${hypercertValidation.error?.message}`);\n }\n\n const hypercertResult = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CLAIM,\n record: hypercertRecord,\n });\n\n if (!hypercertResult.success) {\n throw new NetworkError(\"Failed to create hypercert record\");\n }\n\n const uri = hypercertResult.data.uri;\n const cid = hypercertResult.data.cid;\n this.emit(\"recordCreated\", { uri, cid });\n this.emitProgress(onProgress, {\n name: \"createHypercert\",\n status: \"success\",\n data: { uri },\n });\n\n return { uri, cid };\n }\n\n /**\n * Attaches a location to a hypercert with progress tracking.\n *\n * @param hypercertUri - URI of the hypercert\n * @param location - Location data\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to location URI\n * @internal\n */\n private async attachLocationWithProgress(\n hypercertUri: string,\n location: AttachLocationParams,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<string> {\n this.emitProgress(onProgress, { name: \"attachLocation\", status: \"start\" });\n try {\n const locationResult = await this.attachLocation(hypercertUri, location);\n this.emitProgress(onProgress, {\n name: \"attachLocation\",\n status: \"success\",\n data: { uri: locationResult.uri },\n });\n return locationResult.uri;\n } catch (error) {\n this.emitProgress(onProgress, { name: \"attachLocation\", status: \"error\", error: error as Error });\n this.logger?.warn(`Failed to attach location: ${error instanceof Error ? error.message : \"Unknown\"}`);\n throw error;\n }\n }\n\n /**\n * Creates contribution records with progress tracking.\n *\n * @param hypercertUri - URI of the hypercert\n * @param contributions - Array of contribution data\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to array of contribution URIs\n * @internal\n */\n private async createContributionsWithProgress(\n hypercertUri: string,\n contributions: Array<{ contributors: string[]; role: string; description?: string }>,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<string[]> {\n this.emitProgress(onProgress, { name: \"createContributions\", status: \"start\" });\n try {\n const contributionUris: string[] = [];\n for (const contrib of contributions) {\n const contribResult = await this.addContribution({\n hypercertUri,\n contributors: contrib.contributors,\n role: contrib.role,\n description: contrib.description,\n });\n contributionUris.push(contribResult.uri);\n }\n this.emitProgress(onProgress, {\n name: \"createContributions\",\n status: \"success\",\n data: { count: contributionUris.length },\n });\n return contributionUris;\n } catch (error) {\n this.emitProgress(onProgress, { name: \"createContributions\", status: \"error\", error: error as Error });\n this.logger?.warn(`Failed to create contributions: ${error instanceof Error ? error.message : \"Unknown\"}`);\n throw error;\n }\n }\n\n /**\n * Creates evidence records with progress tracking.\n *\n * @param hypercertUri - URI of the hypercert\n * @param evidenceItems - Array of evidence data (without subjectUri)\n * @param onProgress - Optional progress callback\n * @returns Promise resolving to array of evidence URIs\n * @internal\n */\n private async createEvidenceWithProgress(\n hypercertUri: string,\n evidenceItems: Array<Omit<CreateHypercertEvidenceParams, \"subjectUri\">>,\n onProgress?: (step: ProgressStep) => void,\n ): Promise<string[]> {\n this.emitProgress(onProgress, { name: \"addEvidence\", status: \"start\" });\n try {\n const evidenceUris = await Promise.all(\n evidenceItems.map((evidence) =>\n this.addEvidence({\n subjectUri: hypercertUri,\n ...evidence,\n } as CreateHypercertEvidenceParams).then((result) => result.uri),\n ),\n );\n this.emitProgress(onProgress, {\n name: \"addEvidence\",\n status: \"success\",\n data: { count: evidenceUris.length },\n });\n return evidenceUris;\n } catch (error) {\n this.emitProgress(onProgress, { name: \"addEvidence\", status: \"error\", error: error as Error });\n this.logger?.warn(`Failed to create evidence: ${error instanceof Error ? error.message : \"Unknown\"}`);\n throw error;\n }\n }\n\n /**\n * Creates a new hypercert with all related records.\n *\n * This method orchestrates the creation of a hypercert and its associated\n * records in the correct order:\n *\n * 1. Upload image (if provided)\n * 2. Create rights record\n * 3. Create hypercert record (referencing rights)\n * 4. Attach location (if provided)\n * 5. Create contributions (if provided)\n *\n * @param params - Creation parameters (see {@link CreateHypercertParams})\n * @returns Promise resolving to URIs and CIDs of all created records\n * @throws {@link ValidationError} if any record fails validation\n * @throws {@link NetworkError} if any API call fails\n *\n * @remarks\n * The operation is not atomic - if a later step fails, earlier records\n * will still exist. The result object will contain URIs for all\n * successfully created records.\n *\n * **Progress Steps**:\n * - `uploadImage`: Image blob upload\n * - `createRights`: Rights record creation\n * - `createHypercert`: Main hypercert record creation\n * - `attachLocation`: Location record creation\n * - `createContributions`: Contribution records creation\n * - `addEvidence`: Evidence records creation\n *\n * @example Minimal hypercert\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"My Impact\",\n * description: \"Description of impact work\",\n * workScope: \"Education\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-06-30\",\n * rights: {\n * name: \"Attribution\",\n * type: \"license\",\n * description: \"CC-BY-4.0\",\n * },\n * });\n * ```\n *\n * @example Full hypercert with all options\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"Reforestation Project\",\n * description: \"Planted 10,000 trees...\",\n * shortDescription: \"10K trees planted\",\n * workScope: \"Environment\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: { name: \"Open\", type: \"impact\", description: \"...\" },\n * image: coverImageBlob,\n * location: { value: \"Amazon, Brazil\", name: \"Amazon Basin\" },\n * contributions: [\n * { contributors: [\"did:plc:org1\"], role: \"coordinator\" },\n * { contributors: [\"did:plc:org2\"], role: \"implementer\" },\n * ],\n * evidence: [{ uri: \"https://...\", description: \"Satellite data\" }],\n * onProgress: console.log,\n * });\n * ```\n */\n async create(params: CreateHypercertParams): Promise<CreateHypercertResult> {\n const createdAt = new Date().toISOString();\n const result: CreateHypercertResult = {\n hypercertUri: \"\",\n rightsUri: \"\",\n hypercertCid: \"\",\n rightsCid: \"\",\n };\n\n try {\n // Step 1: Upload image if provided\n const imageBlobRef = params.image ? await this.uploadImageBlob(params.image, params.onProgress) : undefined;\n\n // Step 2: Create rights record\n const { uri: rightsUri, cid: rightsCid } = await this.createRightsRecord(\n params.rights,\n createdAt,\n params.onProgress,\n );\n result.rightsUri = rightsUri;\n result.rightsCid = rightsCid;\n\n // Step 3: Create hypercert record\n const { uri: hypercertUri, cid: hypercertCid } = await this.createHypercertRecord(\n params,\n rightsUri,\n rightsCid,\n imageBlobRef,\n createdAt,\n params.onProgress,\n );\n result.hypercertUri = hypercertUri;\n result.hypercertCid = hypercertCid;\n\n // Step 4: Attach location if provided\n if (params.location) {\n try {\n result.locationUri = await this.attachLocationWithProgress(hypercertUri, params.location, params.onProgress);\n } catch {\n // Error already logged and progress emitted\n }\n }\n\n // Step 5: Create contributions if provided\n if (params.contributions && params.contributions.length > 0) {\n try {\n result.contributionUris = await this.createContributionsWithProgress(\n hypercertUri,\n params.contributions,\n params.onProgress,\n );\n } catch {\n // Error already logged and progress emitted\n }\n }\n\n // Step 6: Add evidence records if provided\n if (params.evidence && params.evidence.length > 0) {\n try {\n result.evidenceUris = await this.createEvidenceWithProgress(hypercertUri, params.evidence, params.onProgress);\n } catch {\n // Error already logged and progress emitted\n }\n }\n\n return result;\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Updates an existing hypercert record.\n *\n * @param params - Update parameters\n * @param params.uri - AT-URI of the hypercert to update\n * @param params.updates - Partial record with fields to update\n * @param params.image - New image blob, `null` to remove, `undefined` to keep existing\n * @returns Promise resolving to update result\n * @throws {@link ValidationError} if the URI format is invalid or record fails validation\n * @throws {@link NetworkError} if the update fails\n *\n * @remarks\n * This is a partial update - only specified fields are changed.\n * The `createdAt` and `rights` fields cannot be changed.\n *\n * @example Update title and description\n * ```typescript\n * await repo.hypercerts.update({\n * uri: \"at://did:plc:abc/org.hypercerts.hypercert/xyz\",\n * updates: {\n * title: \"Updated Title\",\n * description: \"New description\",\n * },\n * });\n * ```\n *\n * @example Update with new image\n * ```typescript\n * await repo.hypercerts.update({\n * uri: hypercertUri,\n * updates: { title: \"New Title\" },\n * image: newImageBlob,\n * });\n * ```\n *\n * @example Remove image\n * ```typescript\n * await repo.hypercerts.update({\n * uri: hypercertUri,\n * updates: {},\n * image: null, // Explicitly remove image\n * });\n * ```\n */\n async update(params: {\n uri: string;\n updates: Partial<Omit<HypercertClaim, \"$type\" | \"createdAt\" | \"rights\">>;\n image?: Blob | null;\n }): Promise<UpdateResult> {\n try {\n const uriMatch = params.uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${params.uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n // The existing record comes from ATProto, use it directly\n // TypeScript ensures type safety through the HypercertClaim interface\n const existingRecord = existing.data.value as HypercertClaim;\n\n const recordForUpdate: Record<string, unknown> = {\n ...existingRecord,\n ...params.updates,\n createdAt: existingRecord.createdAt,\n rights: existingRecord.rights,\n };\n\n // Handle image update\n delete (recordForUpdate as { image?: unknown }).image;\n if (params.image !== undefined) {\n if (params.image === null) {\n // Remove image\n } else {\n const arrayBuffer = await params.image.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.image.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n recordForUpdate.image = {\n $type: \"blob\",\n ref: uploadResult.data.blob.ref,\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n }\n }\n } else if (existingRecord.image) {\n // Preserve existing image\n recordForUpdate.image = existingRecord.image;\n }\n\n const validation = validate(recordForUpdate, collection, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid hypercert record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection,\n rkey,\n record: recordForUpdate,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update hypercert\");\n }\n\n this.emit(\"recordUpdated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to update hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a hypercert by its AT-URI.\n *\n * @param uri - AT-URI of the hypercert (e.g., \"at://did:plc:abc/org.hypercerts.hypercert/xyz\")\n * @returns Promise resolving to hypercert URI, CID, and parsed record\n * @throws {@link ValidationError} if the URI format is invalid or record doesn't match schema\n * @throws {@link NetworkError} if the record cannot be fetched\n *\n * @example\n * ```typescript\n * const { uri, cid, record } = await repo.hypercerts.get(hypercertUri);\n * console.log(`${record.title}: ${record.description}`);\n * ```\n */\n async get(uri: string): Promise<{ uri: string; cid: string; record: HypercertClaim }> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get hypercert\");\n }\n\n return {\n uri: result.data.uri,\n cid: result.data.cid ?? \"\",\n record: result.data.value as HypercertClaim,\n };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Lists hypercerts in the repository with pagination.\n *\n * @param params - Optional pagination parameters\n * @returns Promise resolving to paginated list of hypercerts\n * @throws {@link NetworkError} if the list operation fails\n *\n * @example\n * ```typescript\n * // Get first page\n * const { records, cursor } = await repo.hypercerts.list({ limit: 20 });\n *\n * // Get next page\n * if (cursor) {\n * const nextPage = await repo.hypercerts.list({ limit: 20, cursor });\n * }\n * ```\n */\n async list(params?: ListParams): Promise<PaginatedList<{ uri: string; cid: string; record: HypercertClaim }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CLAIM,\n limit: params?.limit,\n cursor: params?.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list hypercerts\");\n }\n\n return {\n records:\n result.data.records?.map((r) => ({\n uri: r.uri,\n cid: r.cid,\n record: r.value as HypercertClaim,\n })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to list hypercerts: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Deletes a hypercert record.\n *\n * @param uri - AT-URI of the hypercert to delete\n * @throws {@link ValidationError} if the URI format is invalid\n * @throws {@link NetworkError} if the deletion fails\n *\n * @remarks\n * This only deletes the hypercert record itself. Related records\n * (rights, locations, contributions) are not automatically deleted.\n *\n * @example\n * ```typescript\n * await repo.hypercerts.delete(hypercertUri);\n * ```\n */\n async delete(uri: string): Promise<void> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.deleteRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to delete hypercert\");\n }\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to delete hypercert: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Attaches a location to an existing hypercert.\n *\n * @param hypercertUri - AT-URI of the hypercert to attach location to\n * @param location - Location data\n * @param location.value - Location value (address, coordinates, or description)\n * @param location.name - Optional human-readable name\n * @param location.description - Optional description\n * @param location.srs - Spatial Reference System (e.g., \"EPSG:4326\")\n * @param location.geojson - Optional GeoJSON blob for precise boundaries\n * @returns Promise resolving to location record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example Simple location\n * ```typescript\n * await repo.hypercerts.attachLocation(hypercertUri, {\n * value: \"San Francisco, CA\",\n * name: \"SF Bay Area\",\n * srs: \"EPSG:4326\",\n * });\n * ```\n *\n * @example Location with GeoJSON\n * ```typescript\n * const geojsonBlob = new Blob([JSON.stringify(geojson)], {\n * type: \"application/geo+json\"\n * });\n *\n * await repo.hypercerts.attachLocation(hypercertUri, {\n * value: \"Custom Region\",\n * srs: \"EPSG:4326\",\n * geojson: geojsonBlob,\n * });\n * ```\n */\n async attachLocation(hypercertUri: string, location: AttachLocationParams): Promise<CreateResult> {\n try {\n if (!location.srs) {\n throw new ValidationError(\n \"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.\",\n );\n }\n\n // Validate that hypercert exists (unused but confirms hypercert is valid)\n await this.get(hypercertUri);\n const createdAt = new Date().toISOString();\n\n const locationData = await this.resolveUriOrBlob(location.location, \"application/geo+json\");\n\n const locationRecord: HypercertLocation = {\n $type: HYPERCERT_COLLECTIONS.LOCATION,\n lpVersion: location.lpVersion || \"1.0\",\n srs: location.srs,\n locationType: location.locationType,\n location: locationData,\n createdAt,\n name: location.name,\n description: location.description,\n };\n\n const validation = validate(locationRecord, HYPERCERT_COLLECTIONS.LOCATION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid location record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.LOCATION,\n record: locationRecord,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to attach location\");\n }\n\n await this.update({\n uri: hypercertUri,\n updates: {\n location: {\n $type: \"com.atproto.repo.strongRef\",\n uri: result.data.uri,\n cid: result.data.cid,\n },\n },\n });\n\n this.emit(\"locationAttached\", { uri: result.data.uri, cid: result.data.cid, hypercertUri });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to attach location: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Generic helper to resolve string | Blob into a URI or blob reference.\n *\n * @param content - Either a URI string or a Blob to upload\n * @param fallbackMimeType - MIME type to use if Blob.type is empty\n * @returns Promise resolving to either a URI ref or blob ref union type\n * @internal\n */\n private async resolveUriOrBlob(content: string | Blob, fallbackMimeType: string) {\n if (typeof content === \"string\") {\n return {\n $type: \"org.hypercerts.defs#uri\" as const,\n uri: content,\n };\n } else {\n const uploadedBlob = await this.handleBlobUpload(content, fallbackMimeType);\n return {\n $type: \"org.hypercerts.defs#smallBlob\" as const,\n blob: uploadedBlob,\n };\n }\n }\n\n /**\n * Adds evidence to any subject via the subject ref.\n *\n * @param evidence - HypercertEvidenceInput\n * @returns Promise resolving to update result\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addEvidence({\n * subjectUri: \"at://did:plc:u7h3dstby64di67bxaotzxcz/org.hypercerts.claim.activity/3mbvv5d7ixh2g\"\n * content: Blob,\n * title: \"Meeting Notes\",\n * shortDescription: \"Meetings notes from the 3rd of December 2025\",\n * description: \"The meeting with the board of directors and audience on 2025 in regards to the ecological landscape\",\n * relationType: \"supports\",\n * })\n * ```\n */\n async addEvidence(evidence: CreateHypercertEvidenceParams): Promise<UpdateResult> {\n try {\n const { subjectUri, content, ...rest } = evidence;\n const subject = await this.get(subjectUri);\n const createdAt = new Date().toISOString();\n\n const evidenceContent = await this.resolveUriOrBlob(content, \"application/octet-stream\");\n const evidenceRecord: HypercertEvidence = {\n ...rest,\n $type: HYPERCERT_COLLECTIONS.EVIDENCE,\n createdAt,\n content: evidenceContent,\n subject: { uri: subject.uri, cid: subject.cid },\n };\n const validation = validate(evidenceRecord, HYPERCERT_COLLECTIONS.EVIDENCE, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid evidence record: ${validation.error?.message}`);\n }\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.EVIDENCE,\n record: evidenceRecord,\n });\n if (!result.success) {\n throw new NetworkError(`Failed to add evidence`);\n }\n this.emit(\"evidenceAdded\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add evidence: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a contribution details record.\n *\n * This creates a standalone contribution details record that can be referenced\n * from an activity's `contributors` array via a strong reference.\n *\n * @param params - Contribution parameters\n * @param params.hypercertUri - Optional hypercert (unused, kept for backward compatibility)\n * @param params.contributors - Array of contributor DIDs (unused, kept for backward compatibility)\n * @param params.role - Role of the contributor (e.g., \"coordinator\", \"implementer\")\n * @param params.description - Optional description of the contribution\n * @returns Promise resolving to contribution details record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @remarks\n * In the new lexicon structure, contributions are stored differently:\n * - Use `contributionDetails` for detailed contribution records (role, description, timeframe)\n * - Use `contributorInformation` for contributor profiles (identifier, displayName, image)\n * - Reference these from the activity's `contributors` array using strong refs\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addContribution({\n * role: \"implementer\",\n * description: \"On-ground implementation team\",\n * });\n * ```\n */\n async addContribution(params: {\n hypercertUri?: string;\n contributors: string[];\n role: string;\n description?: string;\n }): Promise<CreateResult> {\n try {\n const createdAt = new Date().toISOString();\n const contributionRecord: HypercertContributionDetails = {\n $type: HYPERCERT_COLLECTIONS.CONTRIBUTION_DETAILS,\n role: params.role,\n createdAt,\n contributionDescription: params.description,\n };\n\n const validation = validate(contributionRecord, HYPERCERT_COLLECTIONS.CONTRIBUTION_DETAILS, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid contribution details record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.CONTRIBUTION_DETAILS,\n record: contributionRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create contribution details\");\n }\n\n this.emit(\"contributionCreated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to add contribution: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Creates a measurement record for a hypercert.\n *\n * Measurements quantify the impact claimed in a hypercert with\n * specific metrics and values.\n *\n * @param params - Measurement parameters\n * @param params.hypercertUri - AT-URI of the hypercert being measured\n * @param params.measurers - DIDs of entities who performed the measurement\n * @param params.metric - Name of the metric (e.g., \"CO2 Reduced\", \"Trees Planted\")\n * @param params.value - Measured value with units (e.g., \"100 tons\", \"10000\")\n * @param params.methodUri - Optional URI describing the measurement methodology\n * @param params.evidenceUris - Optional URIs to supporting evidence\n * @returns Promise resolving to measurement record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addMeasurement({\n * hypercertUri: hypercertUri,\n * measurers: [\"did:plc:auditor\"],\n * metric: \"Carbon Offset\",\n * value: \"150 tons CO2e\",\n * methodUri: \"https://example.com/methodology\",\n * evidenceUris: [\"https://example.com/audit-report\"],\n * });\n * ```\n */\n async addMeasurement(params: {\n hypercertUri: string;\n measurers: string[];\n metric: string;\n value: string;\n methodUri?: string;\n evidenceUris?: string[];\n }): Promise<CreateResult> {\n try {\n const hypercert = await this.get(params.hypercertUri);\n const createdAt = new Date().toISOString();\n\n const measurementRecord: HypercertMeasurement = {\n $type: HYPERCERT_COLLECTIONS.MEASUREMENT,\n hypercert: { uri: hypercert.uri, cid: hypercert.cid },\n measurers: params.measurers,\n metric: params.metric,\n value: params.value,\n createdAt,\n measurementMethodURI: params.methodUri,\n evidenceURI: params.evidenceUris,\n };\n\n const validation = validate(measurementRecord, HYPERCERT_COLLECTIONS.MEASUREMENT, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid measurement record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.MEASUREMENT,\n record: measurementRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create measurement\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add measurement: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates an evaluation record for a hypercert or other subject.\n *\n * Evaluations provide third-party assessments of impact claims.\n *\n * @param params - Evaluation parameters\n * @param params.subjectUri - AT-URI of the record being evaluated\n * @param params.evaluators - DIDs of evaluating entities\n * @param params.summary - Summary of the evaluation findings\n * @returns Promise resolving to evaluation record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * await repo.hypercerts.addEvaluation({\n * subjectUri: hypercertUri,\n * evaluators: [\"did:plc:evaluator-org\"],\n * summary: \"Verified impact claims through site visit and data analysis\",\n * });\n * ```\n */\n async addEvaluation(params: { subjectUri: string; evaluators: string[]; summary: string }): Promise<CreateResult> {\n try {\n const subject = await this.get(params.subjectUri);\n const createdAt = new Date().toISOString();\n\n const evaluationRecord: HypercertEvaluation = {\n $type: HYPERCERT_COLLECTIONS.EVALUATION,\n subject: { uri: subject.uri, cid: subject.cid },\n evaluators: params.evaluators,\n summary: params.summary,\n createdAt,\n };\n\n const validation = validate(evaluationRecord, HYPERCERT_COLLECTIONS.EVALUATION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid evaluation record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.EVALUATION,\n record: evaluationRecord as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create evaluation\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to add evaluation: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Creates a collection of hypercerts.\n *\n * Collections group related hypercerts with optional weights\n * for relative importance.\n *\n * @param params - Collection parameters\n * @param params.title - Collection title\n * @param params.claims - Array of hypercert references with weights\n * @param params.shortDescription - Optional short description\n * @param params.banner - Optional cover image blob\n * @returns Promise resolving to collection record URI and CID\n * @throws {@link ValidationError} if validation fails\n * @throws {@link NetworkError} if the operation fails\n *\n * @example\n * ```typescript\n * const collection = await repo.hypercerts.createCollection({\n * title: \"Climate Projects 2024\",\n * shortDescription: \"Our climate impact portfolio\",\n * claims: [\n * { uri: hypercert1Uri, cid: hypercert1Cid, weight: \"0.5\" },\n * { uri: hypercert2Uri, cid: hypercert2Cid, weight: \"0.3\" },\n * { uri: hypercert3Uri, cid: hypercert3Cid, weight: \"0.2\" },\n * ],\n * banner: coverImageBlob,\n * });\n * ```\n */\n async createCollection(params: {\n title: string;\n claims: Array<{ uri: string; cid: string; weight: string }>;\n shortDescription?: string;\n banner?: Blob;\n }): Promise<CreateResult> {\n try {\n const createdAt = new Date().toISOString();\n\n let bannerRef: JsonBlobRef | undefined;\n if (params.banner) {\n const arrayBuffer = await params.banner.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.banner.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n bannerRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n }\n }\n\n const collectionRecord: Record<string, unknown> = {\n $type: HYPERCERT_COLLECTIONS.COLLECTION,\n title: params.title,\n claims: params.claims.map((c) => ({ claim: { uri: c.uri, cid: c.cid }, weight: c.weight })),\n createdAt,\n };\n\n if (params.shortDescription) {\n collectionRecord.shortDescription = params.shortDescription;\n }\n\n if (bannerRef) {\n collectionRecord.banner = bannerRef;\n }\n\n const validation = validate(collectionRecord, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid collection record: ${validation.error?.message}`);\n }\n\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n record: collectionRecord,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create collection\");\n }\n\n this.emit(\"collectionCreated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to create collection: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Gets a collection by its AT-URI.\n *\n * @param uri - AT-URI of the collection\n * @returns Promise resolving to collection URI, CID, and parsed record\n * @throws {@link ValidationError} if the URI format is invalid or record doesn't match schema\n * @throws {@link NetworkError} if the record cannot be fetched\n *\n * @example\n * ```typescript\n * const { record } = await repo.hypercerts.getCollection(collectionUri);\n * console.log(`Collection: ${record.title}`);\n * console.log(`Contains ${record.claims.length} hypercerts`);\n * ```\n */\n async getCollection(uri: string): Promise<{ uri: string; cid: string; record: HypercertCollection }> {\n try {\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get collection\");\n }\n\n // Validate with lexicon registry (more lenient - doesn't require $type)\n const validation = validate(result.data.value, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid collection record format: ${validation.error?.message}`);\n }\n\n return {\n uri: result.data.uri,\n cid: result.data.cid ?? \"\",\n record: result.data.value as HypercertCollection,\n };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get collection: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Lists collections in the repository with pagination.\n *\n * @param params - Optional pagination parameters\n * @returns Promise resolving to paginated list of collections\n * @throws {@link NetworkError} if the list operation fails\n *\n * @example\n * ```typescript\n * const { records } = await repo.hypercerts.listCollections();\n * for (const { record } of records) {\n * console.log(`${record.title}: ${record.claims.length} claims`);\n * }\n * ```\n */\n async listCollections(\n params?: ListParams,\n ): Promise<PaginatedList<{ uri: string; cid: string; record: HypercertCollection }>> {\n try {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n limit: params?.limit,\n cursor: params?.cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list collections\");\n }\n\n return {\n records:\n result.data.records?.map((r) => ({\n uri: r.uri,\n cid: r.cid,\n record: r.value as HypercertCollection,\n })) || [],\n cursor: result.data.cursor ?? undefined,\n };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(\n `Failed to list collections: ${error instanceof Error ? error.message : \"Unknown\"}`,\n error,\n );\n }\n }\n\n /**\n * Creates a new project that organizes multiple hypercert activities.\n *\n * Projects are now implemented as collections with `type='project'`.\n *\n * @param params - Project creation parameters\n * @returns Promise resolving to created project URI and CID\n *\n * @example\n * ```typescript\n * const result = await repo.hypercerts.createProject({\n * title: \"Climate Impact 2024\",\n * shortDescription: \"Year-long climate initiative\",\n * activities: [\n * { uri: activity1Uri, cid: activity1Cid, weight: \"0.6\" },\n * { uri: activity2Uri, cid: activity2Cid, weight: \"0.4\" }\n * ]\n * });\n * console.log(`Created project: ${result.uri}`);\n * ```\n */\n async createProject(params: {\n title: string;\n shortDescription: string;\n description?: unknown;\n avatar?: Blob;\n banner?: Blob;\n activities?: Array<{ uri: string; cid: string; weight: string }>;\n }): Promise<CreateResult> {\n try {\n const createdAt = new Date().toISOString();\n\n // Upload avatar blob if provided\n let avatarRef: JsonBlobRef | undefined;\n if (params.avatar) {\n const arrayBuffer = await params.avatar.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.avatar.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n avatarRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n } else {\n throw new NetworkError(\"Failed to upload avatar image\");\n }\n }\n\n // Upload banner blob if provided\n let bannerRef: JsonBlobRef | undefined;\n if (params.banner) {\n const arrayBuffer = await params.banner.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: params.banner.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n bannerRef = {\n $type: \"blob\",\n ref: { $link: uploadResult.data.blob.ref.toString() },\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n } else {\n throw new NetworkError(\"Failed to upload banner image\");\n }\n }\n\n // Build project record as a collection with type='project'\n // Collections require 'items' array, so we map activities to items\n const items =\n params.activities?.map((a) => ({\n itemIdentifier: { uri: a.uri, cid: a.cid },\n itemWeight: a.weight,\n })) || [];\n\n const projectRecord: Record<string, unknown> = {\n $type: HYPERCERT_COLLECTIONS.COLLECTION,\n type: \"project\",\n title: params.title,\n shortDescription: params.shortDescription,\n items,\n createdAt,\n };\n\n // Add optional fields\n if (params.description) {\n projectRecord.description = params.description;\n }\n\n if (avatarRef) {\n projectRecord.avatar = avatarRef;\n }\n\n if (bannerRef) {\n projectRecord.banner = bannerRef;\n }\n\n // Validate against collection lexicon\n const validation = validate(projectRecord, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid project record: ${validation.error?.message}`);\n }\n\n // Create record\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n record: projectRecord,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create project\");\n }\n\n // Emit event\n this.emit(\"projectCreated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to create project: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Gets a project by its AT-URI.\n *\n * Projects are collections with `type='project'`.\n *\n * @param uri - AT-URI of the project\n * @returns Promise resolving to project data (as collection)\n *\n * @example\n * ```typescript\n * const { record } = await repo.hypercerts.getProject(projectUri);\n * console.log(`${record.title}: ${record.items?.length || 0} activities`);\n * ```\n */\n async getProject(uri: string): Promise<{ uri: string; cid: string; record: HypercertCollection }> {\n try {\n // Parse URI\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n // Fetch record\n const result = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to get project\");\n }\n\n // Validate as collection\n const validation = validate(result.data.value, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid project record format: ${validation.error?.message}`);\n }\n\n // Verify it's actually a project (collection with type='project')\n const record = result.data.value as HypercertCollection;\n if (record.type !== \"project\") {\n throw new ValidationError(`Record is not a project (type='${record.type}')`);\n }\n\n return {\n uri: result.data.uri,\n cid: result.data.cid ?? \"\",\n record,\n };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to get project: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Lists all projects with optional pagination.\n *\n * Projects are collections with `type='project'`. This method filters\n * collections to only return those with type='project'.\n *\n * @param params - Optional pagination parameters\n * @returns Promise resolving to paginated list of projects\n *\n * @example\n * ```typescript\n * const { records } = await repo.hypercerts.listProjects();\n * for (const { record } of records) {\n * console.log(`${record.title}: ${record.shortDescription}`);\n * }\n * ```\n */\n async listProjects(\n params?: ListParams,\n ): Promise<PaginatedList<{ uri: string; cid: string; record: HypercertCollection }>> {\n try {\n const limit = params?.limit;\n let cursor = params?.cursor;\n const allRecords: Array<{ uri: string; cid: string; record: HypercertCollection }> = [];\n\n // Loop-fetch until we have enough projects or no more cursor\n while (!cursor || allRecords.length < (limit ?? Infinity)) {\n const result = await this.agent.com.atproto.repo.listRecords({\n repo: this.repoDid,\n collection: HYPERCERT_COLLECTIONS.COLLECTION,\n limit: limit ?? 50,\n cursor,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to list projects\");\n }\n\n // Filter and collect project records\n for (const r of result.data.records ?? []) {\n const record = r.value as HypercertCollection;\n if (record.type === \"project\") {\n allRecords.push({ uri: r.uri, cid: r.cid, record });\n }\n // Stop if we've collected enough\n if (limit && allRecords.length >= limit) break;\n }\n\n // Update cursor; break if no more pages\n cursor = result.data.cursor;\n if (!cursor) break;\n }\n\n return { records: allRecords, cursor };\n } catch (error) {\n if (error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to list projects: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Updates an existing project.\n *\n * Projects are collections with `type='project'`.\n *\n * @param uri - AT-URI of the project to update\n * @param updates - Fields to update\n * @returns Promise resolving to updated project URI and CID\n *\n * @example\n * ```typescript\n * const result = await repo.hypercerts.updateProject(projectUri, {\n * title: \"Updated Project Title\",\n * shortDescription: \"New description\"\n * });\n * ```\n */\n async updateProject(\n uri: string,\n updates: {\n title?: string;\n shortDescription?: string;\n description?: unknown;\n avatar?: Blob | null;\n banner?: Blob | null;\n activities?: Array<{ uri: string; cid: string; weight: string }>;\n },\n ): Promise<UpdateResult> {\n try {\n // Parse URI and fetch existing record\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!existing.success) {\n throw new NetworkError(`Project not found: ${uri}`);\n }\n\n const existingRecord = existing.data.value as HypercertCollection;\n\n // Verify it's actually a project\n if (existingRecord.type !== \"project\") {\n throw new ValidationError(`Record is not a project (type='${existingRecord.type}')`);\n }\n\n // Merge updates with existing record\n const recordForUpdate: Record<string, unknown> = {\n ...existingRecord,\n // MUST preserve type, createdAt, and items structure\n type: \"project\",\n createdAt: existingRecord.createdAt,\n };\n\n // Apply simple field updates\n if (updates.title !== undefined) recordForUpdate.title = updates.title;\n if (updates.shortDescription !== undefined) recordForUpdate.shortDescription = updates.shortDescription;\n if (updates.description !== undefined) recordForUpdate.description = updates.description;\n\n // Handle avatar update with three-way logic\n delete (recordForUpdate as { avatar?: unknown }).avatar;\n if (updates.avatar !== undefined) {\n if (updates.avatar === null) {\n // Remove avatar\n } else {\n const arrayBuffer = await updates.avatar.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: updates.avatar.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n recordForUpdate.avatar = {\n $type: \"blob\",\n ref: uploadResult.data.blob.ref,\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n } else {\n throw new NetworkError(\"Failed to upload avatar image\");\n }\n }\n } else if (existingRecord.avatar) {\n recordForUpdate.avatar = existingRecord.avatar;\n }\n\n // Handle banner update\n delete (recordForUpdate as { banner?: unknown }).banner;\n if (updates.banner !== undefined) {\n if (updates.banner === null) {\n // Remove banner\n } else {\n const arrayBuffer = await updates.banner.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n const uploadResult = await this.agent.com.atproto.repo.uploadBlob(uint8Array, {\n encoding: updates.banner.type || \"image/jpeg\",\n });\n if (uploadResult.success) {\n recordForUpdate.banner = {\n $type: \"blob\",\n ref: uploadResult.data.blob.ref,\n mimeType: uploadResult.data.blob.mimeType,\n size: uploadResult.data.blob.size,\n };\n } else {\n throw new NetworkError(\"Failed to upload banner image\");\n }\n }\n } else if (existingRecord.banner) {\n recordForUpdate.banner = existingRecord.banner;\n }\n\n // Transform activities to items array\n if (updates.activities) {\n recordForUpdate.items = updates.activities.map((a) => ({\n itemIdentifier: { uri: a.uri, cid: a.cid },\n itemWeight: a.weight,\n }));\n } else {\n // Preserve existing items\n recordForUpdate.items = existingRecord.items;\n }\n\n // Validate merged record\n const validation = validate(recordForUpdate, HYPERCERT_COLLECTIONS.COLLECTION, \"main\", false);\n if (!validation.success) {\n throw new ValidationError(`Invalid project record: ${validation.error?.message}`);\n }\n\n // Update record\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection,\n rkey,\n record: recordForUpdate,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update project\");\n }\n\n // Emit event\n this.emit(\"projectUpdated\", { uri: result.data.uri, cid: result.data.cid });\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to update project: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n\n /**\n * Deletes a project.\n *\n * Projects are collections with `type='project'`.\n *\n * @param uri - AT-URI of the project to delete\n *\n * @example\n * ```typescript\n * await repo.hypercerts.deleteProject(projectUri);\n * console.log(\"Project deleted\");\n * ```\n */\n async deleteProject(uri: string): Promise<void> {\n try {\n // Parse URI\n const uriMatch = uri.match(/^at:\\/\\/([^/]+)\\/([^/]+)\\/(.+)$/);\n if (!uriMatch) {\n throw new ValidationError(`Invalid URI format: ${uri}`);\n }\n const [, , collection, rkey] = uriMatch;\n\n // Verify it's actually a project before deleting\n const existing = await this.agent.com.atproto.repo.getRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (existing.success) {\n const record = existing.data.value as HypercertCollection;\n if (record.type !== \"project\") {\n throw new ValidationError(`Record is not a project (type='${record.type}')`);\n }\n }\n\n // Delete record\n const result = await this.agent.com.atproto.repo.deleteRecord({\n repo: this.repoDid,\n collection,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to delete project\");\n }\n\n // Emit event\n this.emit(\"projectDeleted\", { uri });\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) throw error;\n throw new NetworkError(`Failed to delete project: ${error instanceof Error ? error.message : \"Unknown\"}`, error);\n }\n }\n}\n","/**\n * CollaboratorOperationsImpl - SDS collaborator management operations.\n *\n * This module provides the implementation for managing collaborator\n * access on Shared Data Server (SDS) repositories.\n *\n * @packageDocumentation\n */\n\nimport { NetworkError } from \"../core/errors.js\";\nimport type { CollaboratorPermissions, Session } from \"../core/types.js\";\nimport type { CollaboratorOperations, GrantAccessParams } from \"./interfaces.js\";\nimport type { RepositoryAccessGrant, RepositoryRole } from \"./types.js\";\n\n/**\n * Implementation of collaborator operations for SDS access control.\n *\n * This class manages access permissions for shared repositories on\n * Shared Data Servers (SDS). It provides role-based access control\n * with predefined permission sets.\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.collaborators} on an SDS-connected repository.\n *\n * **Role Hierarchy**:\n * - `viewer`: Read-only access\n * - `editor`: Read + Create + Update\n * - `admin`: All permissions except ownership transfer\n * - `owner`: Full control including ownership management\n *\n * **SDS API Endpoints Used**:\n * - `com.sds.repo.grantAccess`: Grant access to a user\n * - `com.sds.repo.revokeAccess`: Revoke access from a user\n * - `com.sds.repo.listCollaborators`: List all collaborators\n * - `com.sds.repo.getPermissions`: Get current user's permissions\n * - `com.sds.repo.transferOwnership`: Transfer repository ownership\n *\n * @example\n * ```typescript\n * // Get SDS repository\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Grant editor access\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:new-user\",\n * role: \"editor\",\n * });\n *\n * // List all collaborators\n * const collaborators = await sdsRepo.collaborators.list();\n *\n * // Check specific user\n * const hasAccess = await sdsRepo.collaborators.hasAccess(\"did:plc:someone\");\n * const role = await sdsRepo.collaborators.getRole(\"did:plc:someone\");\n * ```\n *\n * @internal\n */\nexport class CollaboratorOperationsImpl implements CollaboratorOperations {\n /**\n * Creates a new CollaboratorOperationsImpl.\n *\n * @param session - Authenticated OAuth session with fetchHandler\n * @param repoDid - DID of the repository to manage\n * @param serverUrl - SDS server URL\n *\n * @internal\n */\n constructor(\n private session: Session,\n private repoDid: string,\n private serverUrl: string,\n ) {}\n\n /**\n * Converts a role to its corresponding permissions object.\n *\n * @param role - The role to convert\n * @returns Permission flags for the role\n * @internal\n */\n private roleToPermissions(role: RepositoryRole): CollaboratorPermissions {\n switch (role) {\n case \"viewer\":\n return { read: true, create: false, update: false, delete: false, admin: false, owner: false };\n case \"editor\":\n return { read: true, create: true, update: true, delete: false, admin: false, owner: false };\n case \"admin\":\n return { read: true, create: true, update: true, delete: true, admin: true, owner: false };\n case \"owner\":\n return { read: true, create: true, update: true, delete: true, admin: true, owner: true };\n }\n }\n\n /**\n * Determines the role from a permissions object.\n *\n * @param permissions - The permissions to analyze\n * @returns The highest role matching the permissions\n * @internal\n */\n private permissionsToRole(permissions: CollaboratorPermissions): RepositoryRole {\n if (permissions.owner) return \"owner\";\n if (permissions.admin) return \"admin\";\n if (permissions.create || permissions.update) return \"editor\";\n return \"viewer\";\n }\n\n /**\n * Normalizes permissions from SDS API format to SDK format.\n *\n * The SDS API returns permissions as an object with boolean flags\n * (e.g., `{ read: true, create: true, update: false, ... }`).\n * This method ensures all expected fields are present with default values.\n *\n * @param permissions - Permissions object from SDS API\n * @returns Normalized permission flags object\n * @internal\n */\n private parsePermissions(permissions: CollaboratorPermissions): CollaboratorPermissions {\n return {\n read: permissions.read ?? false,\n create: permissions.create ?? false,\n update: permissions.update ?? false,\n delete: permissions.delete ?? false,\n admin: permissions.admin ?? false,\n owner: permissions.owner ?? false,\n };\n }\n\n /**\n * Grants repository access to a user.\n *\n * @param params - Grant parameters\n * @param params.userDid - DID of the user to grant access to\n * @param params.role - Role to assign (determines permissions)\n * @throws {@link NetworkError} if the grant operation fails\n *\n * @remarks\n * If the user already has access, their permissions are updated\n * to the new role.\n *\n * @example\n * ```typescript\n * // Grant viewer access\n * await repo.collaborators.grant({\n * userDid: \"did:plc:viewer-user\",\n * role: \"viewer\",\n * });\n *\n * // Upgrade to editor\n * await repo.collaborators.grant({\n * userDid: \"did:plc:viewer-user\",\n * role: \"editor\",\n * });\n * ```\n */\n async grant(params: GrantAccessParams): Promise<void> {\n const permissions = this.roleToPermissions(params.role);\n\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.grantAccess`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n userDid: params.userDid,\n permissions,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to grant access: ${response.statusText}`);\n }\n }\n\n /**\n * Revokes repository access from a user.\n *\n * @param params - Revoke parameters\n * @param params.userDid - DID of the user to revoke access from\n * @throws {@link NetworkError} if the revoke operation fails\n *\n * @remarks\n * - Cannot revoke access from the repository owner\n * - Revoked access is recorded with a `revokedAt` timestamp\n *\n * @example\n * ```typescript\n * await repo.collaborators.revoke({\n * userDid: \"did:plc:former-collaborator\",\n * });\n * ```\n */\n async revoke(params: { userDid: string }): Promise<void> {\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.revokeAccess`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n userDid: params.userDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to revoke access: ${response.statusText}`);\n }\n }\n\n /**\n * Lists all collaborators on the repository.\n *\n * @param params - Optional pagination parameters\n * @param params.limit - Maximum number of results (1-100, default 50)\n * @param params.cursor - Pagination cursor from previous response\n * @returns Promise resolving to collaborators and optional cursor\n * @throws {@link NetworkError} if the list operation fails\n *\n * @remarks\n * The list includes both active and revoked collaborators.\n * Check `revokedAt` to filter active collaborators.\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await repo.collaborators.list({ limit: 10 });\n * console.log(`Found ${page1.collaborators.length} collaborators`);\n *\n * // Get next page if available\n * if (page1.cursor) {\n * const page2 = await repo.collaborators.list({ limit: 10, cursor: page1.cursor });\n * }\n *\n * // Filter active collaborators\n * const active = page1.collaborators.filter(c => !c.revokedAt);\n * ```\n */\n async list(params?: { limit?: number; cursor?: string }): Promise<{\n collaborators: RepositoryAccessGrant[];\n cursor?: string;\n }> {\n const queryParams = new URLSearchParams({\n repo: this.repoDid,\n });\n\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n\n if (params?.cursor) {\n queryParams.set(\"cursor\", params.cursor);\n }\n\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.repo.listCollaborators?${queryParams.toString()}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to list collaborators: ${response.statusText}`);\n }\n\n const data = await response.json();\n const collaborators = (data.collaborators || []).map(\n (c: {\n userDid: string;\n permissions: CollaboratorPermissions; // SDS API returns object with boolean flags\n grantedBy: string;\n grantedAt: string;\n revokedAt?: string;\n }) => {\n const permissions = this.parsePermissions(c.permissions);\n return {\n userDid: c.userDid,\n role: this.permissionsToRole(permissions),\n permissions: permissions,\n grantedBy: c.grantedBy,\n grantedAt: c.grantedAt,\n revokedAt: c.revokedAt,\n };\n },\n );\n\n return {\n collaborators,\n cursor: data.cursor,\n };\n }\n\n /**\n * Checks if a user has any access to the repository.\n *\n * @param userDid - DID of the user to check\n * @returns Promise resolving to `true` if user has active access\n *\n * @remarks\n * Returns `false` if:\n * - User was never granted access\n * - User's access was revoked\n * - The list operation fails (error is suppressed)\n *\n * @example\n * ```typescript\n * if (await repo.collaborators.hasAccess(\"did:plc:someone\")) {\n * console.log(\"User has access\");\n * }\n * ```\n */\n async hasAccess(userDid: string): Promise<boolean> {\n try {\n const { collaborators } = await this.list();\n return collaborators.some((c) => c.userDid === userDid && !c.revokedAt);\n } catch {\n return false;\n }\n }\n\n /**\n * Gets the role assigned to a user.\n *\n * @param userDid - DID of the user to check\n * @returns Promise resolving to the user's role, or `null` if no active access\n *\n * @example\n * ```typescript\n * const role = await repo.collaborators.getRole(\"did:plc:someone\");\n * if (role === \"admin\" || role === \"owner\") {\n * // User can manage other collaborators\n * }\n * ```\n */\n async getRole(userDid: string): Promise<RepositoryRole | null> {\n const { collaborators } = await this.list();\n const collab = collaborators.find((c) => c.userDid === userDid && !c.revokedAt);\n return collab?.role ?? null;\n }\n\n /**\n * Gets the current user's permissions for this repository.\n *\n * @returns Promise resolving to the permission flags\n * @throws {@link NetworkError} if the request fails\n *\n * @remarks\n * This is useful for checking what actions the current user can perform\n * before attempting operations that might fail due to insufficient permissions.\n *\n * @example\n * ```typescript\n * const permissions = await repo.collaborators.getPermissions();\n *\n * if (permissions.admin) {\n * // Show admin UI\n * console.log(\"You can manage collaborators\");\n * }\n *\n * if (permissions.create) {\n * console.log(\"You can create records\");\n * }\n * ```\n *\n * @example Conditional UI rendering\n * ```typescript\n * const permissions = await repo.collaborators.getPermissions();\n *\n * // Show/hide UI elements based on permissions\n * const canEdit = permissions.update;\n * const canDelete = permissions.delete;\n * const isAdmin = permissions.admin;\n * const isOwner = permissions.owner;\n * ```\n */\n async getPermissions(): Promise<CollaboratorPermissions> {\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.repo.getPermissions?repo=${encodeURIComponent(this.repoDid)}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to get permissions: ${response.statusText}`);\n }\n\n const data = await response.json();\n return data.permissions as CollaboratorPermissions;\n }\n\n /**\n * Transfers repository ownership to another user.\n *\n * @param params - Transfer parameters\n * @param params.newOwnerDid - DID of the user to transfer ownership to\n * @throws {@link NetworkError} if the transfer fails\n *\n * @remarks\n * **IMPORTANT**: This action is irreversible. Once ownership is transferred:\n * - The new owner gains full control of the repository\n * - Your role will be changed to admin (or specified role)\n * - You cannot transfer ownership back without the new owner's approval\n *\n * **Requirements**:\n * - You must be the current owner\n * - The new owner must have an existing account\n * - The new owner will be notified of the ownership transfer\n *\n * @example\n * ```typescript\n * // Transfer ownership to another user\n * await repo.collaborators.transferOwnership({\n * newOwnerDid: \"did:plc:new-owner\",\n * });\n *\n * console.log(\"Ownership transferred successfully\");\n * // You are now an admin, not the owner\n * ```\n *\n * @example With confirmation\n * ```typescript\n * const confirmTransfer = await askUser(\n * \"Are you sure you want to transfer ownership? This cannot be undone.\"\n * );\n *\n * if (confirmTransfer) {\n * await repo.collaborators.transferOwnership({\n * newOwnerDid: \"did:plc:new-owner\",\n * });\n * }\n * ```\n */\n async transferOwnership(params: { newOwnerDid: string }): Promise<void> {\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.repo.transferOwnership`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: this.repoDid,\n newOwner: params.newOwnerDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to transfer ownership: ${response.statusText}`);\n }\n }\n}\n","/**\n * OrganizationOperationsImpl - SDS organization management operations.\n *\n * This module provides the implementation for creating and managing\n * organizations on Shared Data Server (SDS) instances.\n *\n * @packageDocumentation\n */\n\nimport { NetworkError, ValidationError } from \"../errors.js\";\nimport type { CollaboratorPermissions, Session } from \"../core/types.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport type { CreateOrganizationParams, OrganizationOperations } from \"./interfaces.js\";\nimport type { OrganizationInfo } from \"./types.js\";\n\n/**\n * Implementation of organization operations for SDS management.\n *\n * Organizations on SDS provide a way to create shared repositories\n * that multiple users can collaborate on. Each organization has:\n *\n * - A unique DID (Decentralized Identifier)\n * - A handle for human-readable identification\n * - An owner and optional collaborators\n * - Its own repository for storing records\n *\n * @remarks\n * This class is typically not instantiated directly. Access it through\n * {@link Repository.organizations} on an SDS-connected repository.\n *\n * **SDS API Endpoints Used**:\n * - `com.sds.organization.create`: Create a new organization\n * - `com.sds.organization.list`: List accessible organizations\n *\n * **Access Types**:\n * - `\"owner\"`: User created or owns the organization\n * - `\"collaborator\"`: User was invited with specific permissions\n *\n * @example\n * ```typescript\n * // Get SDS repository\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Create an organization\n * const org = await sdsRepo.organizations.create({\n * name: \"My Team\",\n * description: \"A team for impact projects\",\n * });\n *\n * // List organizations you have access to\n * const orgs = await sdsRepo.organizations.list();\n *\n * // Get specific organization\n * const orgInfo = await sdsRepo.organizations.get(org.did);\n * ```\n *\n * @internal\n */\nexport class OrganizationOperationsImpl implements OrganizationOperations {\n /**\n * Creates a new OrganizationOperationsImpl.\n *\n * @param session - Authenticated OAuth session with fetchHandler\n * @param _repoDid - DID of the user's repository (reserved for future use)\n * @param serverUrl - SDS server URL\n * @param _logger - Optional logger for debugging (reserved for future use)\n *\n * @internal\n */\n constructor(\n private session: Session,\n private _repoDid: string,\n private serverUrl: string,\n private _logger?: LoggerInterface,\n ) {}\n\n /**\n * Creates a new organization.\n *\n * @param params - Organization parameters\n * @param params.name - Display name for the organization\n * @param params.description - Optional description of the organization's purpose\n * @param params.handle - Optional custom handle. If not provided, one is auto-generated.\n * @returns Promise resolving to the created organization info\n * @throws {@link NetworkError} if organization creation fails\n *\n * @remarks\n * The creating user automatically becomes the owner with full permissions.\n *\n * **Handle Format**: Handles are typically formatted as\n * `{name}.sds.{domain}` (e.g., \"my-team.sds.hypercerts.org\").\n * If you provide a custom handle, it must be unique on the SDS.\n *\n * @example Basic organization\n * ```typescript\n * const org = await repo.organizations.create({\n * name: \"Climate Action Team\",\n * });\n * console.log(`Created org: ${org.did}`);\n * ```\n *\n * @example With description and custom handle\n * ```typescript\n * const org = await repo.organizations.create({\n * name: \"Reforestation Initiative\",\n * description: \"Coordinating tree planting projects worldwide\",\n * handle: \"reforestation\",\n * });\n * ```\n */\n async create(params: CreateOrganizationParams): Promise<OrganizationInfo> {\n const userDid = this.session.did || this.session.sub;\n if (!userDid) {\n throw new NetworkError(\"No authenticated user found\");\n }\n\n if (!params.handlePrefix) {\n throw new ValidationError(\"Missing handlePrefix\");\n }\n if (!params.name) {\n throw new ValidationError(\"Missing name\");\n }\n\n const response = await this.session.fetchHandler(`${this.serverUrl}/xrpc/com.sds.organization.create`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n ...params,\n creatorDid: userDid,\n }),\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to create organization: ${response.statusText}`);\n }\n\n const data = await response.json();\n return {\n did: data.did,\n handle: data.handle,\n name: data.name,\n description: data.description,\n createdAt: data.createdAt || new Date().toISOString(),\n accessType: data.accessType || \"owner\",\n permissions: data.permissions || {\n read: true,\n create: true,\n update: true,\n delete: true,\n admin: true,\n owner: true,\n },\n };\n }\n\n /**\n * Gets an organization by its DID.\n *\n * @param did - The organization's DID\n * @returns Promise resolving to organization info, or `null` if not found\n *\n * @remarks\n * This method searches through the user's accessible organizations.\n * If the organization exists but the user doesn't have access,\n * it will return `null`.\n *\n * @example\n * ```typescript\n * const org = await repo.organizations.get(\"did:plc:org123\");\n * if (org) {\n * console.log(`Found: ${org.name}`);\n * console.log(`Your role: ${org.accessType}`);\n * } else {\n * console.log(\"Organization not found or no access\");\n * }\n * ```\n */\n async get(did: string): Promise<OrganizationInfo | null> {\n try {\n const { organizations } = await this.list();\n return organizations.find((o) => o.did === did) ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * Lists organizations the current user has access to.\n *\n * @param params - Optional pagination parameters\n * @param params.limit - Maximum number of results (1-100, default 50)\n * @param params.cursor - Pagination cursor from previous response\n * @returns Promise resolving to organizations and optional cursor\n * @throws {@link NetworkError} if the list operation fails\n *\n * @remarks\n * Returns organizations where the user is either:\n * - The owner\n * - A collaborator with any permission level\n *\n * The `accessType` field indicates the user's relationship to each organization.\n *\n * @example\n * ```typescript\n * // Get first page\n * const page1 = await repo.organizations.list({ limit: 20 });\n * console.log(`Found ${page1.organizations.length} organizations`);\n *\n * // Get next page if available\n * if (page1.cursor) {\n * const page2 = await repo.organizations.list({ limit: 20, cursor: page1.cursor });\n * }\n *\n * // Filter by access type\n * const owned = page1.organizations.filter(o => o.accessType === \"owner\");\n * const shared = page1.organizations.filter(o => o.accessType === \"shared\");\n * ```\n *\n * @example Display organization details\n * ```typescript\n * const { organizations } = await repo.organizations.list();\n *\n * for (const org of organizations) {\n * console.log(`${org.name} (@${org.handle})`);\n * console.log(` DID: ${org.did}`);\n * console.log(` Access: ${org.accessType}`);\n * if (org.description) {\n * console.log(` Description: ${org.description}`);\n * }\n * }\n * ```\n */\n async list(params?: { limit?: number; cursor?: string }): Promise<{\n organizations: OrganizationInfo[];\n cursor?: string;\n }> {\n const userDid = this.session.did || this.session.sub;\n if (!userDid) {\n throw new NetworkError(\"No authenticated user found\");\n }\n\n const queryParams = new URLSearchParams({\n userDid,\n });\n\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n\n if (params?.cursor) {\n queryParams.set(\"cursor\", params.cursor);\n }\n\n const response = await this.session.fetchHandler(\n `${this.serverUrl}/xrpc/com.sds.organization.list?${queryParams.toString()}`,\n { method: \"GET\" },\n );\n\n if (!response.ok) {\n throw new NetworkError(`Failed to list organizations: ${response.statusText}`);\n }\n\n const data = await response.json();\n const organizations = (data.organizations || []).map(\n (r: {\n did: string;\n handle: string;\n name: string;\n description?: string;\n createdAt?: string;\n accessType: \"owner\" | \"shared\" | \"none\";\n permissions: CollaboratorPermissions;\n }) => ({\n did: r.did,\n handle: r.handle,\n name: r.name,\n description: r.description,\n createdAt: r.createdAt || new Date().toISOString(),\n accessType: r.accessType,\n permissions: r.permissions,\n }),\n );\n\n return {\n organizations,\n cursor: data.cursor,\n };\n }\n}\n","/**\n * Repository - Unified fluent API for ATProto repository operations.\n *\n * This module provides the main interface for interacting with AT Protocol\n * data servers (PDS and SDS) through a consistent, fluent API.\n *\n * @packageDocumentation\n */\n\nimport { SDSRequiredError } from \"../core/errors.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport type { Session } from \"../core/types.js\";\nimport { ConfigurableAgent } from \"../agent/ConfigurableAgent.js\";\nimport { LexiconRegistry } from \"./LexiconRegistry.js\";\nimport type { Agent } from \"@atproto/api\";\n\n// Types\nexport type {\n RepositoryOptions,\n CreateResult,\n UpdateResult,\n PaginatedList,\n ListParams,\n RepositoryRole,\n RepositoryAccessGrant,\n OrganizationInfo,\n ProgressStep,\n} from \"./types.js\";\n\n// Interfaces\nexport type {\n RecordOperations,\n BlobOperations,\n ProfileOperations,\n HypercertOperations,\n HypercertEvents,\n CollaboratorOperations,\n OrganizationOperations,\n CreateHypercertParams,\n CreateHypercertResult,\n} from \"./interfaces.js\";\n\n// Implementations\nimport { RecordOperationsImpl } from \"./RecordOperationsImpl.js\";\nimport { BlobOperationsImpl } from \"./BlobOperationsImpl.js\";\nimport { ProfileOperationsImpl } from \"./ProfileOperationsImpl.js\";\nimport { HypercertOperationsImpl } from \"./HypercertOperationsImpl.js\";\nimport { CollaboratorOperationsImpl } from \"./CollaboratorOperationsImpl.js\";\nimport { OrganizationOperationsImpl } from \"./OrganizationOperationsImpl.js\";\n\nimport type {\n RecordOperations,\n BlobOperations,\n ProfileOperations,\n HypercertOperations,\n CollaboratorOperations,\n OrganizationOperations,\n} from \"./interfaces.js\";\n\n/**\n * Repository provides a fluent API for AT Protocol data operations.\n *\n * This class is the primary interface for working with data in the AT Protocol\n * ecosystem. It provides organized access to:\n *\n * - **Records**: Low-level CRUD operations for any AT Protocol record type\n * - **Blobs**: Binary data upload and retrieval (images, files)\n * - **Profile**: User profile management\n * - **Hypercerts**: High-level hypercert creation and management\n * - **Collaborators**: Access control for shared repositories (SDS only)\n * - **Organizations**: Organization management (SDS only)\n *\n * @remarks\n * The Repository uses lazy initialization for operation handlers - they are\n * created only when first accessed. This improves performance when you only\n * need a subset of operations.\n *\n * **PDS vs SDS:**\n * - **PDS (Personal Data Server)**: User's own data storage. All operations\n * except collaborators and organizations are available.\n * - **SDS (Shared Data Server)**: Collaborative data storage with access\n * control. All operations including collaborators and organizations.\n *\n * @example Basic usage\n * ```typescript\n * // Get a repository from the SDK\n * const repo = sdk.repository(session);\n *\n * // Access user profile\n * const profile = await repo.profile.get();\n *\n * // Create a hypercert\n * const result = await repo.hypercerts.create({\n * title: \"My Impact\",\n * description: \"Description of the impact\",\n * workScope: \"Climate Action\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-12-31\",\n * rights: {\n * name: \"Attribution\",\n * type: \"license\",\n * description: \"CC-BY-4.0\",\n * },\n * });\n * ```\n *\n * @example Working with a different user's repository\n * ```typescript\n * // Get the current user's repo\n * const myRepo = sdk.repository(session);\n *\n * // Get another user's repo (read-only for most operations)\n * const otherRepo = myRepo.repo(\"did:plc:other-user-did\");\n * const theirProfile = await otherRepo.profile.get();\n * ```\n *\n * @example SDS operations\n * ```typescript\n * // Get SDS repository for collaborator features\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Manage collaborators\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:collaborator\",\n * role: \"editor\",\n * });\n *\n * // List organizations\n * const orgs = await sdsRepo.organizations.list();\n * ```\n *\n * @see {@link ATProtoSDK.repository} for creating Repository instances\n */\nexport class Repository {\n private session: Session;\n private serverUrl: string;\n private repoDid: string;\n private logger?: LoggerInterface;\n private agent: Agent;\n private _isSDS: boolean;\n private lexiconRegistry: LexiconRegistry;\n\n // Lazily initialized operations\n private _records?: RecordOperationsImpl;\n private _blobs?: BlobOperationsImpl;\n private _profile?: ProfileOperationsImpl;\n private _hypercerts?: HypercertOperationsImpl;\n private _collaborators?: CollaboratorOperationsImpl;\n private _organizations?: OrganizationOperationsImpl;\n\n /**\n * Creates a new Repository instance.\n *\n * @param session - Authenticated OAuth session\n * @param serverUrl - Base URL of the AT Protocol server\n * @param repoDid - DID of the repository to operate on\n * @param isSDS - Whether this is a Shared Data Server\n * @param logger - Optional logger for debugging\n * @param lexiconRegistry - Registry for custom lexicon management\n *\n * @remarks\n * This constructor is typically not called directly. Use\n * {@link ATProtoSDK.repository} to create Repository instances.\n *\n * @internal\n */\n constructor(\n session: Session,\n serverUrl: string,\n repoDid: string,\n isSDS: boolean,\n logger?: LoggerInterface,\n lexiconRegistry?: LexiconRegistry,\n ) {\n this.session = session;\n this.serverUrl = serverUrl;\n this.repoDid = repoDid;\n this._isSDS = isSDS;\n this.logger = logger;\n this.lexiconRegistry = lexiconRegistry || new LexiconRegistry();\n\n // Create a ConfigurableAgent that routes requests to the specified server URL\n // This allows routing to PDS, SDS, or any custom server while maintaining\n // the OAuth session's authentication\n this.agent = new ConfigurableAgent(session, serverUrl);\n }\n\n /**\n * The DID (Decentralized Identifier) of this repository.\n *\n * This is the user or organization that owns the repository data.\n *\n * @example\n * ```typescript\n * console.log(`Working with repo: ${repo.did}`);\n * // Output: Working with repo: did:plc:abc123xyz...\n * ```\n */\n get did(): string {\n return this.repoDid;\n }\n\n /**\n * Whether this repository is on a Shared Data Server (SDS).\n *\n * SDS servers support additional features like collaborators and\n * organizations. Attempting to use these features on a PDS will\n * throw {@link SDSRequiredError}.\n *\n * @example\n * ```typescript\n * if (repo.isSDS) {\n * const collaborators = await repo.collaborators.list();\n * }\n * ```\n */\n get isSDS(): boolean {\n return this._isSDS;\n }\n\n /**\n * Gets the server URL this repository connects to.\n *\n * @returns The base URL of the AT Protocol server\n *\n * @example\n * ```typescript\n * console.log(repo.getServerUrl());\n * // Output: https://bsky.social or https://sds.hypercerts.org\n * ```\n */\n getServerUrl(): string {\n return this.serverUrl;\n }\n\n /**\n * Creates a Repository instance for a different DID on the same server.\n *\n * This allows you to read data from other users' repositories while\n * maintaining your authenticated session.\n *\n * @param did - The DID of the repository to access\n * @returns A new Repository instance for the specified DID\n *\n * @remarks\n * Write operations on another user's repository will typically fail\n * unless you have been granted collaborator access (SDS only).\n *\n * @example\n * ```typescript\n * // Read another user's profile\n * const otherRepo = repo.repo(\"did:plc:other-user\");\n * const profile = await otherRepo.profile.get();\n *\n * // List their public hypercerts\n * const hypercerts = await otherRepo.hypercerts.list();\n * ```\n */\n repo(did: string): Repository {\n return new Repository(this.session, this.serverUrl, did, this._isSDS, this.logger, this.lexiconRegistry);\n }\n\n /**\n * Gets the LexiconRegistry instance for managing custom lexicons.\n *\n * The registry is shared across all operations in this repository and\n * enables validation of custom record types.\n *\n * @returns The {@link LexiconRegistry} instance\n *\n * @example\n * ```typescript\n * // Access the registry\n * const registry = repo.getLexiconRegistry();\n *\n * // Register a custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.evaluation\",\n * defs: {\n * main: {\n * type: \"record\",\n * key: \"tid\",\n * record: {\n * type: \"object\",\n * required: [\"$type\", \"score\"],\n * properties: {\n * \"$type\": { type: \"string\", const: \"org.myapp.evaluation\" },\n * score: { type: \"integer\", minimum: 0, maximum: 100 }\n * }\n * }\n * }\n * }\n * });\n *\n * // Now create records using the custom lexicon\n * await repo.records.create({\n * collection: \"org.myapp.evaluation\",\n * record: {\n * $type: \"org.myapp.evaluation\",\n * score: 85\n * }\n * });\n * ```\n */\n getLexiconRegistry(): LexiconRegistry {\n return this.lexiconRegistry;\n }\n\n /**\n * Low-level record operations for CRUD on any AT Protocol record type.\n *\n * Use this for direct access to AT Protocol records when the high-level\n * APIs don't meet your needs.\n *\n * @returns {@link RecordOperations} interface for record CRUD\n *\n * @example\n * ```typescript\n * // Create a custom record\n * const result = await repo.records.create({\n * collection: \"org.example.myRecord\",\n * record: { foo: \"bar\" },\n * });\n *\n * // List records in a collection\n * const list = await repo.records.list({\n * collection: \"org.example.myRecord\",\n * limit: 50,\n * });\n *\n * // Get a specific record\n * const record = await repo.records.get({\n * collection: \"org.example.myRecord\",\n * rkey: \"abc123\",\n * });\n * ```\n */\n get records(): RecordOperations {\n if (!this._records) {\n this._records = new RecordOperationsImpl(this.agent, this.repoDid, this.lexiconRegistry);\n }\n return this._records;\n }\n\n /**\n * Blob operations for uploading and retrieving binary data.\n *\n * Blobs are used for images, files, and other binary content associated\n * with records.\n *\n * @returns {@link BlobOperations} interface for blob management\n *\n * @example\n * ```typescript\n * // Upload an image\n * const imageBlob = new Blob([imageData], { type: \"image/png\" });\n * const uploadResult = await repo.blobs.upload(imageBlob);\n *\n * // The ref can be used in records\n * console.log(uploadResult.ref.$link); // CID of the blob\n *\n * // Retrieve a blob by CID\n * const { data, mimeType } = await repo.blobs.get(cid);\n * ```\n */\n get blobs(): BlobOperations {\n if (!this._blobs) {\n this._blobs = new BlobOperationsImpl(this.agent, this.repoDid, this.serverUrl);\n }\n return this._blobs;\n }\n\n /**\n * Profile operations for managing user profiles.\n *\n * @returns {@link ProfileOperations} interface for profile management\n *\n * @example\n * ```typescript\n * // Get current profile\n * const profile = await repo.profile.get();\n * console.log(profile.displayName);\n *\n * // Update profile\n * await repo.profile.update({\n * displayName: \"New Name\",\n * description: \"Updated bio\",\n * avatar: avatarBlob, // Optional: update avatar image\n * });\n * ```\n */\n get profile(): ProfileOperations {\n if (!this._profile) {\n this._profile = new ProfileOperationsImpl(this.agent, this.repoDid, this.serverUrl);\n }\n return this._profile;\n }\n\n /**\n * High-level hypercert operations.\n *\n * Provides a convenient API for creating and managing hypercerts,\n * including related records like locations, contributions, and evidence.\n *\n * @returns {@link HypercertOperations} interface with EventEmitter capabilities\n *\n * @example Creating a hypercert\n * ```typescript\n * const result = await repo.hypercerts.create({\n * title: \"Climate Action Project\",\n * description: \"Reduced carbon emissions by 1000 tons\",\n * workScope: \"Climate Action\",\n * workTimeframeFrom: \"2024-01-01\",\n * workTimeframeTo: \"2024-06-30\",\n * rights: {\n * name: \"Public Domain\",\n * type: \"license\",\n * description: \"CC0 - No Rights Reserved\",\n * },\n * image: imageBlob, // Optional cover image\n * location: {\n * value: \"San Francisco, CA\",\n * name: \"SF Bay Area\",\n * },\n * });\n * console.log(`Created: ${result.hypercertUri}`);\n * ```\n *\n * @example Listening to events\n * ```typescript\n * repo.hypercerts.on(\"recordCreated\", ({ uri, cid }) => {\n * console.log(`Record created: ${uri}`);\n * });\n * ```\n */\n get hypercerts(): HypercertOperations {\n if (!this._hypercerts) {\n this._hypercerts = new HypercertOperationsImpl(this.agent, this.repoDid, this.serverUrl, this.logger);\n }\n return this._hypercerts;\n }\n\n /**\n * Collaborator operations for managing repository access.\n *\n * **SDS Only**: This property throws {@link SDSRequiredError} if accessed\n * on a PDS repository.\n *\n * @returns {@link CollaboratorOperations} interface for access control\n * @throws {@link SDSRequiredError} if not connected to an SDS server\n *\n * @example\n * ```typescript\n * // Ensure we're on SDS\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Grant editor access\n * await sdsRepo.collaborators.grant({\n * userDid: \"did:plc:new-collaborator\",\n * role: \"editor\",\n * });\n *\n * // List all collaborators\n * const collaborators = await sdsRepo.collaborators.list();\n *\n * // Check access\n * const hasAccess = await sdsRepo.collaborators.hasAccess(\"did:plc:someone\");\n *\n * // Revoke access\n * await sdsRepo.collaborators.revoke({ userDid: \"did:plc:former-collaborator\" });\n * ```\n */\n get collaborators(): CollaboratorOperations {\n if (!this._isSDS) {\n throw new SDSRequiredError(\"Collaborator operations are only available on SDS servers\");\n }\n if (!this._collaborators) {\n this._collaborators = new CollaboratorOperationsImpl(this.session, this.repoDid, this.serverUrl);\n }\n return this._collaborators;\n }\n\n /**\n * Organization operations for creating and managing organizations.\n *\n * **SDS Only**: This property throws {@link SDSRequiredError} if accessed\n * on a PDS repository.\n *\n * @returns {@link OrganizationOperations} interface for organization management\n * @throws {@link SDSRequiredError} if not connected to an SDS server\n *\n * @example\n * ```typescript\n * // Ensure we're on SDS\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n *\n * // Create an organization\n * const org = await sdsRepo.organizations.create({\n * name: \"My Organization\",\n * description: \"A team working on impact certificates\",\n * handle: \"my-org\", // Optional custom handle\n * });\n *\n * // List organizations you have access to\n * const orgs = await sdsRepo.organizations.list();\n *\n * // Get specific organization\n * const orgInfo = await sdsRepo.organizations.get(org.did);\n * ```\n */\n get organizations(): OrganizationOperations {\n if (!this._isSDS) {\n throw new SDSRequiredError(\"Organization operations are only available on SDS servers\");\n }\n if (!this._organizations) {\n this._organizations = new OrganizationOperationsImpl(this.session, this.repoDid, this.serverUrl, this.logger);\n }\n return this._organizations;\n }\n}\n","import { z } from \"zod\";\nimport type { SessionStore, StateStore, CacheInterface, LoggerInterface } from \"./interfaces.js\";\n\n/**\n * Type for HTTP loopback URLs (localhost, 127.0.0.1, [::1])\n */\nexport type LoopbackUrl = `http://localhost${string}` | `http://127.0.0.1${string}` | `http://[::1]${string}`;\n\n/**\n * Type for HTTPS URLs (production)\n */\nexport type HttpsUrl = `https://${string}`;\n\n/**\n * Type for URLs that can be used in development or production\n */\nexport type DevelopmentOrProductionUrl = HttpsUrl | LoopbackUrl;\n\n/**\n * Custom URL validator that allows HTTP loopback addresses for development.\n *\n * Accepts:\n * - Any HTTPS URL (production)\n * - http://localhost (with optional port and path)\n * - http://127.0.0.1 (with optional port and path)\n * - http://[::1] (with optional port and path) - IPv6 loopback\n *\n * Rejects:\n * - Other HTTP URLs (e.g., http://example.com)\n * - Invalid URLs\n *\n * @internal\n */\nconst urlOrLoopback = z.string().refine(\n (value) => {\n try {\n const url = new URL(value);\n\n // Always allow HTTPS\n if (url.protocol === \"https:\") {\n return true;\n }\n\n // For HTTP, only allow loopback addresses\n if (url.protocol === \"http:\") {\n const hostname = url.hostname.toLowerCase();\n return hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n }\n\n return false;\n } catch {\n return false;\n }\n },\n {\n message: \"Must be a valid HTTPS URL or HTTP loopback URL (localhost, 127.0.0.1, [::1])\",\n },\n);\n\n/**\n * Zod schema for OAuth configuration validation.\n *\n * @remarks\n * All URLs must be valid and use HTTPS in production. For local development,\n * HTTP loopback URLs (localhost, 127.0.0.1, [::1]) are allowed.\n * The `jwkPrivate` field should contain the private key in JWK (JSON Web Key) format as a string.\n */\nexport const OAuthConfigSchema = z.object({\n /**\n * URL to the OAuth client metadata JSON document.\n * This document describes your application to the authorization server.\n *\n * For local development, you can use `http://localhost/` as a loopback client.\n *\n * @see https://atproto.com/specs/oauth#client-metadata\n */\n clientId: urlOrLoopback,\n\n /**\n * URL where users are redirected after authentication.\n * Must match one of the redirect URIs in your client metadata.\n *\n * For local development, you can use HTTP loopback URLs like\n * `http://127.0.0.1:3000/callback` or `http://localhost:3000/callback`.\n */\n redirectUri: urlOrLoopback,\n\n /**\n * OAuth scopes to request, space-separated.\n *\n * Can be a string of space-separated permissions or use the permission system:\n *\n * @example Using presets\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n * scope: ScopePresets.EMAIL_AND_PROFILE\n * ```\n *\n * @example Building custom scopes\n * ```typescript\n * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';\n * scope: buildScope(\n * new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .build()\n * )\n * ```\n *\n * @example Legacy scopes\n * ```typescript\n * scope: \"atproto transition:generic\"\n * ```\n *\n * @see https://atproto.com/specs/permission for permission details\n */\n scope: z.string().min(1, \"OAuth scope is required\"),\n\n /**\n * URL to your public JWKS (JSON Web Key Set) endpoint.\n * Used by the authorization server to verify your client's signatures.\n *\n * For local development, you can serve JWKS from a loopback URL like\n * `http://127.0.0.1:3000/.well-known/jwks.json`.\n */\n jwksUri: urlOrLoopback,\n\n /**\n * Private JWK (JSON Web Key) as a JSON string.\n * Used for signing DPoP proofs and client assertions.\n *\n * @remarks\n * This should be kept secret and never exposed to clients.\n * Typically loaded from environment variables or a secrets manager.\n */\n jwkPrivate: z.string(),\n\n /**\n * Enable development mode features (optional).\n *\n * When true, suppresses warnings about using HTTP loopback URLs.\n * Should be set to true for local development to reduce console noise.\n *\n * @default false\n *\n * @example\n * ```typescript\n * oauth: {\n * clientId: \"http://localhost/\",\n * redirectUri: \"http://127.0.0.1:3000/callback\",\n * // ... other config\n * developmentMode: true, // Suppress loopback warnings\n * }\n * ```\n */\n developmentMode: z.boolean().optional(),\n});\n\n/**\n * Zod schema for server URL configuration.\n *\n * @remarks\n * At least one server (PDS or SDS) should be configured for the SDK to be useful.\n * For local development, HTTP loopback URLs are allowed.\n */\nexport const ServerConfigSchema = z.object({\n /**\n * Personal Data Server URL - the user's own AT Protocol server.\n * This is the primary server for user data operations.\n *\n * @example Production\n * ```typescript\n * pds: \"https://bsky.social\"\n * ```\n *\n * @example Local development\n * ```typescript\n * pds: \"http://localhost:2583\"\n * ```\n */\n pds: urlOrLoopback.optional(),\n\n /**\n * Shared Data Server URL - for collaborative data storage.\n * Required for collaborator and organization operations.\n *\n * @example Production\n * ```typescript\n * sds: \"https://sds.hypercerts.org\"\n * ```\n *\n * @example Local development\n * ```typescript\n * sds: \"http://127.0.0.1:2584\"\n * ```\n */\n sds: urlOrLoopback.optional(),\n});\n\n/**\n * Zod schema for timeout configuration.\n *\n * @remarks\n * All timeout values are in milliseconds.\n */\nexport const TimeoutConfigSchema = z.object({\n /**\n * Timeout for fetching PDS metadata during identity resolution.\n * @default 5000 (5 seconds, set by OAuthClient)\n */\n pdsMetadata: z.number().positive().optional(),\n\n /**\n * Timeout for general API requests to PDS/SDS.\n * @default 30000 (30 seconds)\n */\n apiRequests: z.number().positive().optional(),\n});\n\n/**\n * Zod schema for SDK configuration validation.\n *\n * @remarks\n * This schema validates only the primitive/serializable parts of the configuration.\n * Storage interfaces ({@link SessionStore}, {@link StateStore}) cannot be validated\n * with Zod as they are runtime objects.\n */\nexport const ATProtoSDKConfigSchema = z.object({\n oauth: OAuthConfigSchema,\n servers: ServerConfigSchema.optional(),\n timeouts: TimeoutConfigSchema.optional(),\n});\n\n/**\n * Configuration options for the ATProto SDK.\n *\n * This interface defines all configuration needed to initialize the SDK,\n * including OAuth credentials, server endpoints, and optional customizations.\n *\n * @example Minimal configuration\n * ```typescript\n * const config: ATProtoSDKConfig = {\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: {\n * pds: \"https://bsky.social\",\n * },\n * };\n * ```\n *\n * @example Full configuration with custom storage\n * ```typescript\n * const config: ATProtoSDKConfig = {\n * oauth: { ... },\n * servers: {\n * pds: \"https://bsky.social\",\n * sds: \"https://sds.hypercerts.org\",\n * },\n * storage: {\n * sessionStore: new RedisSessionStore(redisClient),\n * stateStore: new RedisStateStore(redisClient),\n * },\n * timeouts: {\n * pdsMetadata: 5000,\n * apiRequests: 30000,\n * },\n * logger: console,\n * };\n * ```\n */\nexport interface ATProtoSDKConfig {\n /**\n * OAuth 2.0 configuration for authentication.\n *\n * Required fields for the OAuth flow with DPoP (Demonstrating Proof of Possession).\n * Your application must host the client metadata and JWKS endpoints.\n *\n * @see https://atproto.com/specs/oauth for AT Protocol OAuth specification\n */\n oauth: z.infer<typeof OAuthConfigSchema>;\n\n /**\n * Server URLs for PDS and SDS connections.\n *\n * - **PDS**: Personal Data Server - user's own data storage\n * - **SDS**: Shared Data Server - collaborative storage with access control\n */\n servers?: z.infer<typeof ServerConfigSchema>;\n\n /**\n * Storage adapters for persisting OAuth sessions and state.\n *\n * If not provided, in-memory implementations are used automatically.\n * **Warning**: In-memory storage is lost on process restart - use persistent\n * storage (Redis, database, etc.) in production.\n *\n * @example\n * ```typescript\n * storage: {\n * sessionStore: new RedisSessionStore(redis),\n * stateStore: new RedisStateStore(redis),\n * }\n * ```\n */\n storage?: {\n /**\n * Persistent storage for OAuth sessions.\n * Sessions contain access tokens, refresh tokens, and DPoP keys.\n */\n sessionStore?: SessionStore;\n\n /**\n * Temporary storage for OAuth state during the authorization flow.\n * State is short-lived and used for PKCE and CSRF protection.\n */\n stateStore?: StateStore;\n };\n\n /**\n * Custom fetch implementation for HTTP requests.\n *\n * Use this to add custom headers, logging, or to use a different HTTP client.\n * Must be compatible with the standard Fetch API.\n *\n * @example\n * ```typescript\n * fetch: async (url, init) => {\n * console.log(`Fetching: ${url}`);\n * return globalThis.fetch(url, init);\n * }\n * ```\n */\n fetch?: typeof fetch;\n\n /**\n * Timeout configuration for network requests.\n * Values are in milliseconds.\n */\n timeouts?: z.infer<typeof TimeoutConfigSchema>;\n\n /**\n * Cache for profiles, metadata, and other frequently accessed data.\n *\n * Implementing caching can significantly reduce API calls and improve performance.\n * The SDK does not provide a default cache - you must implement {@link CacheInterface}.\n */\n cache?: CacheInterface;\n\n /**\n * Logger for debugging and observability.\n *\n * The logger receives debug, info, warn, and error messages from the SDK.\n * Compatible with `console` or any logger implementing {@link LoggerInterface}.\n *\n * @example\n * ```typescript\n * logger: console\n * // or\n * logger: pino()\n * // or\n * logger: winston.createLogger({ ... })\n * ```\n */\n logger?: LoggerInterface;\n}\n","import { OAuthClient } from \"../auth/OAuthClient.js\";\nimport { Repository } from \"../repository/Repository.js\";\nimport { LexiconRegistry } from \"../repository/LexiconRegistry.js\";\nimport type { RepositoryOptions } from \"../repository/types.js\";\nimport { InMemorySessionStore } from \"../storage/InMemorySessionStore.js\";\nimport { InMemoryStateStore } from \"../storage/InMemoryStateStore.js\";\nimport { HYPERCERT_LEXICONS } from \"../lexicons.js\";\nimport type { ATProtoSDKConfig } from \"./config.js\";\nimport { ATProtoSDKConfigSchema } from \"./config.js\";\nimport { ValidationError, NetworkError } from \"./errors.js\";\nimport type { Session } from \"./types.js\";\n\n/**\n * Options for the OAuth authorization flow.\n */\nexport interface AuthorizeOptions {\n /**\n * OAuth scope string to request specific permissions.\n * Overrides the default scope configured in {@link ATProtoSDKConfig.oauth.scope}.\n *\n * Can use the permission system for type-safe scope building.\n *\n * @example Using presets\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n *\n * // Request email and profile access\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.EMAIL_AND_PROFILE\n * });\n *\n * // Request full posting capabilities\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.POSTING_APP\n * });\n * ```\n *\n * @example Building custom scopes\n * ```typescript\n * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';\n *\n * const scope = buildScope(\n * new PermissionBuilder()\n * .accountEmail('read')\n * .repoWrite('app.bsky.feed.post')\n * .blob(['image/*'])\n * .build()\n * );\n *\n * await sdk.authorize(\"user.bsky.social\", { scope });\n * ```\n *\n * @example Legacy scopes\n * ```typescript\n * // Request read-only access\n * await sdk.authorize(\"user.bsky.social\", { scope: \"atproto\" });\n *\n * // Request full access (legacy)\n * await sdk.authorize(\"user.bsky.social\", {\n * scope: \"atproto transition:generic\"\n * });\n * ```\n */\n scope?: string;\n}\n\n/**\n * Main ATProto SDK class providing OAuth authentication and repository access.\n *\n * This is the primary entry point for interacting with AT Protocol servers.\n * It handles the OAuth 2.0 flow with DPoP (Demonstrating Proof of Possession)\n * and provides access to repository operations for managing records, blobs,\n * and profiles.\n *\n * @example Basic usage with OAuth flow\n * ```typescript\n * import { ATProtoSDK, InMemorySessionStore, InMemoryStateStore } from \"@hypercerts-org/sdk\";\n *\n * const sdk = new ATProtoSDK({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto transition:generic\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: process.env.JWK_PRIVATE_KEY!,\n * },\n * servers: {\n * pds: \"https://bsky.social\",\n * sds: \"https://sds.hypercerts.org\",\n * },\n * });\n *\n * // Start OAuth flow - redirect user to this URL\n * const authUrl = await sdk.authorize(\"user.bsky.social\");\n *\n * // After user returns, handle the callback\n * const session = await sdk.callback(new URLSearchParams(window.location.search));\n *\n * // Get a repository to work with data\n * const repo = sdk.repository(session);\n * ```\n *\n * @example Restoring an existing session\n * ```typescript\n * // Restore a previous session by DID\n * const session = await sdk.restoreSession(\"did:plc:abc123...\");\n * if (session) {\n * const repo = sdk.repository(session);\n * // Continue working with the restored session\n * }\n * ```\n *\n * @see {@link ATProtoSDKConfig} for configuration options\n * @see {@link Repository} for data operations\n * @see {@link OAuthClient} for OAuth implementation details\n */\nexport class ATProtoSDK {\n private oauthClient: OAuthClient;\n private config: ATProtoSDKConfig;\n private logger?: ATProtoSDKConfig[\"logger\"];\n private lexiconRegistry: LexiconRegistry;\n\n /**\n * Creates a new ATProto SDK instance.\n *\n * @param config - SDK configuration including OAuth credentials, server URLs, and optional storage adapters\n * @throws {@link ValidationError} if the configuration is invalid (e.g., malformed URLs, missing required fields)\n *\n * @remarks\n * If no storage adapters are provided, in-memory implementations are used.\n * These are suitable for development and testing but **not recommended for production**\n * as sessions will be lost on restart.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses in-memory storage)\n * const sdk = new ATProtoSDK({\n * oauth: {\n * clientId: \"https://my-app.com/client-metadata.json\",\n * redirectUri: \"https://my-app.com/callback\",\n * scope: \"atproto\",\n * jwksUri: \"https://my-app.com/.well-known/jwks.json\",\n * jwkPrivate: privateKeyJwk,\n * },\n * servers: { pds: \"https://bsky.social\" },\n * });\n * ```\n */\n constructor(config: ATProtoSDKConfig) {\n // Validate configuration\n const validationResult = ATProtoSDKConfigSchema.safeParse(config);\n if (!validationResult.success) {\n throw new ValidationError(`Invalid SDK configuration: ${validationResult.error.message}`, validationResult.error);\n }\n\n // Apply defaults for optional storage\n const configWithDefaults: ATProtoSDKConfig = {\n ...config,\n storage: {\n sessionStore: config.storage?.sessionStore ?? new InMemorySessionStore(),\n stateStore: config.storage?.stateStore ?? new InMemoryStateStore(),\n },\n };\n\n this.config = configWithDefaults;\n this.logger = config.logger;\n\n // Initialize lexicon registry with hypercert lexicons\n // Filter out undefined lexicons (some may not be exported from lexicon package yet)\n const validLexicons = HYPERCERT_LEXICONS.filter((lex) => lex !== undefined);\n this.lexiconRegistry = new LexiconRegistry(validLexicons);\n\n // Initialize OAuth client\n this.oauthClient = new OAuthClient(configWithDefaults);\n\n this.logger?.info(\"ATProto SDK initialized\");\n }\n\n /**\n * Initiates the OAuth authorization flow.\n *\n * This method starts the OAuth 2.0 authorization flow by resolving the user's\n * identity and generating an authorization URL. The user should be redirected\n * to this URL to authenticate.\n *\n * @param identifier - The user's ATProto identifier. Can be:\n * - A handle (e.g., `\"user.bsky.social\"`)\n * - A DID (e.g., `\"did:plc:abc123...\"`)\n * - A PDS URL (e.g., `\"https://bsky.social\"`)\n * @param options - Optional authorization settings\n * @returns A Promise resolving to the authorization URL to redirect the user to\n * @throws {@link ValidationError} if the identifier is empty or invalid\n * @throws {@link NetworkError} if the identity cannot be resolved\n *\n * @example\n * ```typescript\n * // Using a handle\n * const authUrl = await sdk.authorize(\"alice.bsky.social\");\n *\n * // Using a DID directly\n * const authUrl = await sdk.authorize(\"did:plc:abc123xyz\");\n *\n * // With custom scope\n * const authUrl = await sdk.authorize(\"alice.bsky.social\", {\n * scope: \"atproto transition:generic\"\n * });\n *\n * // Redirect user to authUrl\n * window.location.href = authUrl;\n * ```\n */\n async authorize(identifier: string, options?: AuthorizeOptions): Promise<string> {\n if (!identifier || !identifier.trim()) {\n throw new ValidationError(\"ATProto identifier is required\");\n }\n\n return this.oauthClient.authorize(identifier.trim(), options);\n }\n\n /**\n * Handles the OAuth callback and exchanges the authorization code for tokens.\n *\n * Call this method when the user is redirected back to your application\n * after authenticating. It validates the OAuth state, exchanges the\n * authorization code for access/refresh tokens, and creates a session.\n *\n * @param params - URL search parameters from the callback URL\n * @returns A Promise resolving to the authenticated OAuth session\n * @throws {@link AuthenticationError} if the callback parameters are invalid or the code exchange fails\n * @throws {@link ValidationError} if required parameters are missing\n *\n * @example\n * ```typescript\n * // In your callback route handler\n * const params = new URLSearchParams(window.location.search);\n * // params contains: code, state, iss (issuer)\n *\n * const session = await sdk.callback(params);\n * console.log(`Authenticated as ${session.did}`);\n *\n * // Store the DID to restore the session later\n * localStorage.setItem(\"userDid\", session.did);\n * ```\n */\n async callback(params: URLSearchParams): Promise<Session> {\n return this.oauthClient.callback(params);\n }\n\n /**\n * Restores an existing OAuth session by DID.\n *\n * Use this method to restore a previously authenticated session, typically\n * on application startup. The method retrieves the stored session and\n * automatically refreshes expired tokens if needed.\n *\n * @param did - The user's Decentralized Identifier (DID), e.g., `\"did:plc:abc123...\"`\n * @returns A Promise resolving to the restored session, or `null` if no session exists\n * @throws {@link ValidationError} if the DID is empty\n * @throws {@link SessionExpiredError} if the session cannot be refreshed\n *\n * @example\n * ```typescript\n * // On application startup\n * const savedDid = localStorage.getItem(\"userDid\");\n * if (savedDid) {\n * const session = await sdk.restoreSession(savedDid);\n * if (session) {\n * // User is still authenticated\n * const repo = sdk.repository(session);\n * } else {\n * // Session not found, user needs to re-authenticate\n * const authUrl = await sdk.authorize(savedDid);\n * }\n * }\n * ```\n */\n async restoreSession(did: string): Promise<Session | null> {\n if (!did || !did.trim()) {\n throw new ValidationError(\"DID is required\");\n }\n\n return this.oauthClient.restore(did.trim());\n }\n\n /**\n * Revokes an OAuth session, logging the user out.\n *\n * This method invalidates the session's tokens and removes it from storage.\n * After revocation, the session can no longer be used or restored.\n *\n * @param did - The user's DID to revoke the session for\n * @throws {@link ValidationError} if the DID is empty\n *\n * @example\n * ```typescript\n * // Log out the user\n * await sdk.revokeSession(session.did);\n * localStorage.removeItem(\"userDid\");\n * ```\n */\n async revokeSession(did: string): Promise<void> {\n if (!did || !did.trim()) {\n throw new ValidationError(\"DID is required\");\n }\n\n return this.oauthClient.revoke(did.trim());\n }\n\n /**\n * Gets the account email address from the authenticated session.\n *\n * This method retrieves the email address associated with the user's account\n * by calling the `com.atproto.server.getSession` endpoint. The email will only\n * be returned if the appropriate OAuth scope was granted during authorization.\n *\n * Required OAuth scopes:\n * - **Granular permissions**: `account:email?action=read` or `account:email`\n * - **Transitional permissions**: `transition:email`\n *\n * @param session - An authenticated OAuth session\n * @returns A Promise resolving to email info, or `null` if permission not granted\n * @throws {@link ValidationError} if the session is invalid\n * @throws {@link NetworkError} if the API request fails\n *\n * @example Using granular permissions\n * ```typescript\n * import { ScopePresets } from '@hypercerts-org/sdk-core';\n *\n * // Authorize with email scope\n * const authUrl = await sdk.authorize(\"user.bsky.social\", {\n * scope: ScopePresets.EMAIL_READ\n * });\n *\n * // After callback...\n * const emailInfo = await sdk.getAccountEmail(session);\n * if (emailInfo) {\n * console.log(`Email: ${emailInfo.email}`);\n * console.log(`Confirmed: ${emailInfo.emailConfirmed}`);\n * } else {\n * console.log(\"Email permission not granted\");\n * }\n * ```\n *\n * @example Using transitional permissions (legacy)\n * ```typescript\n * // Authorize with transition:email scope\n * const authUrl = await sdk.authorize(\"user.bsky.social\", {\n * scope: \"atproto transition:email\"\n * });\n *\n * // After callback...\n * const emailInfo = await sdk.getAccountEmail(session);\n * ```\n */\n async getAccountEmail(session: Session): Promise<{ email: string; emailConfirmed: boolean } | null> {\n if (!session) {\n throw new ValidationError(\"Session is required\");\n }\n\n try {\n // Determine PDS URL from session or config\n const pdsUrl = this.config.servers?.pds;\n if (!pdsUrl) {\n throw new ValidationError(\"PDS server URL not configured\");\n }\n\n // Call com.atproto.server.getSession endpoint using session's fetchHandler\n // which automatically includes proper authorization with DPoP\n const response = await session.fetchHandler(\"/xrpc/com.atproto.server.getSession\", {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n throw new NetworkError(`Failed to get session info: ${response.status} ${response.statusText}`);\n }\n\n const data = (await response.json()) as {\n email?: string;\n emailConfirmed?: boolean;\n did: string;\n handle: string;\n };\n\n // Return null if email not present (permission not granted)\n if (!data.email) {\n return null;\n }\n\n return {\n email: data.email,\n emailConfirmed: data.emailConfirmed ?? false,\n };\n } catch (error) {\n this.logger?.error(\"Failed to get account email\", { error });\n if (error instanceof ValidationError || error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to get account email: ${error instanceof Error ? error.message : String(error)}`,\n error,\n );\n }\n }\n\n /**\n * Creates a repository instance for data operations.\n *\n * The repository provides a fluent API for working with AT Protocol data\n * including records, blobs, profiles, and domain-specific operations like\n * hypercerts and collaborators.\n *\n * @param session - An authenticated OAuth session\n * @param options - Repository configuration options\n * @returns A {@link Repository} instance configured for the specified server\n * @throws {@link ValidationError} if the session is invalid or server URL is not configured\n *\n * @remarks\n * - **PDS (Personal Data Server)**: User's own data storage, default for most operations\n * - **SDS (Shared Data Server)**: Shared data storage with collaborator support\n *\n * @example Using default PDS\n * ```typescript\n * const repo = sdk.repository(session);\n * const profile = await repo.profile.get();\n * ```\n *\n * @example Using configured SDS\n * ```typescript\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n * const collaborators = await sdsRepo.collaborators.list();\n * ```\n *\n * @example Using custom server URL\n * ```typescript\n * const customRepo = sdk.repository(session, {\n * serverUrl: \"https://custom.atproto.server\"\n * });\n * ```\n */\n repository(session: Session, options?: RepositoryOptions): Repository {\n if (!session) {\n throw new ValidationError(\"Session is required\");\n }\n\n // Determine server URL\n let serverUrl: string;\n let isSDS = false;\n\n if (options?.serverUrl) {\n // Custom URL provided\n serverUrl = options.serverUrl;\n // Check if it matches configured SDS\n isSDS = this.config.servers?.sds === serverUrl;\n } else if (options?.server === \"sds\") {\n // Use configured SDS\n if (!this.config.servers?.sds) {\n throw new ValidationError(\"SDS server URL not configured\");\n }\n serverUrl = this.config.servers.sds;\n isSDS = true;\n } else if (options?.server === \"pds\" || !options?.server) {\n // Use configured PDS (default)\n if (!this.config.servers?.pds) {\n throw new ValidationError(\"PDS server URL not configured\");\n }\n serverUrl = this.config.servers.pds;\n isSDS = false;\n } else {\n // Custom server string (treat as URL)\n serverUrl = options.server;\n isSDS = this.config.servers?.sds === serverUrl;\n }\n\n // Get repository DID (default to session DID)\n const repoDid = session.did || session.sub;\n\n return new Repository(session, serverUrl, repoDid, isSDS, this.logger, this.lexiconRegistry);\n }\n\n /**\n * Gets the LexiconRegistry instance for managing custom lexicons.\n *\n * The registry allows you to register custom lexicon schemas and validate\n * records against them. All registered lexicons will be automatically\n * validated during record creation operations.\n *\n * @returns The {@link LexiconRegistry} instance\n *\n * @example\n * ```typescript\n * // Register a custom lexicon\n * const registry = sdk.getLexiconRegistry();\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... }\n * });\n *\n * // Check if lexicon is registered\n * if (registry.isRegistered(\"org.myapp.customRecord\")) {\n * console.log(\"Custom lexicon is available\");\n * }\n * ```\n */\n getLexiconRegistry(): LexiconRegistry {\n return this.lexiconRegistry;\n }\n\n /**\n * The configured PDS (Personal Data Server) URL.\n *\n * @returns The PDS URL if configured, otherwise `undefined`\n */\n get pdsUrl(): string | undefined {\n return this.config.servers?.pds;\n }\n\n /**\n * The configured SDS (Shared Data Server) URL.\n *\n * @returns The SDS URL if configured, otherwise `undefined`\n */\n get sdsUrl(): string | undefined {\n return this.config.servers?.sds;\n }\n}\n\n/**\n * Factory function to create an ATProto SDK instance.\n *\n * This is a convenience function equivalent to `new ATProtoSDK(config)`.\n *\n * @param config - SDK configuration\n * @returns A new {@link ATProtoSDK} instance\n *\n * @example\n * ```typescript\n * import { createATProtoSDK } from \"@hypercerts-org/sdk\";\n *\n * const sdk = createATProtoSDK({\n * oauth: { ... },\n * servers: { pds: \"https://bsky.social\" },\n * });\n * ```\n */\nexport function createATProtoSDK(config: ATProtoSDKConfig): ATProtoSDK {\n return new ATProtoSDK(config);\n}\n","/**\n * BaseOperations - Abstract base class for custom lexicon operations.\n *\n * This module provides a foundation for building domain-specific operation\n * classes that work with custom lexicons. It handles validation, record\n * creation, and provides utilities for working with AT Protocol records.\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"@atproto/api\";\nimport { ValidationError, NetworkError } from \"../errors.js\";\nimport type { LexiconRegistry } from \"./LexiconRegistry.js\";\nimport type { CreateResult, UpdateResult } from \"./types.js\";\nimport type { LoggerInterface } from \"../core/interfaces.js\";\nimport type { StrongRef } from \"../services/hypercerts/types.js\";\n\n/**\n * Abstract base class for creating custom lexicon operation classes.\n *\n * Extend this class to build domain-specific operations for your custom\n * lexicons. The base class provides:\n *\n * - Automatic validation against registered lexicon schemas\n * - Helper methods for creating and updating records\n * - Utilities for building strongRefs and AT-URIs\n * - Error handling and logging support\n *\n * @typeParam TParams - Type of parameters accepted by the create() method\n * @typeParam TResult - Type of result returned by the create() method\n *\n * @remarks\n * This class is designed to be extended by developers creating custom\n * operation classes for their own lexicons. It follows the same patterns\n * as the built-in hypercert operations.\n *\n * @example Basic usage\n * ```typescript\n * import { BaseOperations } from \"@hypercerts-org/sdk-core\";\n *\n * interface EvaluationParams {\n * subjectUri: string;\n * subjectCid: string;\n * score: number;\n * methodology?: string;\n * }\n *\n * interface EvaluationResult {\n * uri: string;\n * cid: string;\n * record: MyEvaluation;\n * }\n *\n * class EvaluationOperations extends BaseOperations<EvaluationParams, EvaluationResult> {\n * async create(params: EvaluationParams): Promise<EvaluationResult> {\n * const record = {\n * $type: \"org.myapp.evaluation\",\n * subject: this.createStrongRef(params.subjectUri, params.subjectCid),\n * score: params.score,\n * methodology: params.methodology,\n * createdAt: new Date().toISOString(),\n * };\n *\n * const { uri, cid } = await this.validateAndCreate(\"org.myapp.evaluation\", record);\n * return { uri, cid, record };\n * }\n * }\n * ```\n *\n * @example With validation and error handling\n * ```typescript\n * class ProjectOperations extends BaseOperations<CreateProjectParams, ProjectResult> {\n * async create(params: CreateProjectParams): Promise<ProjectResult> {\n * // Validate input parameters\n * if (!params.title || params.title.trim().length === 0) {\n * throw new ValidationError(\"Project title cannot be empty\");\n * }\n *\n * const record = {\n * $type: \"org.myapp.project\",\n * title: params.title,\n * description: params.description,\n * createdAt: new Date().toISOString(),\n * };\n *\n * try {\n * const { uri, cid } = await this.validateAndCreate(\"org.myapp.project\", record);\n * this.logger?.info(`Created project: ${uri}`);\n * return { uri, cid, record };\n * } catch (error) {\n * this.logger?.error(`Failed to create project: ${error}`);\n * throw error;\n * }\n * }\n * }\n * ```\n */\nexport abstract class BaseOperations<TParams = unknown, TResult = unknown> {\n /**\n * Creates a new BaseOperations instance.\n *\n * @param agent - AT Protocol Agent for making API calls\n * @param repoDid - DID of the repository to operate on\n * @param lexiconRegistry - Registry for validating records against lexicon schemas\n * @param logger - Optional logger for debugging and monitoring\n *\n * @internal\n */\n constructor(\n protected agent: Agent,\n protected repoDid: string,\n protected lexiconRegistry: LexiconRegistry,\n protected logger?: LoggerInterface,\n ) {}\n\n /**\n * Validates a record against its lexicon schema and creates it in the repository.\n *\n * This method performs the following steps:\n * 1. Validates the record against the registered lexicon schema\n * 2. Throws ValidationError if validation fails\n * 3. Creates the record using the AT Protocol Agent\n * 4. Returns the created record's URI and CID\n *\n * @param collection - NSID of the collection (e.g., \"org.myapp.customRecord\")\n * @param record - Record data conforming to the collection's lexicon schema\n * @param rkey - Optional record key. If not provided, a TID is auto-generated\n * @returns Promise resolving to the created record's URI and CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @example\n * ```typescript\n * const record = {\n * $type: \"org.myapp.evaluation\",\n * subject: { uri: \"at://...\", cid: \"bafyrei...\" },\n * score: 85,\n * createdAt: new Date().toISOString(),\n * };\n *\n * const { uri, cid } = await this.validateAndCreate(\"org.myapp.evaluation\", record);\n * ```\n */\n protected async validateAndCreate(collection: string, record: unknown, rkey?: string): Promise<CreateResult> {\n // Validate record against registered lexicon\n if (this.lexiconRegistry.isRegistered(collection)) {\n const validation = this.lexiconRegistry.validate(collection, record);\n if (!validation.valid) {\n throw new ValidationError(`Invalid ${collection}: ${validation.error}`);\n }\n }\n\n try {\n const result = await this.agent.com.atproto.repo.createRecord({\n repo: this.repoDid,\n collection,\n record: record as Record<string, unknown>,\n rkey,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to create record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to create ${collection}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Validates a record against its lexicon schema and updates it in the repository.\n *\n * This method performs the following steps:\n * 1. Validates the record against the registered lexicon schema\n * 2. Throws ValidationError if validation fails\n * 3. Updates the record using the AT Protocol Agent\n * 4. Returns the updated record's URI and new CID\n *\n * @param collection - NSID of the collection\n * @param rkey - Record key (the last segment of the AT-URI)\n * @param record - New record data (completely replaces existing record)\n * @returns Promise resolving to the updated record's URI and new CID\n * @throws {@link ValidationError} if the record doesn't conform to the lexicon schema\n * @throws {@link NetworkError} if the API request fails\n *\n * @remarks\n * This is a full replacement operation, not a partial update.\n *\n * @example\n * ```typescript\n * const updatedRecord = {\n * $type: \"org.myapp.evaluation\",\n * subject: { uri: \"at://...\", cid: \"bafyrei...\" },\n * score: 90, // Updated score\n * createdAt: existingRecord.createdAt,\n * };\n *\n * const { uri, cid } = await this.validateAndUpdate(\n * \"org.myapp.evaluation\",\n * \"abc123\",\n * updatedRecord\n * );\n * ```\n */\n protected async validateAndUpdate(collection: string, rkey: string, record: unknown): Promise<UpdateResult> {\n // Validate record against registered lexicon\n if (this.lexiconRegistry.isRegistered(collection)) {\n const validation = this.lexiconRegistry.validate(collection, record);\n if (!validation.valid) {\n throw new ValidationError(`Invalid ${collection}: ${validation.error}`);\n }\n }\n\n try {\n const result = await this.agent.com.atproto.repo.putRecord({\n repo: this.repoDid,\n collection,\n rkey,\n record: record as Record<string, unknown>,\n });\n\n if (!result.success) {\n throw new NetworkError(\"Failed to update record\");\n }\n\n return { uri: result.data.uri, cid: result.data.cid };\n } catch (error) {\n if (error instanceof ValidationError || error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Failed to update ${collection}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error,\n );\n }\n }\n\n /**\n * Creates a strongRef object from a URI and CID.\n *\n * StrongRefs are used in AT Protocol to reference specific versions\n * of records. They ensure that references point to an exact record\n * version, not just the latest version.\n *\n * @param uri - AT-URI of the record (e.g., \"at://did:plc:abc/collection/rkey\")\n * @param cid - Content Identifier (CID) of the record\n * @returns StrongRef object with uri and cid properties\n *\n * @example\n * ```typescript\n * const hypercertRef = this.createStrongRef(\n * \"at://did:plc:abc123/org.hypercerts.claim.activity/xyz789\",\n * \"bafyreiabc123...\"\n * );\n *\n * const evaluation = {\n * $type: \"org.myapp.evaluation\",\n * subject: hypercertRef, // Reference to specific hypercert version\n * score: 85,\n * createdAt: new Date().toISOString(),\n * };\n * ```\n */\n protected createStrongRef(uri: string, cid: string): StrongRef {\n return { uri, cid };\n }\n\n /**\n * Creates a strongRef from a CreateResult or UpdateResult.\n *\n * This is a convenience method for creating strongRefs from the\n * results of create or update operations.\n *\n * @param result - Result from a create or update operation\n * @returns StrongRef object with uri and cid properties\n *\n * @example\n * ```typescript\n * // Create a project\n * const projectResult = await this.validateAndCreate(\"org.myapp.project\", projectRecord);\n *\n * // Create a task that references the project\n * const taskRecord = {\n * $type: \"org.myapp.task\",\n * project: this.createStrongRefFromResult(projectResult),\n * title: \"Implement feature\",\n * createdAt: new Date().toISOString(),\n * };\n * ```\n */\n protected createStrongRefFromResult(result: CreateResult | UpdateResult): StrongRef {\n return { uri: result.uri, cid: result.cid };\n }\n\n /**\n * Parses an AT-URI to extract its components.\n *\n * AT-URIs follow the format: `at://{did}/{collection}/{rkey}`\n *\n * @param uri - AT-URI to parse\n * @returns Object containing did, collection, and rkey\n * @throws Error if the URI format is invalid\n *\n * @example\n * ```typescript\n * const { did, collection, rkey } = this.parseAtUri(\n * \"at://did:plc:abc123/org.hypercerts.claim.activity/xyz789\"\n * );\n * // did: \"did:plc:abc123\"\n * // collection: \"org.hypercerts.claim.activity\"\n * // rkey: \"xyz789\"\n * ```\n */\n protected parseAtUri(uri: string): { did: string; collection: string; rkey: string } {\n if (!uri.startsWith(\"at://\")) {\n throw new Error(`Invalid AT-URI format: ${uri}`);\n }\n\n const parts = uri.slice(5).split(\"/\"); // Remove \"at://\" and split\n if (parts.length !== 3) {\n throw new Error(`Invalid AT-URI format: ${uri}`);\n }\n\n return {\n did: parts[0],\n collection: parts[1],\n rkey: parts[2],\n };\n }\n\n /**\n * Builds an AT-URI from its components.\n *\n * @param did - DID of the repository\n * @param collection - NSID of the collection\n * @param rkey - Record key (typically a TID)\n * @returns Complete AT-URI string\n *\n * @example\n * ```typescript\n * const uri = this.buildAtUri(\n * \"did:plc:abc123\",\n * \"org.myapp.evaluation\",\n * \"xyz789\"\n * );\n * // Returns: \"at://did:plc:abc123/org.myapp.evaluation/xyz789\"\n * ```\n */\n protected buildAtUri(did: string, collection: string, rkey: string): string {\n return `at://${did}/${collection}/${rkey}`;\n }\n\n /**\n * Abstract create method that must be implemented by subclasses.\n *\n * Implement this method to define how your custom records are created.\n * Use the helper methods like `validateAndCreate()`, `createStrongRef()`,\n * etc. to build your implementation.\n *\n * @param params - Parameters for creating the record\n * @returns Promise resolving to the creation result\n *\n * @example\n * ```typescript\n * async create(params: EvaluationParams): Promise<EvaluationResult> {\n * const record = {\n * $type: \"org.myapp.evaluation\",\n * subject: this.createStrongRef(params.subjectUri, params.subjectCid),\n * score: params.score,\n * methodology: params.methodology,\n * createdAt: new Date().toISOString(),\n * };\n *\n * const { uri, cid } = await this.validateAndCreate(\"org.myapp.evaluation\", record);\n * return { uri, cid, record };\n * }\n * ```\n */\n abstract create(params: TParams): Promise<TResult>;\n}\n","/**\n * Lexicon Development Utilities - AT-URI and StrongRef Helpers\n *\n * This module provides utilities for working with AT Protocol URIs and strongRefs\n * when building custom lexicons. These tools help developers create type-safe\n * references between records.\n *\n * @packageDocumentation\n */\n\nimport type { StrongRef } from \"../services/hypercerts/types.js\";\nimport type { CreateResult, UpdateResult } from \"../repository/types.js\";\n\n/**\n * Components of an AT-URI (AT Protocol Uniform Resource Identifier).\n *\n * AT-URIs follow the format: `at://{did}/{collection}/{rkey}`\n * where:\n * - `did`: The DID of the repository owner (e.g., \"did:plc:abc123\")\n * - `collection`: The NSID of the record type (e.g., \"org.hypercerts.claim.activity\")\n * - `rkey`: The record key, either a TID or custom key (e.g., \"3km2vj4kfqp2a\")\n */\nexport interface AtUriComponents {\n /** Repository owner's DID */\n did: string;\n /** Collection NSID (lexicon identifier) */\n collection: string;\n /** Record key (TID or custom string) */\n rkey: string;\n}\n\n/**\n * Parse an AT-URI into its component parts.\n *\n * Extracts the DID, collection NSID, and record key from an AT-URI string.\n * AT-URIs follow the format: `at://{did}/{collection}/{rkey}`\n *\n * @param uri - The AT-URI to parse\n * @returns The components of the URI\n * @throws {Error} If the URI format is invalid\n *\n * @example\n * ```typescript\n * const components = parseAtUri(\"at://did:plc:abc123/org.hypercerts.claim.activity/3km2vj4kfqp2a\");\n * console.log(components);\n * // {\n * // did: \"did:plc:abc123\",\n * // collection: \"org.hypercerts.claim.activity\",\n * // rkey: \"3km2vj4kfqp2a\"\n * // }\n * ```\n */\nexport function parseAtUri(uri: string): AtUriComponents {\n if (!uri.startsWith(\"at://\")) {\n throw new Error(`Invalid AT-URI format: must start with \"at://\", got \"${uri}\"`);\n }\n\n const withoutProtocol = uri.slice(5); // Remove \"at://\"\n const parts = withoutProtocol.split(\"/\");\n\n if (parts.length !== 3) {\n throw new Error(`Invalid AT-URI format: expected \"at://{did}/{collection}/{rkey}\", got \"${uri}\"`);\n }\n\n const [did, collection, rkey] = parts;\n\n if (!did || !collection || !rkey) {\n throw new Error(`Invalid AT-URI format: all components must be non-empty, got \"${uri}\"`);\n }\n\n return { did, collection, rkey };\n}\n\n/**\n * Build an AT-URI from its component parts.\n *\n * Constructs a valid AT-URI string from a DID, collection NSID, and record key.\n * The resulting URI follows the format: `at://{did}/{collection}/{rkey}`\n *\n * @param did - The repository owner's DID\n * @param collection - The collection NSID (lexicon identifier)\n * @param rkey - The record key (TID or custom string)\n * @returns The complete AT-URI\n *\n * @example\n * ```typescript\n * const uri = buildAtUri(\n * \"did:plc:abc123\",\n * \"org.hypercerts.claim.activity\",\n * \"3km2vj4kfqp2a\"\n * );\n * console.log(uri); // \"at://did:plc:abc123/org.hypercerts.claim.activity/3km2vj4kfqp2a\"\n * ```\n */\nexport function buildAtUri(did: string, collection: string, rkey: string): string {\n if (!did || !collection || !rkey) {\n throw new Error(\"All AT-URI components (did, collection, rkey) must be non-empty\");\n }\n\n return `at://${did}/${collection}/${rkey}`;\n}\n\n/**\n * Extract the record key (TID or custom key) from an AT-URI.\n *\n * Returns the last component of the AT-URI, which is the record key.\n * This is equivalent to `parseAtUri(uri).rkey` but more efficient.\n *\n * @param uri - The AT-URI to extract from\n * @returns The record key (TID or custom string)\n * @throws {Error} If the URI format is invalid\n *\n * @example\n * ```typescript\n * const rkey = extractRkeyFromUri(\"at://did:plc:abc123/org.hypercerts.claim.activity/3km2vj4kfqp2a\");\n * console.log(rkey); // \"3km2vj4kfqp2a\"\n * ```\n */\nexport function extractRkeyFromUri(uri: string): string {\n const { rkey } = parseAtUri(uri);\n return rkey;\n}\n\n/**\n * Check if a string is a valid AT-URI format.\n *\n * Validates that the string follows the AT-URI format without throwing errors.\n * This is useful for input validation before parsing.\n *\n * @param uri - The string to validate\n * @returns True if the string is a valid AT-URI, false otherwise\n *\n * @example\n * ```typescript\n * if (isValidAtUri(userInput)) {\n * const components = parseAtUri(userInput);\n * // ... use components\n * } else {\n * console.error(\"Invalid AT-URI\");\n * }\n * ```\n */\nexport function isValidAtUri(uri: string): boolean {\n try {\n parseAtUri(uri);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Create a strongRef from a URI and CID.\n *\n * StrongRefs are the canonical way to reference specific versions of records\n * in AT Protocol. They combine an AT-URI (which identifies the record) with\n * a CID (which identifies the specific version).\n *\n * @param uri - The AT-URI of the record\n * @param cid - The CID (Content Identifier) of the record version\n * @returns A strongRef object\n *\n * @example\n * ```typescript\n * const ref = createStrongRef(\n * \"at://did:plc:abc123/org.hypercerts.claim.activity/3km2vj4kfqp2a\",\n * \"bafyreiabc123...\"\n * );\n * console.log(ref);\n * // {\n * // uri: \"at://did:plc:abc123/org.hypercerts.claim.activity/3km2vj4kfqp2a\",\n * // cid: \"bafyreiabc123...\"\n * // }\n * ```\n */\nexport function createStrongRef(uri: string, cid: string): StrongRef {\n if (!uri || !cid) {\n throw new Error(\"Both uri and cid are required to create a strongRef\");\n }\n\n return { uri, cid };\n}\n\n/**\n * Create a strongRef from a CreateResult or UpdateResult.\n *\n * This is a convenience function that extracts the URI and CID from\n * the result of a record creation or update operation.\n *\n * @param result - The result from creating or updating a record\n * @returns A strongRef object\n *\n * @example\n * ```typescript\n * const hypercert = await repo.hypercerts.create({\n * title: \"Climate Research\",\n * // ... other params\n * });\n *\n * const ref = createStrongRefFromResult(hypercert);\n * // Now use ref in another record to reference this hypercert\n * ```\n */\nexport function createStrongRefFromResult(result: CreateResult | UpdateResult): StrongRef {\n return createStrongRef(result.uri, result.cid);\n}\n\n/**\n * Validate that an object is a valid strongRef.\n *\n * Checks that the object has the required `uri` and `cid` properties\n * and that they are non-empty strings.\n *\n * @param ref - The object to validate\n * @returns True if the object is a valid strongRef, false otherwise\n *\n * @example\n * ```typescript\n * const maybeRef = { uri: \"at://...\", cid: \"bafyrei...\" };\n * if (validateStrongRef(maybeRef)) {\n * // Safe to use as strongRef\n * record.subject = maybeRef;\n * }\n * ```\n */\nexport function validateStrongRef(ref: unknown): ref is StrongRef {\n if (!ref || typeof ref !== \"object\") {\n return false;\n }\n\n const obj = ref as Record<string, unknown>;\n return typeof obj.uri === \"string\" && obj.uri.length > 0 && typeof obj.cid === \"string\" && obj.cid.length > 0;\n}\n\n/**\n * Type guard to check if a value is a strongRef.\n *\n * This is an alias for `validateStrongRef` that provides better semantics\n * for type narrowing in TypeScript.\n *\n * @param value - The value to check\n * @returns True if the value is a strongRef, false otherwise\n *\n * @example\n * ```typescript\n * function processReference(ref: unknown) {\n * if (isStrongRef(ref)) {\n * // TypeScript knows ref is StrongRef here\n * console.log(ref.uri);\n * }\n * }\n * ```\n */\nexport function isStrongRef(value: unknown): value is StrongRef {\n return validateStrongRef(value);\n}\n","/**\n * Lexicon Builder Utilities\n *\n * This module provides utilities for constructing lexicon JSON schemas programmatically.\n * These builders help developers create valid AT Protocol lexicons with proper structure\n * and type-safe field definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Lexicon field type definitions.\n */\nexport type LexiconFieldType =\n | \"string\"\n | \"integer\"\n | \"boolean\"\n | \"number\"\n | \"datetime\"\n | \"blob\"\n | \"ref\"\n | \"array\"\n | \"object\"\n | \"unknown\";\n\n/**\n * Base lexicon field definition.\n */\nexport interface LexiconFieldBase {\n type: LexiconFieldType;\n description?: string;\n}\n\n/**\n * String field definition.\n */\nexport interface LexiconStringField extends LexiconFieldBase {\n type: \"string\";\n format?: \"datetime\" | \"uri\" | \"at-uri\" | \"did\" | \"handle\" | \"at-identifier\" | \"nsid\" | \"cid\";\n minLength?: number;\n maxLength?: number;\n minGraphemes?: number;\n maxGraphemes?: number;\n enum?: string[];\n const?: string;\n default?: string;\n}\n\n/**\n * Integer field definition.\n */\nexport interface LexiconIntegerField extends LexiconFieldBase {\n type: \"integer\";\n minimum?: number;\n maximum?: number;\n enum?: number[];\n const?: number;\n default?: number;\n}\n\n/**\n * Number field definition.\n */\nexport interface LexiconNumberField extends LexiconFieldBase {\n type: \"number\";\n minimum?: number;\n maximum?: number;\n enum?: number[];\n const?: number;\n default?: number;\n}\n\n/**\n * Boolean field definition.\n */\nexport interface LexiconBooleanField extends LexiconFieldBase {\n type: \"boolean\";\n const?: boolean;\n default?: boolean;\n}\n\n/**\n * Reference field definition (for strongRefs).\n */\nexport interface LexiconRefField extends LexiconFieldBase {\n type: \"ref\";\n ref: string; // NSID or \"com.atproto.repo.strongRef\"\n}\n\n/**\n * Array field definition.\n */\nexport interface LexiconArrayField extends LexiconFieldBase {\n type: \"array\";\n items: LexiconField;\n minLength?: number;\n maxLength?: number;\n}\n\n/**\n * Object field definition.\n */\nexport interface LexiconObjectField extends LexiconFieldBase {\n type: \"object\";\n properties?: Record<string, LexiconField>;\n required?: string[];\n}\n\n/**\n * Blob field definition.\n */\nexport interface LexiconBlobField extends LexiconFieldBase {\n type: \"blob\";\n accept?: string[]; // MIME types\n maxSize?: number;\n}\n\n/**\n * Unknown field definition (accepts any type).\n */\nexport interface LexiconUnknownField extends LexiconFieldBase {\n type: \"unknown\";\n}\n\n/**\n * Union of all lexicon field types.\n */\nexport type LexiconField =\n | LexiconStringField\n | LexiconIntegerField\n | LexiconNumberField\n | LexiconBooleanField\n | LexiconRefField\n | LexiconArrayField\n | LexiconObjectField\n | LexiconBlobField\n | LexiconUnknownField;\n\n/**\n * Record definition for a lexicon.\n *\n * Key types:\n * - \"tid\" (default): Server-generated timestamp-based ID\n * - \"any\": Client can specify any valid rkey\n */\nexport interface LexiconRecordDef {\n type: \"record\";\n key?: \"tid\" | \"any\";\n record: {\n type: \"object\";\n required: string[];\n properties: Record<string, LexiconField>;\n };\n}\n\n/**\n * Main lexicon document structure.\n */\nexport interface LexiconDoc {\n lexicon: 1;\n id: string; // NSID\n defs: {\n main: LexiconRecordDef;\n [key: string]: unknown;\n };\n}\n\n/**\n * Create a string field definition.\n *\n * @param options - String field options\n * @returns A lexicon string field definition\n *\n * @example\n * ```typescript\n * const titleField = createStringField({\n * description: \"Title of the item\",\n * minLength: 1,\n * maxLength: 200,\n * });\n * ```\n */\nexport function createStringField(options: Omit<LexiconStringField, \"type\"> = {}): LexiconStringField {\n return { type: \"string\", ...options };\n}\n\n/**\n * Create an integer field definition.\n *\n * @param options - Integer field options\n * @returns A lexicon integer field definition\n *\n * @example\n * ```typescript\n * const scoreField = createIntegerField({\n * description: \"Score from 0 to 100\",\n * minimum: 0,\n * maximum: 100,\n * });\n * ```\n */\nexport function createIntegerField(options: Omit<LexiconIntegerField, \"type\"> = {}): LexiconIntegerField {\n return { type: \"integer\", ...options };\n}\n\n/**\n * Create a number field definition.\n *\n * @param options - Number field options\n * @returns A lexicon number field definition\n *\n * @example\n * ```typescript\n * const weightField = createNumberField({\n * description: \"Weight as decimal\",\n * minimum: 0,\n * maximum: 1,\n * });\n * ```\n */\nexport function createNumberField(options: Omit<LexiconNumberField, \"type\"> = {}): LexiconNumberField {\n return { type: \"number\", ...options };\n}\n\n/**\n * Create a boolean field definition.\n *\n * @param options - Boolean field options\n * @returns A lexicon boolean field definition\n *\n * @example\n * ```typescript\n * const verifiedField = createBooleanField({\n * description: \"Whether the item is verified\",\n * default: false,\n * });\n * ```\n */\nexport function createBooleanField(options: Omit<LexiconBooleanField, \"type\"> = {}): LexiconBooleanField {\n return { type: \"boolean\", ...options };\n}\n\n/**\n * Create a strongRef field definition.\n *\n * StrongRefs are the standard way to reference other records in AT Protocol.\n * They contain both the AT-URI and CID of the referenced record.\n *\n * @param options - Reference field options\n * @returns A lexicon reference field definition\n *\n * @example\n * ```typescript\n * const subjectField = createStrongRefField({\n * description: \"The hypercert being evaluated\",\n * });\n * ```\n */\nexport function createStrongRefField(\n options: Omit<LexiconRefField, \"type\" | \"ref\"> & { ref?: string } = {},\n): LexiconRefField {\n return {\n type: \"ref\",\n ref: options.ref || \"com.atproto.repo.strongRef\",\n description: options.description,\n };\n}\n\n/**\n * Create an array field definition.\n *\n * @param itemType - The type of items in the array\n * @param options - Array field options\n * @returns A lexicon array field definition\n *\n * @example\n * ```typescript\n * const tagsField = createArrayField(\n * createStringField({ maxLength: 50 }),\n * {\n * description: \"List of tags\",\n * minLength: 1,\n * maxLength: 10,\n * }\n * );\n * ```\n */\nexport function createArrayField(\n itemType: LexiconField,\n options: Omit<LexiconArrayField, \"type\" | \"items\"> = {},\n): LexiconArrayField {\n return {\n type: \"array\",\n items: itemType,\n ...options,\n };\n}\n\n/**\n * Create an object field definition.\n *\n * @param options - Object field options\n * @returns A lexicon object field definition\n *\n * @example\n * ```typescript\n * const metadataField = createObjectField({\n * description: \"Additional metadata\",\n * properties: {\n * author: createStringField(),\n * version: createIntegerField(),\n * },\n * required: [\"author\"],\n * });\n * ```\n */\nexport function createObjectField(options: Omit<LexiconObjectField, \"type\"> = {}): LexiconObjectField {\n return { type: \"object\", ...options };\n}\n\n/**\n * Create a blob field definition.\n *\n * @param options - Blob field options\n * @returns A lexicon blob field definition\n *\n * @example\n * ```typescript\n * const imageField = createBlobField({\n * description: \"Profile image\",\n * accept: [\"image/png\", \"image/jpeg\"],\n * maxSize: 1000000, // 1MB\n * });\n * ```\n */\nexport function createBlobField(options: Omit<LexiconBlobField, \"type\"> = {}): LexiconBlobField {\n return { type: \"blob\", ...options };\n}\n\n/**\n * Create a datetime string field.\n *\n * This is a convenience function for creating string fields with datetime format.\n *\n * @param options - String field options\n * @returns A lexicon string field with datetime format\n *\n * @example\n * ```typescript\n * const createdAtField = createDatetimeField({\n * description: \"When the record was created\",\n * });\n * ```\n */\nexport function createDatetimeField(options: Omit<LexiconStringField, \"type\" | \"format\"> = {}): LexiconStringField {\n return {\n type: \"string\",\n format: \"datetime\",\n ...options,\n };\n}\n\n/**\n * Create a record definition.\n *\n * This defines the structure of records in your lexicon.\n *\n * @param properties - The record's properties (fields)\n * @param required - Array of required field names\n * @param keyType - The type of record key (\"tid\" for server-generated, \"any\" for custom)\n * @returns A lexicon record definition\n *\n * @example\n * ```typescript\n * const recordDef = createRecordDef(\n * {\n * $type: createStringField({ const: \"org.myapp.evaluation\" }),\n * subject: createStrongRefField({ description: \"The evaluated item\" }),\n * score: createIntegerField({ minimum: 0, maximum: 100 }),\n * createdAt: createDatetimeField(),\n * },\n * [\"$type\", \"subject\", \"score\", \"createdAt\"],\n * \"tid\"\n * );\n * ```\n */\nexport function createRecordDef(\n properties: Record<string, LexiconField>,\n required: string[],\n keyType: \"tid\" | \"any\" = \"tid\",\n): LexiconRecordDef {\n return {\n type: \"record\",\n key: keyType,\n record: {\n type: \"object\",\n required,\n properties,\n },\n };\n}\n\n/**\n * Create a complete lexicon document.\n *\n * This creates a full lexicon JSON structure that can be registered with the SDK.\n *\n * @param nsid - The NSID (Namespaced Identifier) for this lexicon\n * @param properties - The record's properties (fields)\n * @param required - Array of required field names\n * @param keyType - The type of record key (\"tid\" for server-generated, \"any\" for custom)\n * @returns A complete lexicon document\n *\n * @example\n * ```typescript\n * const lexicon = createLexiconDoc(\n * \"org.myapp.evaluation\",\n * {\n * $type: createStringField({ const: \"org.myapp.evaluation\" }),\n * subject: createStrongRefField({ description: \"The evaluated item\" }),\n * score: createIntegerField({ minimum: 0, maximum: 100 }),\n * methodology: createStringField({ maxLength: 500 }),\n * createdAt: createDatetimeField(),\n * },\n * [\"$type\", \"subject\", \"score\", \"createdAt\"],\n * \"tid\"\n * );\n *\n * // Register with SDK\n * sdk.getLexiconRegistry().registerFromJSON(lexicon);\n * ```\n */\nexport function createLexiconDoc(\n nsid: string,\n properties: Record<string, LexiconField>,\n required: string[],\n keyType: \"tid\" | \"any\" = \"tid\",\n): LexiconDoc {\n return {\n lexicon: 1,\n id: nsid,\n defs: {\n main: createRecordDef(properties, required, keyType),\n },\n };\n}\n\n/**\n * Validate a lexicon document structure.\n *\n * Performs basic validation to ensure the lexicon follows AT Protocol conventions.\n * This does NOT perform full JSON schema validation.\n *\n * @param lexicon - The lexicon document to validate\n * @returns True if valid, false otherwise\n *\n * @example\n * ```typescript\n * const lexicon = createLexiconDoc(...);\n * if (validateLexiconStructure(lexicon)) {\n * sdk.getLexiconRegistry().registerFromJSON(lexicon);\n * } else {\n * console.error(\"Invalid lexicon structure\");\n * }\n * ```\n */\nexport function validateLexiconStructure(lexicon: unknown): lexicon is LexiconDoc {\n if (!lexicon || typeof lexicon !== \"object\") {\n return false;\n }\n\n const doc = lexicon as Record<string, unknown>;\n\n // Check required top-level fields\n if (doc.lexicon !== 1) return false;\n if (typeof doc.id !== \"string\" || !doc.id) return false;\n if (!doc.defs || typeof doc.defs !== \"object\") return false;\n\n const defs = doc.defs as Record<string, unknown>;\n if (!defs.main || typeof defs.main !== \"object\") return false;\n\n const main = defs.main as Record<string, unknown>;\n if (main.type !== \"record\") return false;\n if (!main.record || typeof main.record !== \"object\") return false;\n\n const record = main.record as Record<string, unknown>;\n if (record.type !== \"object\") return false;\n if (!Array.isArray(record.required)) return false;\n if (!record.properties || typeof record.properties !== \"object\") return false;\n\n return true;\n}\n","/**\n * Sidecar Pattern Utilities\n *\n * This module provides utilities for implementing the AT Protocol \"sidecar pattern\"\n * where additional records are created that reference a main record via StrongRef.\n *\n * ## The Sidecar Pattern\n *\n * In AT Protocol, the sidecar pattern uses **unidirectional references**:\n * - Sidecar records contain a StrongRef (uri + cid) pointing to the main record\n * - Main records do NOT maintain back-references to sidecars\n * - Sidecars are discovered by querying records that reference the main record\n * - Optionally, sidecars can use the same rkey as the main record (in different collections)\n *\n * ## Example Use Cases\n *\n * - Evaluations that reference hypercerts\n * - Comments that reference posts\n * - Metadata records that reference primary entities\n *\n * @see https://atproto.com/specs/record-key\n * @see https://atproto.com/specs/data-model\n *\n * @packageDocumentation\n */\n\nimport type { Repository } from \"../repository/Repository.js\";\nimport type { CreateResult } from \"../repository/types.js\";\n\n/**\n * Parameters for creating a sidecar record.\n */\nexport interface SidecarRecordParams {\n /** The collection NSID for the sidecar record */\n collection: string;\n /** The record data */\n record: Record<string, unknown>;\n /** Optional custom rkey */\n rkey?: string;\n}\n\n/**\n * Result from creating a sidecar record.\n */\nexport interface SidecarResult {\n /** The main record that was referenced */\n mainRecord: CreateResult;\n /** The sidecar record that was created */\n sidecarRecord: CreateResult;\n}\n\n/**\n * Parameters for attaching a sidecar to an existing record.\n */\nexport interface AttachSidecarParams {\n /** The main record to reference */\n mainRecord: { uri: string; cid: string };\n /** The sidecar record to create */\n sidecar: SidecarRecordParams;\n}\n\n/**\n * Result from creating multiple sidecars.\n */\nexport interface MultiSidecarResult {\n /** The main record that was created */\n main: CreateResult;\n /** The sidecar records that were created */\n sidecars: CreateResult[];\n}\n\n/**\n * Parameters for creating a main record with multiple sidecars.\n */\nexport interface CreateWithSidecarsParams {\n /** The main record to create */\n main: SidecarRecordParams;\n /** The sidecar records to create (can reference the main record via placeholder) */\n sidecars: SidecarRecordParams[];\n}\n\n/**\n * Create a sidecar record that references an existing record.\n *\n * This is a low-level utility that creates a single sidecar record. The sidecar\n * record should include a strongRef field that points to the main record.\n *\n * @param repo - The repository instance\n * @param collection - The collection NSID for the sidecar\n * @param record - The sidecar record data (should include a strongRef to the main record)\n * @param options - Optional creation options\n * @returns The created sidecar record\n *\n * @example\n * ```typescript\n * const hypercert = await repo.hypercerts.create({...});\n *\n * const evaluation = await createSidecarRecord(\n * repo,\n * \"org.myapp.evaluation\",\n * {\n * $type: \"org.myapp.evaluation\",\n * subject: { uri: hypercert.hypercertUri, cid: hypercert.hypercertCid },\n * score: 85,\n * createdAt: new Date().toISOString(),\n * }\n * );\n * ```\n */\nexport async function createSidecarRecord(\n repo: Repository,\n collection: string,\n record: Record<string, unknown>,\n options: { rkey?: string } = {},\n): Promise<CreateResult> {\n return await repo.records.create({\n collection,\n record,\n rkey: options.rkey,\n });\n}\n\n/**\n * Attach a sidecar record to an existing main record.\n *\n * This creates a new record that references an existing record via strongRef.\n * It's a higher-level convenience function that wraps `createSidecarRecord`.\n *\n * @param repo - The repository instance\n * @param params - Parameters including the main record reference and sidecar definition\n * @returns Both the main record reference and the created sidecar\n *\n * @example\n * ```typescript\n * const hypercert = await repo.hypercerts.create({...});\n *\n * const result = await attachSidecar(repo, {\n * mainRecord: {\n * uri: hypercert.hypercertUri,\n * cid: hypercert.hypercertCid,\n * },\n * sidecar: {\n * collection: \"org.myapp.evaluation\",\n * record: {\n * $type: \"org.myapp.evaluation\",\n * subject: { uri: hypercert.hypercertUri, cid: hypercert.hypercertCid },\n * score: 85,\n * createdAt: new Date().toISOString(),\n * },\n * },\n * });\n * ```\n */\nexport async function attachSidecar(repo: Repository, params: AttachSidecarParams): Promise<SidecarResult> {\n const sidecarRecord = await createSidecarRecord(repo, params.sidecar.collection, params.sidecar.record, {\n rkey: params.sidecar.rkey,\n });\n\n return {\n mainRecord: params.mainRecord,\n sidecarRecord,\n };\n}\n\n/**\n * Create a main record and multiple sidecar records in sequence.\n *\n * This orchestrates the creation of a main record followed by one or more\n * sidecar records that reference it. This is useful for workflows like:\n * - Creating a project with multiple hypercert claims\n * - Creating a hypercert with evidence and evaluation records\n *\n * @param repo - The repository instance\n * @param params - Parameters including the main record and sidecar definitions\n * @returns The main record and all created sidecar records\n *\n * @example\n * ```typescript\n * const result = await createWithSidecars(repo, {\n * main: {\n * collection: \"org.hypercerts.project\",\n * record: {\n * $type: \"org.hypercerts.project\",\n * title: \"Climate Initiative 2024\",\n * description: \"Our climate work\",\n * createdAt: new Date().toISOString(),\n * },\n * },\n * sidecars: [\n * {\n * collection: \"org.hypercerts.claim.activity\",\n * record: {\n * $type: \"org.hypercerts.claim.activity\",\n * title: \"Tree Planting\",\n * // ... other hypercert fields\n * // Note: If you need to reference the main record, you must wait\n * // for result.main and then call batchCreateSidecars separately\n * },\n * },\n * {\n * collection: \"org.hypercerts.claim.activity\",\n * record: {\n * $type: \"org.hypercerts.claim.activity\",\n * title: \"Carbon Measurement\",\n * // ... other hypercert fields\n * },\n * },\n * ],\n * });\n *\n * console.log(result.main.uri); // Main project record\n * console.log(result.sidecars.length); // 2 hypercert sidecars\n * ```\n */\nexport async function createWithSidecars(\n repo: Repository,\n params: CreateWithSidecarsParams,\n): Promise<MultiSidecarResult> {\n // Create the main record first\n const main = await repo.records.create({\n collection: params.main.collection,\n record: params.main.record,\n rkey: params.main.rkey,\n });\n\n // Create all sidecar records\n const sidecars: CreateResult[] = [];\n for (const sidecar of params.sidecars) {\n const created = await repo.records.create({\n collection: sidecar.collection,\n record: sidecar.record,\n rkey: sidecar.rkey,\n });\n\n sidecars.push(created);\n }\n\n return { main, sidecars };\n}\n\n/**\n * Batch create multiple sidecar records.\n *\n * This is useful when you want to add multiple related records\n * efficiently. The sidecar records should already contain any necessary\n * references to the main record in their data.\n *\n * @param repo - The repository instance\n * @param sidecars - Array of sidecar definitions (records should include references)\n * @returns Array of created sidecar records\n *\n * @example\n * ```typescript\n * const hypercert = await repo.hypercerts.create({...});\n * const mainRef = { uri: hypercert.hypercertUri, cid: hypercert.hypercertCid };\n *\n * const evaluations = await batchCreateSidecars(repo, [\n * {\n * collection: \"org.myapp.evaluation\",\n * record: {\n * $type: \"org.myapp.evaluation\",\n * subject: mainRef, // Reference already included\n * score: 85,\n * methodology: \"Peer review\",\n * createdAt: new Date().toISOString(),\n * },\n * },\n * {\n * collection: \"org.myapp.comment\",\n * record: {\n * $type: \"org.myapp.comment\",\n * subject: mainRef, // Reference already included\n * text: \"Great work!\",\n * createdAt: new Date().toISOString(),\n * },\n * },\n * ]);\n * ```\n */\nexport async function batchCreateSidecars(repo: Repository, sidecars: SidecarRecordParams[]): Promise<CreateResult[]> {\n const results: CreateResult[] = [];\n\n for (const sidecar of sidecars) {\n const result = await createSidecarRecord(repo, sidecar.collection, sidecar.record, {\n rkey: sidecar.rkey,\n });\n results.push(result);\n }\n\n return results;\n}\n","import type { OAuthSession } from \"@atproto/oauth-client-node\";\nimport { z } from \"zod\";\n\n/**\n * Decentralized Identifier (DID) - a unique, persistent identifier for AT Protocol users.\n *\n * DIDs are the canonical identifier for users in the AT Protocol ecosystem.\n * Unlike handles which can change, DIDs remain constant for the lifetime of an account.\n *\n * @remarks\n * AT Protocol supports multiple DID methods:\n * - `did:plc:` - PLC (Public Ledger of Credentials) DIDs, most common for Bluesky users\n * - `did:web:` - Web DIDs, resolved via HTTPS\n *\n * @example\n * ```typescript\n * const did: DID = \"did:plc:ewvi7nxzyoun6zhxrhs64oiz\";\n * const webDid: DID = \"did:web:example.com\";\n * ```\n *\n * @see https://atproto.com/specs/did for DID specification\n */\nexport type DID = string;\n\n/**\n * OAuth session with DPoP (Demonstrating Proof of Possession) support.\n *\n * This type represents an authenticated user session. It wraps the\n * `@atproto/oauth-client-node` OAuthSession and contains:\n * - Access token for API requests\n * - Refresh token for obtaining new access tokens\n * - DPoP key pair for proof-of-possession\n * - User's DID and other identity information\n *\n * @remarks\n * Sessions are managed by the SDK and automatically refresh when tokens expire.\n * Store the user's DID to restore sessions later with {@link ATProtoSDK.restoreSession}.\n *\n * Key properties from OAuthSession:\n * - `did` or `sub`: The user's DID\n * - `handle`: The user's handle (e.g., \"user.bsky.social\")\n *\n * @example\n * ```typescript\n * const session = await sdk.callback(params);\n *\n * // Access user identity\n * console.log(`Logged in as: ${session.did}`);\n *\n * // Use session for repository operations\n * const repo = sdk.repository(session);\n * ```\n *\n * @see https://atproto.com/specs/oauth for OAuth specification\n */\nexport type Session = OAuthSession;\n\n/**\n * Zod schema for collaborator permissions in SDS repositories.\n *\n * Defines the granular permissions a collaborator can have on a shared repository.\n * Permissions follow a hierarchical model where higher-level permissions\n * typically imply lower-level ones.\n */\nexport const CollaboratorPermissionsSchema = z.object({\n /**\n * Can read/view records in the repository.\n * This is the most basic permission level.\n */\n read: z.boolean(),\n\n /**\n * Can create new records in the repository.\n * Typically implies `read` permission.\n */\n create: z.boolean(),\n\n /**\n * Can modify existing records in the repository.\n * Typically implies `read` and `create` permissions.\n */\n update: z.boolean(),\n\n /**\n * Can delete records from the repository.\n * Typically implies `read`, `create`, and `update` permissions.\n */\n delete: z.boolean(),\n\n /**\n * Can manage collaborators and their permissions.\n * Administrative permission that allows inviting/removing collaborators.\n */\n admin: z.boolean(),\n\n /**\n * Full ownership of the repository.\n * Owners have all permissions and cannot be removed by other admins.\n * There must always be at least one owner.\n */\n owner: z.boolean(),\n});\n\n/**\n * Collaborator permissions for SDS (Shared Data Server) repositories.\n *\n * These permissions control what actions a collaborator can perform\n * on records within a shared repository.\n *\n * @example\n * ```typescript\n * // Read-only collaborator\n * const readOnlyPerms: CollaboratorPermissions = {\n * read: true,\n * create: false,\n * update: false,\n * delete: false,\n * admin: false,\n * owner: false,\n * };\n *\n * // Editor collaborator\n * const editorPerms: CollaboratorPermissions = {\n * read: true,\n * create: true,\n * update: true,\n * delete: false,\n * admin: false,\n * owner: false,\n * };\n *\n * // Admin collaborator\n * const adminPerms: CollaboratorPermissions = {\n * read: true,\n * create: true,\n * update: true,\n * delete: true,\n * admin: true,\n * owner: false,\n * };\n * ```\n */\nexport type CollaboratorPermissions = z.infer<typeof CollaboratorPermissionsSchema>;\n\n/**\n * Zod schema for SDS organization data.\n *\n * Organizations are top-level entities in SDS that can own repositories\n * and have multiple collaborators with different permission levels.\n */\nexport const OrganizationSchema = z.object({\n /**\n * The organization's DID - unique identifier.\n * Format: \"did:plc:...\" or \"did:web:...\"\n */\n did: z.string(),\n\n /**\n * The organization's handle - human-readable identifier.\n * Format: \"orgname.sds.hypercerts.org\" or similar\n */\n handle: z.string(),\n\n /**\n * Display name for the organization.\n */\n name: z.string(),\n\n /**\n * Optional description of the organization's purpose.\n */\n description: z.string().optional(),\n\n /**\n * ISO 8601 timestamp when the organization was created.\n * Format: \"2024-01-15T10:30:00.000Z\"\n */\n createdAt: z.string(),\n\n /**\n * The current user's permissions within this organization.\n */\n permissions: CollaboratorPermissionsSchema,\n\n /**\n * How the current user relates to this organization.\n * - `\"owner\"`: User created or owns the organization\n * - `\"shared\"`: User was invited to collaborate (has permissions)\n * - `\"none\"`: User has no access to this organization\n */\n accessType: z.enum([\"owner\", \"shared\", \"none\"]),\n});\n\n/**\n * SDS Organization entity.\n *\n * Represents an organization on a Shared Data Server. Organizations\n * provide a way to group repositories and manage access for teams.\n *\n * @example\n * ```typescript\n * const org: Organization = {\n * did: \"did:plc:org123abc\",\n * handle: \"my-team.sds.hypercerts.org\",\n * name: \"My Team\",\n * description: \"A team working on impact certificates\",\n * createdAt: \"2024-01-15T10:30:00.000Z\",\n * permissions: {\n * read: true,\n * create: true,\n * update: true,\n * delete: true,\n * admin: true,\n * owner: true,\n * },\n * accessType: \"owner\",\n * };\n * ```\n */\nexport type Organization = z.infer<typeof OrganizationSchema>;\n\n/**\n * Zod schema for collaborator data.\n *\n * Represents a user who has been granted access to a shared repository\n * or organization with specific permissions.\n */\nexport const CollaboratorSchema = z.object({\n /**\n * The collaborator's DID - their unique identifier.\n * Format: \"did:plc:...\" or \"did:web:...\"\n */\n userDid: z.string(),\n\n /**\n * The permissions granted to this collaborator.\n */\n permissions: CollaboratorPermissionsSchema,\n\n /**\n * DID of the user who granted these permissions.\n * Useful for audit trails.\n */\n grantedBy: z.string(),\n\n /**\n * ISO 8601 timestamp when permissions were granted.\n * Format: \"2024-01-15T10:30:00.000Z\"\n */\n grantedAt: z.string(),\n\n /**\n * ISO 8601 timestamp when permissions were revoked, if applicable.\n * Undefined if the collaborator is still active.\n */\n revokedAt: z.string().optional(),\n});\n\n/**\n * Collaborator information for SDS repositories.\n *\n * Represents a user who has been granted access to collaborate on\n * a shared repository or organization.\n *\n * @example\n * ```typescript\n * const collaborator: Collaborator = {\n * userDid: \"did:plc:user456def\",\n * permissions: {\n * read: true,\n * create: true,\n * update: true,\n * delete: false,\n * admin: false,\n * owner: false,\n * },\n * grantedBy: \"did:plc:owner123abc\",\n * grantedAt: \"2024-02-01T14:00:00.000Z\",\n * };\n * ```\n */\nexport type Collaborator = z.infer<typeof CollaboratorSchema>;\n"],"names":[],"mappings":"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"}
|