@hypercerts-org/sdk-core 0.9.0-beta.0 → 0.10.0-beta.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sources":["../src/core/config.ts","../src/core/types.ts"],"sourcesContent":["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 * Common scopes: \"atproto\", \"transition:generic\"\n */\n scope: z.string(),\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 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":["z"],"mappings":";;;;AAGA;;;;;;AAMG;AACI,MAAM,iBAAiB,GAAGA,KAAC,CAAC,MAAM,CAAC;AACxC;;;;;AAKG;AACH,IAAA,QAAQ,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;AAE1B;;;AAGG;AACH,IAAA,WAAW,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;AAE7B;;;AAGG;AACH,IAAA,KAAK,EAAEA,KAAC,CAAC,MAAM,EAAE;AAEjB;;;AAGG;AACH,IAAA,OAAO,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;AAEzB;;;;;;;AAOG;AACH,IAAA,UAAU,EAAEA,KAAC,CAAC,MAAM,EAAE;AACvB,CAAA;AAED;;;;;AAKG;AACI,MAAM,kBAAkB,GAAGA,KAAC,CAAC,MAAM,CAAC;AACzC;;;;;AAKG;IACH,GAAG,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;AAEhC;;;;;AAKG;IACH,GAAG,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;AACjC,CAAA;AAED;;;;;AAKG;AACI,MAAM,mBAAmB,GAAGA,KAAC,CAAC,MAAM,CAAC;AAC1C;;;AAGG;IACH,WAAW,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;AAE7C;;;AAGG;IACH,WAAW,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;AAC9C,CAAA;AAED;;;;;;;AAOG;AACI,MAAM,sBAAsB,GAAGA,KAAC,CAAC,MAAM,CAAC;AAC7C,IAAA,KAAK,EAAE,iBAAiB;AACxB,IAAA,OAAO,EAAE,kBAAkB,CAAC,QAAQ,EAAE;AACtC,IAAA,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,EAAE;AACzC,CAAA;;AC/CD;;;;;;AAMG;AACI,MAAM,6BAA6B,GAAGA,KAAC,CAAC,MAAM,CAAC;AACpD;;;AAGG;AACH,IAAA,IAAI,EAAEA,KAAC,CAAC,OAAO,EAAE;AAEjB;;;AAGG;AACH,IAAA,MAAM,EAAEA,KAAC,CAAC,OAAO,EAAE;AAEnB;;;AAGG;AACH,IAAA,MAAM,EAAEA,KAAC,CAAC,OAAO,EAAE;AAEnB;;;AAGG;AACH,IAAA,MAAM,EAAEA,KAAC,CAAC,OAAO,EAAE;AAEnB;;;AAGG;AACH,IAAA,KAAK,EAAEA,KAAC,CAAC,OAAO,EAAE;AAElB;;;;AAIG;AACH,IAAA,KAAK,EAAEA,KAAC,CAAC,OAAO,EAAE;AACnB,CAAA;AA2CD;;;;;AAKG;AACI,MAAM,kBAAkB,GAAGA,KAAC,CAAC,MAAM,CAAC;AACzC;;;AAGG;AACH,IAAA,GAAG,EAAEA,KAAC,CAAC,MAAM,EAAE;AAEf;;;AAGG;AACH,IAAA,MAAM,EAAEA,KAAC,CAAC,MAAM,EAAE;AAElB;;AAEG;AACH,IAAA,IAAI,EAAEA,KAAC,CAAC,MAAM,EAAE;AAEhB;;AAEG;AACH,IAAA,WAAW,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;AAElC;;;AAGG;AACH,IAAA,SAAS,EAAEA,KAAC,CAAC,MAAM,EAAE;AAErB;;AAEG;AACH,IAAA,WAAW,EAAE,6BAA6B;AAE1C;;;;;AAKG;AACH,IAAA,UAAU,EAAEA,KAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChD,CAAA;AA8BD;;;;;AAKG;AACI,MAAM,kBAAkB,GAAGA,KAAC,CAAC,MAAM,CAAC;AACzC;;;AAGG;AACH,IAAA,OAAO,EAAEA,KAAC,CAAC,MAAM,EAAE;AAEnB;;AAEG;AACH,IAAA,WAAW,EAAE,6BAA6B;AAE1C;;;AAGG;AACH,IAAA,SAAS,EAAEA,KAAC,CAAC,MAAM,EAAE;AAErB;;;AAGG;AACH,IAAA,SAAS,EAAEA,KAAC,CAAC,MAAM,EAAE;AAErB;;;AAGG;AACH,IAAA,SAAS,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;AACjC,CAAA;;;;;;;;;;"}
1
+ {"version":3,"file":"types.cjs","sources":["../src/core/config.ts","../src/core/types.ts"],"sourcesContent":["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 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":["z"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { OAuthSession, NodeSavedSession, NodeSavedState } from '@atproto/oauth-client-node';
2
2
  import { z } from 'zod';
3
3
  import { EventEmitter } from 'eventemitter3';
4
- import { OrgHypercertsClaim, OrgHypercertsCollection, OrgHypercertsClaimRights, AppCertifiedLocation, OrgHypercertsClaimContribution, OrgHypercertsClaimMeasurement, OrgHypercertsClaimEvaluation } from '@hypercerts-org/lexicon';
4
+ import { OrgHypercertsClaimEvidence, OrgHypercertsClaimActivity, OrgHypercertsClaimCollection, OrgHypercertsClaimRights, AppCertifiedLocation, OrgHypercertsClaimContribution, OrgHypercertsClaimMeasurement, OrgHypercertsClaimEvaluation, OrgHypercertsDefs } from '@hypercerts-org/lexicon';
5
+ export { BlobRef, JsonBlobRef } from '@atproto/lexicon';
5
6
 
6
7
  /**
7
8
  * Decentralized Identifier (DID) - a unique, persistent identifier for AT Protocol users.
@@ -755,7 +756,32 @@ declare const OAuthConfigSchema: z.ZodObject<{
755
756
  redirectUri: z.ZodString;
756
757
  /**
757
758
  * OAuth scopes to request, space-separated.
758
- * Common scopes: "atproto", "transition:generic"
759
+ *
760
+ * Can be a string of space-separated permissions or use the permission system:
761
+ *
762
+ * @example Using presets
763
+ * ```typescript
764
+ * import { ScopePresets } from '@hypercerts-org/sdk-core';
765
+ * scope: ScopePresets.EMAIL_AND_PROFILE
766
+ * ```
767
+ *
768
+ * @example Building custom scopes
769
+ * ```typescript
770
+ * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';
771
+ * scope: buildScope(
772
+ * new PermissionBuilder()
773
+ * .accountEmail('read')
774
+ * .repoWrite('app.bsky.feed.post')
775
+ * .build()
776
+ * )
777
+ * ```
778
+ *
779
+ * @example Legacy scopes
780
+ * ```typescript
781
+ * scope: "atproto transition:generic"
782
+ * ```
783
+ *
784
+ * @see https://atproto.com/specs/permission for permission details
759
785
  */
760
786
  scope: z.ZodString;
761
787
  /**
@@ -861,7 +887,32 @@ declare const ATProtoSDKConfigSchema: z.ZodObject<{
861
887
  redirectUri: z.ZodString;
862
888
  /**
863
889
  * OAuth scopes to request, space-separated.
864
- * Common scopes: "atproto", "transition:generic"
890
+ *
891
+ * Can be a string of space-separated permissions or use the permission system:
892
+ *
893
+ * @example Using presets
894
+ * ```typescript
895
+ * import { ScopePresets } from '@hypercerts-org/sdk-core';
896
+ * scope: ScopePresets.EMAIL_AND_PROFILE
897
+ * ```
898
+ *
899
+ * @example Building custom scopes
900
+ * ```typescript
901
+ * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';
902
+ * scope: buildScope(
903
+ * new PermissionBuilder()
904
+ * .accountEmail('read')
905
+ * .repoWrite('app.bsky.feed.post')
906
+ * .build()
907
+ * )
908
+ * ```
909
+ *
910
+ * @example Legacy scopes
911
+ * ```typescript
912
+ * scope: "atproto transition:generic"
913
+ * ```
914
+ *
915
+ * @see https://atproto.com/specs/permission for permission details
865
916
  */
866
917
  scope: z.ZodString;
867
918
  /**
@@ -1095,22 +1146,6 @@ interface ATProtoSDKConfig {
1095
1146
  logger?: LoggerInterface;
1096
1147
  }
1097
1148
 
1098
- /**
1099
- * Result of validating a record against a lexicon schema.
1100
- */
1101
- interface ValidationResult {
1102
- /**
1103
- * Whether the record is valid according to the lexicon schema.
1104
- */
1105
- valid: boolean;
1106
- /**
1107
- * Error message if validation failed.
1108
- *
1109
- * Only present when `valid` is `false`.
1110
- */
1111
- error?: string;
1112
- }
1113
-
1114
1149
  /**
1115
1150
  * Repository types - Shared types for repository operations
1116
1151
  * @packageDocumentation
@@ -1205,30 +1240,27 @@ interface ProgressStep {
1205
1240
  * @packageDocumentation
1206
1241
  */
1207
1242
 
1208
- type HypercertClaim = OrgHypercertsClaim.Main;
1243
+ type HypercertClaim = OrgHypercertsClaimActivity.Main;
1209
1244
  type HypercertRights = OrgHypercertsClaimRights.Main;
1210
1245
  type HypercertContribution = OrgHypercertsClaimContribution.Main;
1211
1246
  type HypercertMeasurement = OrgHypercertsClaimMeasurement.Main;
1212
1247
  type HypercertEvaluation = OrgHypercertsClaimEvaluation.Main;
1213
- type HypercertCollection = OrgHypercertsCollection.Main;
1214
- type HypercertCollectionClaimItem = OrgHypercertsCollection.ClaimItem;
1248
+ type HypercertEvidence = OrgHypercertsClaimEvidence.Main;
1249
+ type HypercertCollection = OrgHypercertsClaimCollection.Main;
1250
+ type HypercertCollectionClaimItem = OrgHypercertsClaimActivity.ActivityWeight;
1215
1251
  type HypercertLocation = AppCertifiedLocation.Main;
1216
- /** Blob reference for uploaded files (images, GeoJSON, etc.) */
1217
- interface BlobRef {
1218
- $type: "blob";
1219
- ref: {
1220
- $link: string;
1221
- };
1222
- mimeType: string;
1223
- size: number;
1224
- }
1225
- /** Evidence item for operations */
1226
- interface HypercertEvidence {
1227
- uri: string;
1228
- title?: string;
1229
- description?: string;
1230
- }
1231
- /** Image input for operations */
1252
+ /**
1253
+ * Image input for SDK operations.
1254
+ *
1255
+ * Can be either:
1256
+ * - A URI reference (for external images)
1257
+ * - A Blob to be uploaded
1258
+ *
1259
+ * The SDK will convert these to the appropriate lexicon types:
1260
+ * - OrgHypercertsDefs.Uri
1261
+ * - OrgHypercertsDefs.SmallImage
1262
+ * - OrgHypercertsDefs.LargeImage
1263
+ */
1232
1264
  type HypercertImage = {
1233
1265
  type: "uri";
1234
1266
  uri: string;
@@ -1236,6 +1268,11 @@ type HypercertImage = {
1236
1268
  type: "blob";
1237
1269
  blob: Blob;
1238
1270
  };
1271
+ /**
1272
+ * Lexicon-defined image types (union of Uri and image blob types).
1273
+ * Use this when working with stored records.
1274
+ */
1275
+ type HypercertImageRecord = OrgHypercertsDefs.Uri | OrgHypercertsDefs.SmallImage | OrgHypercertsDefs.LargeImage;
1239
1276
  /** Hypercert with AT Protocol metadata */
1240
1277
  interface HypercertWithMetadata {
1241
1278
  uri: string;
@@ -2145,17 +2182,51 @@ interface AuthorizeOptions {
2145
2182
  * OAuth scope string to request specific permissions.
2146
2183
  * Overrides the default scope configured in {@link ATProtoSDKConfig.oauth.scope}.
2147
2184
  *
2148
- * @example
2185
+ * Can use the permission system for type-safe scope building.
2186
+ *
2187
+ * @example Using presets
2188
+ * ```typescript
2189
+ * import { ScopePresets } from '@hypercerts-org/sdk-core';
2190
+ *
2191
+ * // Request email and profile access
2192
+ * await sdk.authorize("user.bsky.social", {
2193
+ * scope: ScopePresets.EMAIL_AND_PROFILE
2194
+ * });
2195
+ *
2196
+ * // Request full posting capabilities
2197
+ * await sdk.authorize("user.bsky.social", {
2198
+ * scope: ScopePresets.POSTING_APP
2199
+ * });
2200
+ * ```
2201
+ *
2202
+ * @example Building custom scopes
2203
+ * ```typescript
2204
+ * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';
2205
+ *
2206
+ * const scope = buildScope(
2207
+ * new PermissionBuilder()
2208
+ * .accountEmail('read')
2209
+ * .repoWrite('app.bsky.feed.post')
2210
+ * .blob(['image/*'])
2211
+ * .build()
2212
+ * );
2213
+ *
2214
+ * await sdk.authorize("user.bsky.social", { scope });
2215
+ * ```
2216
+ *
2217
+ * @example Legacy scopes
2149
2218
  * ```typescript
2150
2219
  * // Request read-only access
2151
2220
  * await sdk.authorize("user.bsky.social", { scope: "atproto" });
2152
2221
  *
2153
- * // Request full access (default typically includes transition:generic)
2154
- * await sdk.authorize("user.bsky.social", { scope: "atproto transition:generic" });
2222
+ * // Request full access (legacy)
2223
+ * await sdk.authorize("user.bsky.social", {
2224
+ * scope: "atproto transition:generic"
2225
+ * });
2155
2226
  * ```
2156
2227
  */
2157
2228
  scope?: string;
2158
2229
  }
2159
2230
 
2160
2231
  export { ATProtoSDKConfigSchema, CollaboratorPermissionsSchema, CollaboratorSchema, OAuthConfigSchema, OrganizationSchema, ServerConfigSchema, TimeoutConfigSchema };
2161
- export type { ATProtoSDKConfig, AuthorizeOptions, BlobOperations, BlobRef, CacheInterface, Collaborator, CollaboratorOperations, CollaboratorPermissions, CreateHypercertParams, CreateHypercertResult, CreateResult, DID, HypercertClaim, HypercertCollection, HypercertCollectionClaimItem, HypercertContribution, HypercertEvaluation, HypercertEvents, HypercertEvidence, HypercertImage, HypercertLocation, HypercertMeasurement, HypercertOperations, HypercertRights, HypercertWithMetadata, ListParams, LoggerInterface, Organization, OrganizationInfo, OrganizationOperations, PaginatedList, ProfileOperations, ProgressStep, RecordOperations, RepositoryAccessGrant, RepositoryOptions, RepositoryRole, Session, SessionStore, StateStore, UpdateResult, ValidationResult };
2232
+ export type { ATProtoSDKConfig, AuthorizeOptions, BlobOperations, CacheInterface, Collaborator, CollaboratorOperations, CollaboratorPermissions, CreateHypercertParams, CreateHypercertResult, CreateResult, DID, HypercertClaim, HypercertCollection, HypercertCollectionClaimItem, HypercertContribution, HypercertEvaluation, HypercertEvents, HypercertEvidence, HypercertImage, HypercertImageRecord, HypercertLocation, HypercertMeasurement, HypercertOperations, HypercertRights, HypercertWithMetadata, ListParams, LoggerInterface, Organization, OrganizationInfo, OrganizationOperations, PaginatedList, ProfileOperations, ProgressStep, RecordOperations, RepositoryAccessGrant, RepositoryOptions, RepositoryRole, Session, SessionStore, StateStore, UpdateResult };
package/dist/types.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import { z } from 'zod';
2
+ export { BlobRef } from '@atproto/lexicon';
3
+ import '@hypercerts-org/lexicon';
2
4
 
3
5
  /**
4
6
  * Zod schema for OAuth configuration validation.
@@ -22,9 +24,34 @@ const OAuthConfigSchema = z.object({
22
24
  redirectUri: z.string().url(),
23
25
  /**
24
26
  * OAuth scopes to request, space-separated.
25
- * Common scopes: "atproto", "transition:generic"
27
+ *
28
+ * Can be a string of space-separated permissions or use the permission system:
29
+ *
30
+ * @example Using presets
31
+ * ```typescript
32
+ * import { ScopePresets } from '@hypercerts-org/sdk-core';
33
+ * scope: ScopePresets.EMAIL_AND_PROFILE
34
+ * ```
35
+ *
36
+ * @example Building custom scopes
37
+ * ```typescript
38
+ * import { PermissionBuilder, buildScope } from '@hypercerts-org/sdk-core';
39
+ * scope: buildScope(
40
+ * new PermissionBuilder()
41
+ * .accountEmail('read')
42
+ * .repoWrite('app.bsky.feed.post')
43
+ * .build()
44
+ * )
45
+ * ```
46
+ *
47
+ * @example Legacy scopes
48
+ * ```typescript
49
+ * scope: "atproto transition:generic"
50
+ * ```
51
+ *
52
+ * @see https://atproto.com/specs/permission for permission details
26
53
  */
27
- scope: z.string(),
54
+ scope: z.string().min(1, "OAuth scope is required"),
28
55
  /**
29
56
  * URL to your public JWKS (JSON Web Key Set) endpoint.
30
57
  * Used by the authorization server to verify your client's signatures.
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":["../src/core/config.ts","../src/core/types.ts"],"sourcesContent":["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 * Common scopes: \"atproto\", \"transition:generic\"\n */\n scope: z.string(),\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 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":"types.mjs","sources":["../src/core/config.ts","../src/core/types.ts"],"sourcesContent":["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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypercerts-org/sdk-core",
3
- "version": "0.9.0-beta.0",
3
+ "version": "0.10.0-beta.1",
4
4
  "description": "Framework-agnostic ATProto SDK core for authentication, repository operations, and lexicon management",
5
5
  "main": "dist/index.cjs",
6
6
  "repository": {
@@ -12,8 +12,10 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
- "README.md"
15
+ "README.md",
16
+ "CHANGELOG.md"
16
17
  ],
18
+ "prepublishOnly": "pnpm run check",
17
19
  "keywords": [
18
20
  "atproto",
19
21
  "hypercerts",
@@ -29,12 +31,9 @@
29
31
  "@rollup/plugin-node-resolve": "^16.0.3",
30
32
  "@rollup/plugin-typescript": "^12.3.0",
31
33
  "@types/node": ">=20.10.0",
32
- "@vitest/coverage-v8": "^3.2.4",
33
- "@vitest/ui": "^3.2.4",
34
34
  "jose": "^6.1.3",
35
35
  "rollup": "^4.53.3",
36
- "rollup-plugin-dts": "^6.2.3",
37
- "vitest": "^3.2.4"
36
+ "rollup-plugin-dts": "^6.2.3"
38
37
  },
39
38
  "type": "module",
40
39
  "module": "dist/index.mjs",
@@ -77,16 +76,18 @@
77
76
  "@atproto/lexicon": "^0.5.1",
78
77
  "@atproto/oauth-client": "^0.5.10",
79
78
  "@atproto/oauth-client-node": "^0.3.12",
79
+ "@hypercerts-org/lexicon": "^0.10.0-beta.3",
80
80
  "eventemitter3": "^5.0.1",
81
- "zod": "^3.24.4",
82
- "@hypercerts-org/lexicon": "0.9.0-beta.0"
81
+ "zod": "^3.24.4"
83
82
  },
84
83
  "scripts": {
85
- "test": "vitest",
84
+ "test": "vitest run",
86
85
  "build": "rollup -c",
87
86
  "lint": "eslint .",
88
87
  "format": "prettier --write .",
88
+ "format:check": "prettier --check .",
89
89
  "typecheck": "tsc --noEmit",
90
+ "check": "pnpm run lint && pnpm run typecheck && pnpm run build && pnpm run test",
90
91
  "clean": "rm -rf dist",
91
92
  "test:ui": "vitest --ui",
92
93
  "test:coverage": "vitest --coverage"