@tinycloud/sdk-core 2.1.0-beta.4 → 2.1.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/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client-types.ts","../src/notifications.ts","../src/storage.schema.ts","../src/TinyCloud.ts","../src/spaces/SpaceService.ts","../src/spaces/Space.ts","../src/spaces/spaces.schema.ts","../src/delegations/types.schema.ts","../src/space.ts","../src/delegations/DelegationManager.ts","../src/delegations/SharingService.schema.ts","../src/manifest.ts","../src/delegations/SharingService.ts","../src/authorization/CapabilityKeyRegistry.ts","../src/authorization/strategies.ts","../src/authorization/spaceCreation.ts","../src/version.ts","../src/capabilities.ts"],"sourcesContent":["/**\n * @tinycloud/sdk-core\n *\n * Core TinyCloud SDK package providing shared interfaces and the TinyCloud class.\n *\n * This package defines the platform-agnostic interfaces that both web-sdk and node-sdk\n * implement. The main TinyCloud class accepts an IUserAuthorization implementation,\n * allowing it to work in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\n// Platform-agnostic client types (canonical definitions)\nexport {\n ClientSession,\n EnsData,\n SiweConfig,\n ServerHost,\n ClientSessionSchema,\n EnsDataSchema,\n SiweConfigSchema,\n validateClientSession,\n SiweMessage,\n} from \"./client-types\";\n\n// Notification handler\nexport {\n INotificationHandler,\n SilentNotificationHandler,\n} from \"./notifications\";\n\n// ENS resolver\nexport { IENSResolver } from \"./ens\";\n\n// WASM bindings abstraction\nexport { IWasmBindings, ISessionManager } from \"./wasm\";\n\n// Signer interface\nexport { ISigner, Bytes } from \"./signer\";\n\n// Session storage interface and types\nexport {\n // Interface\n ISessionStorage,\n // Types (derived from Zod schemas)\n PersistedSessionData,\n PersistedTinyCloudSession,\n TinyCloudSession,\n ValidationError,\n // Validation\n validatePersistedSessionData,\n} from \"./storage\";\n\n// User authorization interface and types\nexport {\n IUserAuthorization,\n Extension,\n PartialSiweMessage,\n UserAuthorizationConfig,\n} from \"./userAuthorization\";\n\n// Main TinyCloud class\nexport { TinyCloud, TinyCloudConfig } from \"./TinyCloud\";\n\n// Re-export service types from sdk-services for convenience\nexport {\n // Context\n ServiceContext,\n type ServiceContextConfig,\n type IServiceContext,\n // Service types\n type IService,\n // KV Service\n KVService,\n PrefixedKVService,\n type IKVService,\n type IPrefixedKVService,\n type KVServiceConfig,\n type KVGetOptions,\n type KVPutOptions,\n type KVListOptions,\n type KVDeleteOptions,\n type KVHeadOptions,\n type KVResponse,\n type KVListResponse,\n type KVResponseHeaders,\n // Result pattern\n type Result,\n ok,\n err,\n serviceError,\n ErrorCodes,\n type ErrorCode,\n type ServiceError,\n // Session\n type ServiceSession,\n // Platform dependencies\n type InvokeFunction,\n type InvokeAnyFunction,\n type InvokeAnyEntry,\n type FetchFunction,\n // Retry\n type RetryPolicy,\n defaultRetryPolicy,\n // SQL Service\n SQLService,\n DatabaseHandle,\n SQLAction,\n type ISQLService,\n type IDatabaseHandle,\n type SQLServiceConfig,\n type SqlValue,\n type SqlStatement,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SQLActionType,\n // DuckDB Service\n DuckDbService,\n DuckDbDatabaseHandle,\n DuckDbAction,\n type IDuckDbService,\n type IDuckDbDatabaseHandle,\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type DuckDbQueryResponse,\n type DuckDbExecuteResponse,\n type DuckDbBatchResponse,\n type DuckDbActionType,\n type SchemaInfo,\n type TableInfo,\n type ColumnInfo,\n type ViewInfo,\n // Hooks Service\n HooksService,\n type IHooksService,\n type HookServiceName,\n type HookSubscription,\n type HookEvent,\n type HookStreamEvent,\n type HookWebhookScope,\n type HookWebhookRegistration,\n type HookWebhookRecord,\n type HookWebhookListOptions,\n type HookWebhookUnregisterOptions,\n type SubscribeOptions,\n type HooksServiceConfig,\n // Vault Service\n DataVaultService,\n VaultHeaders,\n VaultPublicSpaceKVActions,\n createVaultCrypto,\n type IDataVaultService,\n type VaultCrypto,\n type WasmVaultFunctions,\n type DataVaultConfig,\n type VaultPutOptions,\n type VaultGetOptions,\n type VaultListOptions,\n type VaultGrantOptions,\n type VaultEntry,\n type VaultError,\n} from \"@tinycloud/sdk-services\";\n\n// Space utilities\nexport {\n SpaceHostResult,\n fetchPeerId,\n submitHostDelegation,\n activateSessionWithHost,\n} from \"./space\";\n\n// Delegations\nexport {\n // Result pattern (aliased to avoid conflict with sdk-services Result)\n Result as DelegationResult,\n DelegationError,\n DelegationErrorCodes,\n DelegationErrorCode,\n // Delegation types\n Delegation,\n CreateDelegationParams,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n DelegatedResource,\n DelegationChain,\n DelegationApiResponse,\n // Configuration types\n DelegationManagerConfig,\n KeyProvider,\n // Classes\n DelegationManager,\n // v2 SharingService\n SharingService,\n createSharingService,\n ISharingService,\n SharingServiceConfig,\n EncodedShareData,\n ReceiveOptions,\n ShareAccess,\n // v2 types\n JWK,\n KeyType,\n KeyInfo,\n CapabilityEntry,\n DelegationRecord,\n DelegationChainV2,\n DelegationDirection,\n DelegationFilters,\n SpaceOwnership,\n SpaceInfo,\n ShareSchema,\n ShareLink,\n ShareLinkData,\n IngestOptions,\n GenerateShareParams,\n} from \"./delegations\";\n\n// Authorization (v2 spec)\nexport {\n // Class\n CapabilityKeyRegistry,\n // Interface\n ICapabilityKeyRegistry,\n // Factory\n createCapabilityKeyRegistry,\n // Types\n StoredDelegationChain,\n // Error codes\n CapabilityKeyRegistryErrorCodes,\n CapabilityKeyRegistryErrorCode,\n // SignStrategy types\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n EventEmitterStrategy,\n SignStrategy,\n defaultSignStrategy,\n // Space creation handler types\n SpaceCreationContext,\n ISpaceCreationHandler,\n AutoApproveSpaceCreationHandler,\n defaultSpaceCreationHandler,\n} from \"./authorization\";\n\n// Spaces (v2 spec)\nexport {\n // Space object\n Space,\n ISpace,\n SpaceConfig,\n ISpaceScopedDelegations,\n ISpaceScopedSharing,\n // SpaceService\n SpaceService,\n ISpaceService,\n SpaceServiceConfig,\n SpaceErrorCodes,\n SpaceErrorCode,\n createSpaceService,\n // URI utilities\n parseSpaceUri,\n buildSpaceUri,\n // Public space utility\n makePublicSpaceId,\n // Delegation creation types\n SpaceDelegationParams,\n CreateDelegationFunction,\n} from \"./spaces\";\n\n// Protocol version checking\nexport {\n ProtocolMismatchError,\n VersionCheckError,\n UnsupportedFeatureError,\n checkNodeInfo,\n} from \"./version\";\nexport type { NodeInfo } from \"./version\";\n\n// Manifest types and resolution (capability chain delegation)\nexport {\n // Types\n type Manifest,\n type ManifestDefaults,\n type ManifestDelegation,\n type PermissionEntry,\n type ResolvedCapabilities,\n type ResolvedDelegate,\n type ResourceCapability,\n // Errors\n ManifestValidationError,\n // Constants\n DEFAULT_DEFAULTS,\n DEFAULT_EXPIRY,\n SERVICE_LONG_TO_SHORT,\n SERVICE_SHORT_TO_LONG,\n // Types\n type AbilitiesMap,\n // Functions\n applyPrefix,\n expandActionShortNames,\n loadManifest,\n manifestAbilitiesUnion,\n normalizeDefaults,\n parseExpiry,\n resolveManifest,\n resourceCapabilitiesToAbilitiesMap,\n validateManifest,\n} from \"./manifest\";\n\n// Capability subset checking and recap parsing\nexport {\n // Errors\n PermissionNotInManifestError,\n SessionExpiredError,\n // Functions\n isCapabilitySubset,\n parseRecapCapabilities,\n // Types\n type ParseRecapFromSiwe,\n type SubsetCheckResult,\n type WasmRecapEntry,\n} from \"./capabilities\";\n","/**\n * Platform-agnostic client types for TinyCloud SDK.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport { SiweMessage } from \"siwe\";\n\nexport { SiweMessage };\n\n/** ENS data associated with a user session. */\nexport interface EnsData {\n domain?: string | null;\n avatarUrl?: string | null;\n}\n\nexport const EnsDataSchema = z.object({\n domain: z.string().nullable().optional(),\n avatarUrl: z.string().nullable().optional(),\n});\n\n/** SIWE configuration. All fields optional — callers provide only what they need to override. */\nexport interface SiweConfig {\n domain?: string;\n uri?: string;\n chainId?: number;\n statement?: string;\n nonce?: string;\n expirationTime?: string;\n notBefore?: string;\n requestId?: string;\n resources?: string[];\n}\n\nexport const SiweConfigSchema = z\n .object({\n domain: z.string().optional(),\n uri: z.string().optional(),\n chainId: z.number().optional(),\n statement: z.string().optional(),\n nonce: z.string().optional(),\n expirationTime: z.string().optional(),\n notBefore: z.string().optional(),\n requestId: z.string().optional(),\n resources: z.array(z.string()).optional(),\n })\n .passthrough();\n\n/** Representation of an active client session. */\nexport interface ClientSession {\n /** User address (may be delegated) */\n address: string;\n /** User address without delegation */\n walletAddress: string;\n /** EIP-155 chain ID */\n chainId: number;\n /** Key to identify the session */\n sessionKey: string;\n /** The SIWE message text (from SiweMessage.prepareMessage()) */\n siwe: string;\n /** The signature of the SIWE message */\n signature: string;\n /** ENS data supported by TinyCloud */\n ens?: EnsData;\n}\n\nexport const ClientSessionSchema = z.object({\n address: z.string(),\n walletAddress: z.string(),\n chainId: z.number(),\n sessionKey: z.string(),\n siwe: z.string(),\n signature: z.string(),\n ens: EnsDataSchema.optional(),\n});\n\n/** The URL of a server running tinycloud-node. */\nexport type ServerHost = string;\n\n/** Validate unknown data as a ClientSession. Returns the parsed session or null. */\nexport function validateClientSession(data: unknown): ClientSession | null {\n const result = ClientSessionSchema.safeParse(data);\n return result.success ? result.data : null;\n}\n","/**\n * Notification handler interface for TinyCloud SDK.\n *\n * Abstracts UI notifications so that web-sdk can show toasts\n * while node-sdk uses a silent no-op handler.\n *\n * @packageDocumentation\n */\n\n/**\n * Platform-agnostic notification handler.\n *\n * Implementations can provide different UX patterns:\n * - Browser: toast notifications via antd or similar\n * - Node.js: silent (default) or logging\n * - CLI: console output\n */\nexport interface INotificationHandler {\n /** Called on successful operations (e.g., \"Successfully signed in\") */\n success(message: string, description?: string): void;\n /** Called on warnings */\n warning(message: string, description?: string): void;\n /** Called on errors */\n error(category: string, message: string, description?: string): void;\n /** Optional cleanup (e.g., dismiss all active notifications) */\n cleanup?(): void;\n}\n\n/** No-op handler for environments without UI (node-sdk default). */\nexport class SilentNotificationHandler implements INotificationHandler {\n success(): void {}\n warning(): void {}\n error(): void {}\n}\n","/**\n * Zod schemas for session persistence types.\n *\n * This is the source of truth for session-related types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\n\n// =============================================================================\n// Shared Patterns\n// =============================================================================\n\n/**\n * Ethereum address pattern (checksummed or lowercase).\n */\nconst ethereumAddressPattern = /^0x[a-fA-F0-9]{40}$/;\n\n// =============================================================================\n// ENS Data Schema\n// =============================================================================\n\n/**\n * Schema for ENS data associated with a session.\n */\nexport const EnsDataSchema = z.object({\n /** ENS name/domain. */\n domain: z.string().nullable().optional(),\n /** ENS avatar URL. */\n avatarUrl: z.string().nullable().optional(),\n});\n\nexport type EnsData = z.infer<typeof EnsDataSchema>;\n\n// =============================================================================\n// Persisted TinyCloud Session Schema\n// =============================================================================\n\n/**\n * Schema for TinyCloud-specific session data that's persisted.\n */\nexport const PersistedTinyCloudSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** Additional spaces included in this session's capabilities. Key is logical name, value is full spaceId URI */\n spaces: z.record(z.string(), z.string()).optional(),\n /** The verification method DID */\n verificationMethod: z.string(),\n});\n\nexport type PersistedTinyCloudSession = z.infer<\n typeof PersistedTinyCloudSessionSchema\n>;\n\n// =============================================================================\n// Persisted Session Data Schema\n// =============================================================================\n\n/**\n * Schema for full persisted session data.\n *\n * Contains all data needed to restore a session without re-authentication.\n */\nexport const PersistedSessionDataSchema = z.object({\n /** User's Ethereum address */\n address: z\n .string()\n .regex(ethereumAddressPattern, \"Invalid Ethereum address\"),\n /** EIP-155 Chain ID */\n chainId: z.number().int().positive(),\n /** Session key in JWK format (stringified) */\n sessionKey: z.string(),\n /** The signed SIWE message */\n siwe: z.string(),\n /** User's signature of the SIWE message */\n signature: z.string(),\n /** TinyCloud delegation data if available */\n tinycloudSession: PersistedTinyCloudSessionSchema.optional(),\n /** Session expiration timestamp (ISO 8601 with timezone offset) */\n expiresAt: z.string().datetime({ offset: true }),\n /** Session creation timestamp (ISO 8601 with timezone offset) */\n createdAt: z.string().datetime({ offset: true }),\n /** Schema version for migrations */\n version: z.string(),\n /** Optional ENS data */\n ens: EnsDataSchema.optional(),\n});\n\nexport type PersistedSessionData = z.infer<typeof PersistedSessionDataSchema>;\n\n// =============================================================================\n// TinyCloud Session Schema (Runtime)\n// =============================================================================\n\n/**\n * Schema for full TinyCloud session with delegation data.\n *\n * This is the runtime session type used for making invocations and delegations.\n */\nexport const TinyCloudSessionSchema = z.object({\n /** User's Ethereum address */\n address: z.string().regex(ethereumAddressPattern, \"Invalid Ethereum address\"),\n /** EIP-155 Chain ID */\n chainId: z.number().int().positive(),\n /** Session key ID */\n sessionKey: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** Additional spaces included in this session's capabilities. Key is logical name, value is full spaceId URI */\n spaces: z.record(z.string(), z.string()).optional(),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The delegation header for API calls */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke operations) */\n jwk: z.object({}).passthrough(),\n /** The signed SIWE message */\n siwe: z.string(),\n /** User's signature of the SIWE message */\n signature: z.string(),\n});\n\nexport type TinyCloudSession = z.infer<typeof TinyCloudSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError extends ServiceError {\n code: \"VALIDATION_ERROR\";\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n/**\n * Validate persisted session data against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validatePersistedSessionData(JSON.parse(rawData));\n * if (result.ok) {\n * // result.data is typed as PersistedSessionData\n * console.log(result.data.address);\n * } else {\n * console.error(result.error.message);\n * }\n * ```\n */\nexport function validatePersistedSessionData(\n data: unknown\n): Result<PersistedSessionData, ValidationError> {\n const result = PersistedSessionDataSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate TinyCloud session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateTinyCloudSession(\n data: unknown\n): Result<TinyCloudSession, ValidationError> {\n const result = TinyCloudSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate persisted TinyCloud session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validatePersistedTinyCloudSession(\n data: unknown\n): Result<PersistedTinyCloudSession, ValidationError> {\n const result = PersistedTinyCloudSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","import {\n IUserAuthorization,\n ClientSession,\n Extension,\n} from \"./userAuthorization\";\nimport {\n ServiceContext,\n IService,\n IServiceContext,\n IKVService,\n KVService,\n ISQLService,\n SQLService,\n IDuckDbService,\n DuckDbService,\n IDataVaultService,\n IHooksService,\n HooksService,\n ServiceSession,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n RetryPolicy,\n defaultRetryPolicy,\n ServiceConstructor,\n Result,\n ok,\n err,\n serviceError,\n ServiceError,\n ErrorCodes,\n} from \"@tinycloud/sdk-services\";\nimport { makePublicSpaceId } from \"./spaces/SpaceService\";\n\n/**\n * Configuration for the TinyCloud SDK.\n */\nexport interface TinyCloudConfig {\n /** Whether to automatically resolve ENS names */\n resolveEns?: boolean;\n\n // === Service Configuration ===\n\n /**\n * TinyCloud host URLs.\n * Required when using services.\n */\n hosts?: string[];\n\n /**\n * Platform-specific invoke function from WASM binding.\n * Required when using services.\n */\n invoke?: InvokeFunction;\n\n /**\n * Optional multi-resource invoke function for aggregated capability requests.\n */\n invokeAny?: InvokeAnyFunction;\n\n /**\n * Custom fetch implementation.\n * Defaults to globalThis.fetch.\n */\n fetch?: FetchFunction;\n\n /**\n * Service constructors to register.\n * Built-in services (like KVService) are registered by default unless overridden.\n *\n * @example\n * ```typescript\n * services: {\n * kv: KVService, // default\n * files: MyFileService, // custom\n * }\n * ```\n */\n services?: Record<string, ServiceConstructor>;\n\n /**\n * Per-service configuration.\n *\n * @example\n * ```typescript\n * serviceConfigs: {\n * kv: { prefix: 'myapp' },\n * files: { maxSize: 10_000_000 },\n * }\n * ```\n */\n serviceConfigs?: Record<string, Record<string, unknown>>;\n\n /**\n * Retry policy for service operations.\n */\n retryPolicy?: Partial<RetryPolicy>;\n}\n\n/**\n * TinyCloud SDK - Unified entry point for web and node.\n *\n * This class provides the main SDK interface. Platform-specific behavior\n * is injected through the IUserAuthorization implementation:\n * - WebUserAuthorization for browser environments\n * - NodeUserAuthorization for Node.js environments\n *\n * @example\n * ```typescript\n * // Web usage\n * import { TinyCloud } from '@tinycloud/sdk-core';\n * import { WebUserAuthorization } from '@tinycloud/web-sdk';\n *\n * const auth = new WebUserAuthorization({ ... });\n * const tc = new TinyCloud(auth);\n * await tc.signIn();\n * const result = await tc.kv.put('key', 'value');\n *\n * // Node usage\n * import { TinyCloud } from '@tinycloud/sdk-core';\n * import { NodeUserAuthorization, PrivateKeySigner } from '@tinycloud/node-sdk';\n *\n * const signer = new PrivateKeySigner(process.env.PRIVATE_KEY);\n * const auth = new NodeUserAuthorization({\n * signStrategy: { type: 'auto-sign' },\n * signer,\n * domain: 'api.myapp.com'\n * });\n * const tc = new TinyCloud(auth);\n * await tc.signIn();\n * ```\n */\nexport class TinyCloud {\n /**\n * User authorization handler.\n * Provides authentication and signing capabilities.\n */\n public readonly userAuthorization: IUserAuthorization;\n\n /**\n * SDK configuration.\n */\n private config: TinyCloudConfig;\n\n /**\n * Registered extensions.\n */\n private extensions: Extension[] = [];\n\n // === Service Infrastructure ===\n\n /**\n * Service context providing platform dependencies to services.\n */\n private _serviceContext?: ServiceContext;\n\n /**\n * Registered services by name.\n */\n private _services: Map<string, IService> = new Map();\n\n /**\n * Whether services have been initialized.\n */\n private _servicesInitialized: boolean = false;\n\n /**\n * Create a new TinyCloud SDK instance.\n *\n * @param userAuthorization - Platform-specific authorization implementation\n * @param config - Optional SDK configuration\n */\n constructor(userAuthorization: IUserAuthorization, config?: TinyCloudConfig) {\n this.userAuthorization = userAuthorization;\n this.config = config || {};\n }\n\n // === Service Management ===\n\n /**\n * Initialize services with platform dependencies.\n * Must be called before using services.\n *\n * @param invoke - Platform-specific invoke function from WASM binding\n * @param hosts - TinyCloud host URLs (optional, uses config.hosts)\n * @param fetchFn - Custom fetch implementation (optional)\n */\n public initializeServices(\n invoke?: InvokeFunction,\n hosts?: string[],\n fetchFn?: FetchFunction,\n ): void {\n const effectiveInvoke = invoke ?? this.config.invoke;\n const effectiveHosts = hosts ?? this.config.hosts;\n\n if (!effectiveInvoke) {\n throw new Error(\n \"invoke function is required to initialize services. \" +\n \"Provide it via config.invoke or initializeServices().\",\n );\n }\n\n if (!effectiveHosts || effectiveHosts.length === 0) {\n throw new Error(\n \"hosts are required to initialize services. \" +\n \"Provide them via config.hosts or initializeServices().\",\n );\n }\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: effectiveInvoke,\n invokeAny: this.config.invokeAny,\n fetch: fetchFn ?? this.config.fetch ?? globalThis.fetch.bind(globalThis),\n hosts: effectiveHosts,\n retryPolicy: this.config.retryPolicy,\n });\n\n // Register default services (can be overridden via config.services)\n const serviceConstructors: Record<string, ServiceConstructor> = {\n kv: KVService,\n sql: SQLService,\n duckdb: DuckDbService,\n hooks: HooksService,\n ...this.config.services,\n };\n\n // Create and register services\n for (const [name, ServiceClass] of Object.entries(serviceConstructors)) {\n const serviceConfig = this.config.serviceConfigs?.[name] ?? {};\n const service = new ServiceClass(serviceConfig);\n service.initialize(this._serviceContext);\n this._serviceContext.registerService(name, service);\n this._services.set(name, service);\n }\n\n this._servicesInitialized = true;\n }\n\n /**\n * Get the service context.\n * @throws Error if services are not initialized\n */\n public get serviceContext(): IServiceContext {\n if (!this._serviceContext) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first.\",\n );\n }\n return this._serviceContext;\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name (e.g., 'kv')\n * @returns The service instance or undefined\n */\n public getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n /**\n * Get the KV service.\n * @throws Error if services are not initialized\n */\n public get kv(): IKVService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"kv\") as IKVService | undefined;\n if (!service) {\n throw new Error(\"KV service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the SQL service.\n * @throws Error if services are not initialized\n */\n public get sql(): ISQLService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"sql\") as ISQLService | undefined;\n if (!service) {\n throw new Error(\"SQL service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the DuckDB service.\n * @throws Error if services are not initialized\n */\n public get duckdb(): IDuckDbService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"duckdb\") as IDuckDbService | undefined;\n if (!service) {\n throw new Error(\"DuckDB service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the Hooks service.\n * @throws Error if services are not initialized\n */\n public get hooks(): IHooksService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"hooks\") as IHooksService | undefined;\n if (!service) {\n throw new Error(\"Hooks service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the Data Vault service.\n * @throws Error if services are not initialized or vault service is not registered\n */\n public get vault(): IDataVaultService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"vault\") as\n | IDataVaultService\n | undefined;\n if (!service) {\n throw new Error(\"Vault service is not registered.\");\n }\n return service;\n }\n\n /**\n * Notify services of session change.\n * Called internally after sign-in and sign-out.\n *\n * @param session - The new session, or null if signed out\n */\n private notifyServicesOfSessionChange(session: ServiceSession | null): void {\n if (this._serviceContext) {\n this._serviceContext.setSession(session);\n }\n }\n\n /**\n * Abort all pending service operations.\n * Called internally before sign-out.\n */\n private abortServiceOperations(): void {\n if (this._serviceContext) {\n this._serviceContext.abort();\n }\n }\n\n /**\n * Convert ClientSession to ServiceSession.\n * Returns null if session lacks required fields.\n */\n private toServiceSession(\n clientSession: ClientSession | undefined,\n ): ServiceSession | null {\n if (!clientSession) return null;\n\n // TinyCloudSession contains the required fields\n const tcSession = (clientSession as any).tinycloudSession;\n if (!tcSession) return null;\n\n return {\n delegationHeader: tcSession.delegationHeader,\n delegationCid: tcSession.delegationCid,\n spaceId: tcSession.spaceId,\n verificationMethod: tcSession.verificationMethod,\n jwk: tcSession.jwk,\n };\n }\n\n /**\n * Add an extension to the SDK.\n * Extensions can add capabilities and lifecycle hooks.\n */\n public extend(extension: Extension): void {\n this.extensions.push(extension);\n this.userAuthorization.extend(extension);\n }\n\n /**\n * Check if an extension is enabled.\n * @param namespace - The extension namespace to check\n */\n public isExtensionEnabled(namespace: string): boolean {\n return this.extensions.some((ext) => ext.namespace === namespace);\n }\n\n // === Authentication Methods (delegate to userAuthorization) ===\n\n /**\n * Get the current session, if signed in.\n */\n public get session(): ClientSession | undefined {\n return this.userAuthorization.session;\n }\n\n /**\n * Check if the user is signed in.\n */\n public get isSignedIn(): boolean {\n return !!this.userAuthorization.session;\n }\n\n /**\n * Sign in and create a new session.\n * Notifies services of the new session after successful sign-in.\n * @returns The new session\n */\n public async signIn(): Promise<ClientSession> {\n const session = await this.userAuthorization.signIn();\n\n // Notify services of the new session\n const serviceSession = this.toServiceSession(session);\n this.notifyServicesOfSessionChange(serviceSession);\n\n return session;\n }\n\n /**\n * Sign out and clear the current session.\n * Aborts pending service operations and notifies services.\n */\n public async signOut(): Promise<void> {\n // Abort all pending operations before sign-out\n this.abortServiceOperations();\n\n await this.userAuthorization.signOut();\n\n // Clear cached public KV service\n this._publicKV = undefined;\n\n // Clear session from services\n this.notifyServicesOfSessionChange(null);\n }\n\n /**\n * Get the current wallet address.\n */\n public address(): string | undefined {\n return this.userAuthorization.address();\n }\n\n /**\n * Get the current chain ID.\n */\n public chainId(): number | undefined {\n return this.userAuthorization.chainId();\n }\n\n /**\n * Sign a message with the connected wallet.\n * @param message - Message to sign\n */\n public async signMessage(message: string): Promise<string> {\n return this.userAuthorization.signMessage(message);\n }\n\n // === Public Space Methods ===\n\n /**\n * Cached public KV service instance.\n */\n private _publicKV?: IKVService;\n\n /**\n * Construct the deterministic public space ID for a given address and chain ID.\n *\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @returns The public space ID\n */\n static makePublicSpaceId(address: string, chainId: number): string {\n return makePublicSpaceId(address, chainId);\n }\n\n /**\n * Ensure the user's public space exists.\n * Creates it via spaces.create('public') if it doesn't.\n * Called automatically by modules that need to publish data.\n *\n * Requires the user to be signed in and services to be initialized.\n */\n public async ensurePublicSpace(): Promise<Result<void, ServiceError>> {\n const address = this.address();\n const chainId = this.chainId();\n if (!address || !chainId) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"Must be signed in to ensure public space\",\n \"public-space\",\n ),\n );\n }\n\n if (!this._serviceContext) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"Services not initialized. Call initializeServices() or signIn() first.\",\n \"public-space\",\n ),\n );\n }\n\n const spaceId = makePublicSpaceId(address, chainId);\n\n // Check if it already exists via invoke\n try {\n const session = this._serviceContext.session;\n if (!session) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"No active session\",\n \"public-space\",\n ),\n );\n }\n\n const headers = this._serviceContext.invoke(\n session,\n \"space\",\n spaceId,\n \"tinycloud.space/info\",\n );\n\n const response = await this._serviceContext.fetch(\n `${this._serviceContext.hosts[0]}/invoke`,\n { method: \"POST\", headers, body: JSON.stringify({ spaceId }) },\n );\n\n if (response.ok) {\n return ok(undefined);\n }\n\n if (response.status === 404) {\n // Space doesn't exist — create it\n const createHeaders = this._serviceContext.invoke(\n session,\n \"space\",\n \"public\",\n \"tinycloud.space/create\",\n );\n\n const createResponse = await this._serviceContext.fetch(\n `${this._serviceContext.hosts[0]}/invoke`,\n {\n method: \"POST\",\n headers: createHeaders,\n body: JSON.stringify({ name: \"public\" }),\n },\n );\n\n if (!createResponse.ok) {\n // 409 means it already exists — that's fine\n if (createResponse.status === 409) {\n return ok(undefined);\n }\n const errorText = await createResponse.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to create public space: ${createResponse.status} - ${errorText}`,\n \"public-space\",\n ),\n );\n }\n\n return ok(undefined);\n }\n\n // Other error from info check\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to check public space: ${response.status} - ${errorText}`,\n \"public-space\",\n ),\n );\n } catch (error) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Network error ensuring public space: ${String(error)}`,\n \"public-space\",\n { cause: error instanceof Error ? error : undefined },\n ),\n );\n }\n }\n\n /**\n * Get a KVService scoped to the user's own public space.\n * Writes require authentication (owner/delegate).\n *\n * @throws Error if not signed in or services not initialized\n */\n public get publicKV(): IKVService {\n if (!this._servicesInitialized || !this._serviceContext) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n\n const address = this.address();\n const chainId = this.chainId();\n if (!address || !chainId) {\n throw new Error(\"Must be signed in to access publicKV.\");\n }\n\n // Return cached instance if available\n if (this._publicKV) {\n return this._publicKV;\n }\n\n const publicSpaceId = makePublicSpaceId(address, chainId);\n const session = this._serviceContext.session;\n if (!session) {\n throw new Error(\"No active session. Sign in first.\");\n }\n\n // Create a KV service with a context that targets the public space\n const publicKV = new KVService({ prefix: \"\" });\n const publicContext = new ServiceContext({\n invoke: this._serviceContext.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n retryPolicy: this.config.retryPolicy,\n });\n publicContext.setSession({\n ...session,\n spaceId: publicSpaceId,\n });\n publicKV.initialize(publicContext);\n\n this._publicKV = publicKV;\n return this._publicKV;\n }\n\n /**\n * Read from any user's public space (unauthenticated).\n * Uses the public REST endpoint — no session needed.\n *\n * @param host - TinyCloud server URL (e.g., \"https://node.tinycloud.xyz\")\n * @param spaceId - Full public space ID\n * @param key - Key to read\n * @param fetchFn - Optional custom fetch function\n * @returns The data at the key\n */\n static async readPublicSpace<T = unknown>(\n host: string,\n spaceId: string,\n key: string,\n fetchFn?: FetchFunction,\n ): Promise<Result<T, ServiceError>> {\n const doFetch = fetchFn ?? globalThis.fetch.bind(globalThis);\n const encodedKey = key.split(\"/\").map(encodeURIComponent).join(\"/\");\n const url = `${host}/public/${encodeURIComponent(spaceId)}/kv/${encodedKey}`;\n\n try {\n const response = await doFetch(url, { method: \"GET\" });\n\n if (!response.ok) {\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.NOT_FOUND,\n `Key not found: ${key} in space ${spaceId}`,\n \"public-space\",\n ),\n );\n }\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to read public space: ${response.status} - ${errorText}`,\n \"public-space\",\n { meta: { status: response.status } },\n ),\n );\n }\n\n const contentType = response.headers.get(\"content-type\");\n let data: T;\n if (contentType?.includes(\"application/json\")) {\n data = (await response.json()) as T;\n } else {\n const text = await response.text();\n // Try parsing as JSON, fall back to raw text\n try {\n data = JSON.parse(text) as T;\n } catch {\n data = text as unknown as T;\n }\n }\n\n return ok(data);\n } catch (error) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Network error reading public space: ${String(error)}`,\n \"public-space\",\n { cause: error instanceof Error ? error : undefined },\n ),\n );\n }\n }\n\n /**\n * Read from any user's public space by address (unauthenticated).\n * Convenience method that constructs the space ID from address and chain ID.\n *\n * @param host - TinyCloud server URL\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @param key - Key to read\n * @param fetchFn - Optional custom fetch function\n * @returns The data at the key\n */\n static async readPublicKey<T = unknown>(\n host: string,\n address: string,\n chainId: number,\n key: string,\n fetchFn?: FetchFunction,\n ): Promise<Result<T, ServiceError>> {\n const spaceId = makePublicSpaceId(address, chainId);\n return TinyCloud.readPublicSpace<T>(host, spaceId, key, fetchFn);\n }\n}\n","/**\n * SpaceService - Global singleton for managing spaces (owned and delegated).\n *\n * SpaceService provides a unified interface for discovering, creating,\n * and accessing spaces. It handles both owned spaces (created by the user)\n * and delegated spaces (shared by other users).\n *\n * @packageDocumentation\n */\n\nimport type {\n IKVService,\n Result,\n ServiceError,\n ServiceSession,\n FetchFunction,\n InvokeFunction,\n} from \"@tinycloud/sdk-services\";\nimport { ok, err, serviceError } from \"@tinycloud/sdk-services\";\nimport type {\n SpaceInfo,\n SpaceOwnership,\n Delegation,\n CreateDelegationParams,\n ShareLink,\n GenerateShareParams,\n} from \"../delegations/types\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry\";\nimport type { ISharingService } from \"../delegations/SharingService\";\nimport {\n Space,\n type ISpace,\n type ISpaceScopedDelegations,\n type ISpaceScopedSharing,\n type SpaceConfig,\n} from \"./Space\";\nimport {\n validateServerDelegationsResponse,\n validateServerOwnedSpacesResponse,\n validateServerCreateSpaceResponse,\n validateServerSpaceInfoResponse,\n type ServerDelegationsResponse,\n} from \"./spaces.schema.js\";\n\n// =============================================================================\n// Service Name and Error Codes\n// =============================================================================\n\nconst SERVICE_NAME = \"space\";\n\n/**\n * Error codes for SpaceService operations.\n */\nexport const SpaceErrorCodes = {\n /** Space not found */\n NOT_FOUND: \"SPACE_NOT_FOUND\",\n /** Space already exists */\n ALREADY_EXISTS: \"SPACE_ALREADY_EXISTS\",\n /** Creation failed */\n CREATION_FAILED: \"SPACE_CREATION_FAILED\",\n /** Authentication required */\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n /** Invalid space name or URI */\n INVALID_NAME: \"INVALID_SPACE_NAME\",\n /** Network error */\n NETWORK_ERROR: \"NETWORK_ERROR\",\n /** Not initialized */\n NOT_INITIALIZED: \"NOT_INITIALIZED\",\n} as const;\n\nexport type SpaceErrorCode = (typeof SpaceErrorCodes)[keyof typeof SpaceErrorCodes];\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Parameters for creating a space-scoped delegation.\n * Extends CreateDelegationParams with the spaceId.\n */\nexport interface SpaceDelegationParams extends Omit<CreateDelegationParams, \"spaceId\"> {\n /** The space ID to create the delegation for */\n spaceId: string;\n}\n\n/**\n * Function type for creating delegations.\n * Platform SDKs provide this to handle SIWE-based delegation creation.\n */\nexport type CreateDelegationFunction = (\n params: SpaceDelegationParams\n) => Promise<Result<Delegation, ServiceError>>;\n\n/**\n * Configuration for SpaceService.\n */\nexport interface SpaceServiceConfig {\n /** TinyCloud host URLs */\n hosts: string[];\n /** Active session for authentication */\n session: ServiceSession;\n /** Platform-specific invoke function */\n invoke: InvokeFunction;\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n /** Optional capability key registry for delegated space discovery */\n capabilityRegistry?: ICapabilityKeyRegistry;\n /** Factory function to create a space-scoped KV service */\n createKVService?: (spaceId: string) => IKVService;\n /** User's PKH DID (derived from address or provided explicitly) */\n userDid?: string;\n /** Optional SharingService for v2 sharing links (client-side) */\n sharingService?: ISharingService;\n /**\n * Factory function to create delegations using SIWE-based flow.\n * Platform SDKs (web-sdk, node-sdk) provide this using their WASM bindings.\n * Required for space.delegations.create() to work.\n */\n createDelegation?: CreateDelegationFunction;\n}\n\n/**\n * Interface for SpaceService.\n */\nexport interface ISpaceService {\n /**\n * List all spaces the user has access to (owned + delegated).\n */\n list(): Promise<Result<SpaceInfo[], ServiceError>>;\n\n /**\n * Create a new space.\n *\n * @param name - The name for the new space\n */\n create(name: string): Promise<Result<SpaceInfo, ServiceError>>;\n\n /**\n * Get a Space object by name or full URI.\n *\n * For owned spaces, use the short name: `sdk.space('default')`\n * For delegated spaces, use the full URI: `sdk.space('tinycloud:pkh:eip155:1:0x...:photos')`\n *\n * @param nameOrUri - Short name or full URI\n */\n get(nameOrUri: string): ISpace;\n\n /**\n * Check if a space exists and the user has access.\n *\n * @param nameOrUri - Short name or full URI\n */\n exists(nameOrUri: string): Promise<Result<boolean, ServiceError>>;\n\n /**\n * Get the current user's primary space ID.\n */\n getCurrentSpaceId(): string | undefined;\n\n /**\n * Update the service configuration.\n */\n updateConfig(config: Partial<SpaceServiceConfig>): void;\n}\n\n// =============================================================================\n// Public Space Utilities\n// =============================================================================\n\n/**\n * Construct the deterministic public space ID for a given address and chain ID.\n *\n * Public space IDs follow the format:\n * `tinycloud:pkh:eip155:{chainId}:{address}:public`\n *\n * Given an address and chain ID, any client can construct this ID\n * to discover and read a user's public data without prior interaction.\n *\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @returns The full public space ID URI\n *\n * @example\n * ```typescript\n * const spaceId = makePublicSpaceId('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 1);\n * // => \"tinycloud:pkh:eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045:public\"\n * ```\n */\nexport function makePublicSpaceId(address: string, chainId: number): string {\n return `tinycloud:pkh:eip155:${chainId}:${address}:public`;\n}\n\n// =============================================================================\n// Space URI Utilities\n// =============================================================================\n\n/**\n * Parse a space URI to extract components.\n *\n * Full URI format: `tinycloud:pkh:eip155:{chainId}:{address}:{name}`\n * Short name format: `{name}`\n *\n * @param uri - The space URI or short name\n * @returns Parsed components or null if invalid\n */\nexport function parseSpaceUri(\n uri: string\n): { owner: string; name: string; chainId?: string; address?: string } | null {\n // Full URI format: tinycloud:pkh:eip155:{chainId}:{address}:{name}\n const fullUriMatch = uri.match(\n /^tinycloud:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40}):(.+)$/\n );\n if (fullUriMatch) {\n const [, chainId, address, name] = fullUriMatch;\n return {\n owner: `did:pkh:eip155:${chainId}:${address}`,\n name,\n chainId,\n address,\n };\n }\n\n // Short name format - just return the name, owner will be inferred\n if (/^[a-zA-Z0-9_-]+$/.test(uri)) {\n return {\n owner: \"\", // Will be filled in from session\n name: uri,\n };\n }\n\n return null;\n}\n\n/**\n * Build a full space URI from components.\n *\n * @param owner - Owner DID (did:pkh:eip155:{chainId}:{address})\n * @param name - Space name\n * @returns Full space URI\n */\nexport function buildSpaceUri(owner: string, name: string): string {\n // Extract chain ID and address from PKH DID\n const pkhMatch = owner.match(/^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/);\n if (pkhMatch) {\n const [, chainId, address] = pkhMatch;\n return `tinycloud:pkh:eip155:${chainId}:${address}:${name}`;\n }\n // Fallback - shouldn't happen with valid PKH DIDs\n return `tinycloud:${owner}:${name}`;\n}\n\n// =============================================================================\n// Server Response Transformation\n// =============================================================================\n\n/**\n * Transform validated server delegation response to SDK's Delegation[] format.\n *\n * Server returns { [cid: string]: DelegationInfo } where:\n * - Key is the delegation CID\n * - Value is DelegationInfo with delegator, delegate, capabilities, etc.\n *\n * SDK expects Delegation[] with cid field included.\n *\n * @param validatedData - Pre-validated server response from validateServerDelegationsResponse()\n * @param defaultSpaceId - Default space ID to use if not extractable from resource\n */\nfunction transformServerDelegations(\n validatedData: ServerDelegationsResponse,\n defaultSpaceId: string\n): Delegation[] {\n const result: Delegation[] = [];\n\n for (const [cid, info] of Object.entries(validatedData)) {\n // Extract path from capabilities (use first capability's resource path)\n const capabilities = info.capabilities;\n let path = \"\";\n let spaceId = defaultSpaceId;\n const actions: string[] = [];\n\n for (const cap of capabilities) {\n actions.push(cap.ability);\n // Parse resource to extract space and path\n // Resource format: tinycloud:pkh:eip155:{chainId}:{address}:{spaceName}/{service}/{path}\n const resourceMatch = cap.resource.match(\n /^(tinycloud:pkh:eip155:\\d+:0x[a-fA-F0-9]+:[^/]+)\\/[^/]+\\/(.*)$/\n );\n if (resourceMatch) {\n spaceId = resourceMatch[1];\n path = resourceMatch[2] || \"\";\n }\n }\n\n // Extract first string parent CID (server may return byte arrays for some CIDs)\n const firstStringParent = info.parents?.find((p): p is string => typeof p === 'string');\n\n result.push({\n cid,\n delegateDID: info.delegate,\n delegatorDID: info.delegator,\n spaceId,\n path,\n actions,\n expiry: info.expiry ? new Date(info.expiry) : new Date(Date.now() + 24 * 60 * 60 * 1000),\n isRevoked: false,\n createdAt: info.issued_at ? new Date(info.issued_at) : undefined,\n parentCid: firstStringParent,\n });\n }\n\n return result;\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * SpaceService - Global singleton for managing spaces.\n *\n * @example\n * ```typescript\n * const spaceService = new SpaceService({\n * hosts: ['https://node.tinycloud.xyz'],\n * session,\n * invoke,\n * });\n *\n * // List all accessible spaces\n * const result = await spaceService.list();\n * if (result.ok) {\n * for (const space of result.data) {\n * console.log(`${space.name} (${space.type})`);\n * }\n * }\n *\n * // Create a new space\n * const createResult = await spaceService.create('photos');\n *\n * // Get a space object for operations\n * const space = spaceService.get('photos');\n * await space.kv.put('album/vacation', { photos: [...] });\n * ```\n */\nexport class SpaceService implements ISpaceService {\n private hosts: string[];\n private session: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n private capabilityRegistry?: ICapabilityKeyRegistry;\n private createKVServiceFn?: (spaceId: string) => IKVService;\n private _userDid?: string;\n private sharingService?: ISharingService;\n private createDelegationFn?: CreateDelegationFunction;\n\n /** Cache of created Space objects */\n private spaceCache: Map<string, ISpace> = new Map();\n\n /** Cache of space info */\n private infoCache: Map<string, { info: SpaceInfo; cachedAt: number }> = new Map();\n\n /** Cache TTL in milliseconds (5 minutes) */\n private readonly cacheTTL = 5 * 60 * 1000;\n\n /**\n * Create a new SpaceService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: SpaceServiceConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.capabilityRegistry = config.capabilityRegistry;\n this.createKVServiceFn = config.createKVService;\n this._userDid = config.userDid;\n this.sharingService = config.sharingService;\n this.createDelegationFn = config.createDelegation;\n }\n\n /**\n * Update the service configuration.\n */\n updateConfig(config: Partial<SpaceServiceConfig>): void {\n if (config.hosts) this.hosts = config.hosts;\n if (config.session) this.session = config.session;\n if (config.invoke) this.invoke = config.invoke;\n if (config.fetch) this.fetchFn = config.fetch;\n if (config.capabilityRegistry) this.capabilityRegistry = config.capabilityRegistry;\n if (config.createKVService) this.createKVServiceFn = config.createKVService;\n if (config.userDid !== undefined) this._userDid = config.userDid;\n if (config.sharingService) this.sharingService = config.sharingService;\n if (config.createDelegation) this.createDelegationFn = config.createDelegation;\n\n // Clear caches when config changes\n this.spaceCache.clear();\n this.infoCache.clear();\n }\n\n /**\n * Get the current user's primary space ID.\n */\n getCurrentSpaceId(): string | undefined {\n return this.session?.spaceId;\n }\n\n /**\n * Get the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Get the current user's PKH DID.\n */\n private get userDid(): string | undefined {\n // Return explicitly set user DID, or try to derive from verificationMethod\n if (this._userDid) {\n return this._userDid;\n }\n // verificationMethod might be did:key format - cannot derive PKH from it\n // The caller should provide userDid explicitly for full functionality\n return undefined;\n }\n\n // ===========================================================================\n // List Spaces\n // ===========================================================================\n\n /**\n * List all spaces the user has access to.\n *\n * Combines owned spaces (from the server) with delegated spaces\n * (from the capability registry).\n */\n async list(): Promise<Result<SpaceInfo[], ServiceError>> {\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n try {\n const spaces: SpaceInfo[] = [];\n\n // 1. Get owned spaces from the server\n const ownedResult = await this.listOwnedSpaces();\n if (ownedResult.ok) {\n spaces.push(...ownedResult.data);\n }\n\n // 2. Get delegated spaces from capability registry\n if (this.capabilityRegistry) {\n const delegatedSpaces = this.discoverDelegatedSpaces();\n spaces.push(...delegatedSpaces);\n }\n\n // Remove duplicates (prefer owned over delegated)\n const uniqueSpaces = this.deduplicateSpaces(spaces);\n\n return ok(uniqueSpaces);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list spaces: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n /**\n * List owned spaces from the server.\n */\n private async listOwnedSpaces(): Promise<Result<SpaceInfo[], ServiceError>> {\n try {\n const headers = this.invoke(this.session, \"space\", \"\", \"tinycloud.space/list\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list owned spaces: ${response.status} - ${errorText}`,\n SERVICE_NAME,\n { meta: { status: response.status } }\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerOwnedSpacesResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const spaces: SpaceInfo[] = validationResult.data.map((item) => ({\n id: item.id,\n name: item.name ?? this.extractNameFromId(item.id),\n owner: item.owner,\n type: \"owned\" as SpaceOwnership,\n permissions: [\"*\"], // Full permissions for owned spaces\n }));\n\n return ok(spaces);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing owned spaces: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n /**\n * Discover delegated spaces from the capability registry.\n */\n private discoverDelegatedSpaces(): SpaceInfo[] {\n if (!this.capabilityRegistry) {\n return [];\n }\n\n const spaces: Map<string, SpaceInfo> = new Map();\n\n // Get all capabilities and extract unique space IDs\n const capabilities = this.capabilityRegistry.getAllCapabilities();\n\n for (const capability of capabilities) {\n const spaceId = capability.delegation.spaceId;\n\n // Skip if we already have this space\n if (spaces.has(spaceId)) {\n const existing = spaces.get(spaceId)!;\n // Merge permissions\n if (existing.permissions) {\n const actions = capability.delegation.actions;\n for (const action of actions) {\n if (!existing.permissions.includes(action)) {\n existing.permissions.push(action);\n }\n }\n }\n continue;\n }\n\n // Skip if this is the user's own space\n if (spaceId === this.session?.spaceId) {\n continue;\n }\n\n const parsed = parseSpaceUri(spaceId);\n\n spaces.set(spaceId, {\n id: spaceId,\n name: parsed?.name ?? this.extractNameFromId(spaceId),\n owner: capability.delegation.delegatorDID ?? parsed?.owner ?? \"\",\n type: \"delegated\",\n permissions: [...capability.delegation.actions],\n expiresAt: capability.expiresAt,\n });\n }\n\n return Array.from(spaces.values());\n }\n\n /**\n * Extract space name from a full space ID.\n */\n private extractNameFromId(id: string): string {\n const parsed = parseSpaceUri(id);\n if (parsed) {\n return parsed.name;\n }\n // Fallback: take last segment\n const parts = id.split(\":\");\n return parts[parts.length - 1] || id;\n }\n\n /**\n * Deduplicate spaces, preferring owned over delegated.\n */\n private deduplicateSpaces(spaces: SpaceInfo[]): SpaceInfo[] {\n const seen = new Map<string, SpaceInfo>();\n\n for (const space of spaces) {\n const existing = seen.get(space.id);\n if (!existing || (existing.type === \"delegated\" && space.type === \"owned\")) {\n seen.set(space.id, space);\n }\n }\n\n return Array.from(seen.values());\n }\n\n // ===========================================================================\n // Create Space\n // ===========================================================================\n\n /**\n * Create a new space.\n *\n * @param name - The name for the new space\n */\n async create(name: string): Promise<Result<SpaceInfo, ServiceError>> {\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n // Validate name\n if (!name || !/^[a-zA-Z0-9_-]+$/.test(name)) {\n return err(\n serviceError(\n SpaceErrorCodes.INVALID_NAME,\n \"Space name must contain only alphanumeric characters, underscores, and hyphens\",\n SERVICE_NAME\n )\n );\n }\n\n try {\n const headers = this.invoke(this.session, \"space\", name, \"tinycloud.space/create\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ name }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 409) {\n return err(\n serviceError(\n SpaceErrorCodes.ALREADY_EXISTS,\n `Space \"${name}\" already exists`,\n SERVICE_NAME\n )\n );\n }\n\n return err(\n serviceError(\n SpaceErrorCodes.CREATION_FAILED,\n `Failed to create space: ${response.status} - ${errorText}`,\n SERVICE_NAME,\n { meta: { status: response.status } }\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerCreateSpaceResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.CREATION_FAILED,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const spaceInfo: SpaceInfo = {\n id: validationResult.data.id,\n name: validationResult.data.name || name,\n owner: validationResult.data.owner || this.userDid || \"\",\n type: \"owned\",\n permissions: [\"*\"],\n };\n\n // Cache the info\n this.infoCache.set(spaceInfo.id, { info: spaceInfo, cachedAt: Date.now() });\n\n return ok(spaceInfo);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error creating space: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n // ===========================================================================\n // Get Space\n // ===========================================================================\n\n /**\n * Get a Space object by name or full URI.\n *\n * @param nameOrUri - Short name or full URI\n */\n get(nameOrUri: string): ISpace {\n // Resolve the full space ID\n const spaceId = this.resolveSpaceId(nameOrUri);\n\n // Check cache\n const cached = this.spaceCache.get(spaceId);\n if (cached) {\n return cached;\n }\n\n // Create new Space object\n const parsed = parseSpaceUri(spaceId);\n const name = parsed?.name ?? this.extractNameFromId(spaceId);\n\n const config: SpaceConfig = {\n id: spaceId,\n name,\n createKV: this.createSpaceScopedKV.bind(this),\n createDelegations: this.createSpaceScopedDelegations.bind(this),\n createSharing: this.createSpaceScopedSharing.bind(this),\n getInfo: this.getSpaceInfo.bind(this),\n };\n\n const space = new Space(config);\n this.spaceCache.set(spaceId, space);\n\n return space;\n }\n\n /**\n * Resolve a name or URI to a full space ID.\n */\n private resolveSpaceId(nameOrUri: string): string {\n const parsed = parseSpaceUri(nameOrUri);\n\n if (!parsed) {\n // Invalid format, return as-is\n return nameOrUri;\n }\n\n if (parsed.owner) {\n // Full URI - return as-is\n return nameOrUri;\n }\n\n // Short name - build full URI from user's DID\n if (this.userDid) {\n return buildSpaceUri(this.userDid, parsed.name);\n }\n\n // No user DID available, return as-is\n return nameOrUri;\n }\n\n // ===========================================================================\n // Exists Check\n // ===========================================================================\n\n /**\n * Check if a space exists and the user has access.\n */\n async exists(nameOrUri: string): Promise<Result<boolean, ServiceError>> {\n const spaceId = this.resolveSpaceId(nameOrUri);\n\n // Check info cache first\n const cached = this.infoCache.get(spaceId);\n if (cached && Date.now() - cached.cachedAt < this.cacheTTL) {\n return ok(true);\n }\n\n // Query the server\n const infoResult = await this.getSpaceInfo(spaceId);\n return ok(infoResult.ok);\n }\n\n // ===========================================================================\n // Space Info\n // ===========================================================================\n\n /**\n * Get space info from server or cache.\n */\n private async getSpaceInfo(spaceId: string): Promise<Result<SpaceInfo, ServiceError>> {\n // Check cache\n const cached = this.infoCache.get(spaceId);\n if (cached && Date.now() - cached.cachedAt < this.cacheTTL) {\n return ok(cached.info);\n }\n\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n try {\n const headers = this.invoke(this.session, \"space\", spaceId, \"tinycloud.space/info\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ spaceId }),\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return err(\n serviceError(SpaceErrorCodes.NOT_FOUND, `Space not found: ${spaceId}`, SERVICE_NAME)\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to get space info: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerSpaceInfoResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const data = validationResult.data;\n const spaceInfo: SpaceInfo = {\n id: data.id,\n name: data.name ?? this.extractNameFromId(data.id),\n owner: data.owner,\n type: data.type ?? (data.owner === this.userDid ? \"owned\" : \"delegated\"),\n permissions: data.permissions,\n expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined,\n };\n\n // Cache the info\n this.infoCache.set(spaceId, { info: spaceInfo, cachedAt: Date.now() });\n\n return ok(spaceInfo);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error getting space info: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n // ===========================================================================\n // Space-Scoped Service Factories\n // ===========================================================================\n\n /**\n * Create a space-scoped KV service.\n */\n private createSpaceScopedKV(spaceId: string): IKVService {\n if (this.createKVServiceFn) {\n return this.createKVServiceFn(spaceId);\n }\n\n // Return a proxy that throws a helpful error\n return new Proxy({} as IKVService, {\n get: () => {\n throw new Error(\n \"KV service factory not configured. Provide createKVService in SpaceServiceConfig.\"\n );\n },\n });\n }\n\n /**\n * Create space-scoped delegation operations.\n */\n private createSpaceScopedDelegations(spaceId: string): ISpaceScopedDelegations {\n const self = this;\n\n return {\n async list(): Promise<Result<Delegation[], ServiceError>> {\n // List outgoing delegations (created by user) using tinycloud.capabilities/read\n try {\n // Facts contain the query params for the capabilities/read capability\n const facts = [\n {\n capabilitiesReadParams: {\n type: \"list\",\n filters: { direction: \"created\" },\n },\n },\n ];\n\n // The capabilities/read endpoint requires path=\"all\" to match server routing\n const headers = self.invoke(\n self.session,\n \"capabilities\",\n \"all\",\n \"tinycloud.capabilities/read\",\n facts\n );\n\n const response = await self.fetchFn(`${self.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list delegations: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n // Server returns { [cid: string]: DelegationInfo } - validate and transform to Delegation[]\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerDelegationsResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const delegations = transformServerDelegations(validationResult.data, spaceId);\n return ok(delegations);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing delegations: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n\n async listReceived(): Promise<Result<Delegation[], ServiceError>> {\n // List incoming delegations (received by user) using tinycloud.capabilities/read\n try {\n // Facts contain the query params for the capabilities/read capability\n const facts = [\n {\n capabilitiesReadParams: {\n type: \"list\",\n filters: { direction: \"received\" },\n },\n },\n ];\n\n // The capabilities/read endpoint requires path=\"all\" to match server routing\n const headers = self.invoke(\n self.session,\n \"capabilities\",\n \"all\",\n \"tinycloud.capabilities/read\",\n facts\n );\n\n const response = await self.fetchFn(`${self.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list received delegations: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n // Server returns { [cid: string]: DelegationInfo } - validate and transform to Delegation[]\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerDelegationsResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const delegations = transformServerDelegations(validationResult.data, spaceId);\n return ok(delegations);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing received delegations: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n\n async create(\n params: Omit<CreateDelegationParams, \"spaceId\">\n ): Promise<Result<Delegation, ServiceError>> {\n // Use the platform-provided createDelegation function (SIWE-based flow)\n if (self.createDelegationFn) {\n return self.createDelegationFn({ ...params, spaceId });\n }\n\n // Fallback: return error if no createDelegation function provided\n // The old invoke-based approach doesn't work because /delegate expects\n // SIWE delegation headers, not invocation headers\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Delegation creation requires a createDelegation function. \" +\n \"This should be provided by the platform SDK (web-sdk or node-sdk).\",\n SERVICE_NAME\n )\n );\n },\n\n async revoke(cid: string): Promise<Result<void, ServiceError>> {\n try {\n const headers = self.invoke(\n self.session,\n \"delegation\",\n cid,\n \"tinycloud.delegation/revoke\"\n );\n\n const response = await self.fetchFn(`${self.host}/revoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ cid, spaceId }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to revoke delegation: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error revoking delegation: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n };\n }\n\n /**\n * Create space-scoped sharing operations.\n *\n * When a SharingService is configured, delegates to client-side v2 sharing.\n * V2 sharing links are self-contained with embedded private keys - no server tracking.\n */\n private createSpaceScopedSharing(spaceId: string): ISpaceScopedSharing {\n const self = this;\n\n return {\n async generate(\n params: Omit<GenerateShareParams, \"spaceId\">\n ): Promise<Result<ShareLink, ServiceError>> {\n // Use v2 SharingService when available (client-side sharing links)\n if (self.sharingService) {\n // Note: SharingService uses session.spaceId for the space.\n // For space-scoped sharing on delegated spaces, ensure the session\n // is configured for the correct space before calling generate().\n const result = await self.sharingService.generate(params);\n if (!result.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n result.error.message || \"Failed to generate share link\",\n SERVICE_NAME\n )\n );\n }\n return ok(result.data);\n }\n\n // Fallback: return error since server endpoint doesn't exist\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"SharingService not configured. V2 sharing requires a SharingService instance.\",\n SERVICE_NAME\n )\n );\n },\n\n async list(): Promise<Result<ShareLink[], ServiceError>> {\n // V2 sharing links are self-contained (not server-tracked)\n // This operation is not supported in the v2 spec\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Listing share links is not supported in v2. Share links are self-contained tokens that are not tracked on the server.\",\n SERVICE_NAME\n )\n );\n },\n\n async revoke(token: string): Promise<Result<void, ServiceError>> {\n // V2 sharing links are revoked by revoking the underlying delegation\n // This requires the delegation CID, not the share token\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Revoking share links by token is not supported in v2. To revoke access, revoke the underlying delegation using space.delegations.revoke(cid).\",\n SERVICE_NAME\n )\n );\n },\n };\n }\n}\n\n/**\n * Create a new SpaceService instance.\n *\n * @param config - Service configuration\n * @returns A new SpaceService instance\n */\nexport function createSpaceService(config: SpaceServiceConfig): ISpaceService {\n return new SpaceService(config);\n}\n","/**\n * Space - Represents a scoped access point to a TinyCloud space.\n *\n * The Space object provides scoped access to services within a specific space,\n * whether owned by the user or delegated from another user.\n *\n * @packageDocumentation\n */\n\nimport type { IKVService, Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport type { SpaceInfo } from \"../delegations/types\";\n\n/**\n * Interface for space-scoped delegation operations.\n *\n * Provides delegation management scoped to a specific space.\n */\nexport interface ISpaceScopedDelegations {\n /**\n * List delegations created by the user in this space (outgoing).\n */\n list(): Promise<Result<import(\"../delegations/types\").Delegation[], ServiceError>>;\n\n /**\n * List delegations received by the user for this space (incoming).\n */\n listReceived(): Promise<Result<import(\"../delegations/types\").Delegation[], ServiceError>>;\n\n /**\n * Create a delegation within this space.\n */\n create(\n params: Omit<import(\"../delegations/types\").CreateDelegationParams, \"spaceId\">\n ): Promise<Result<import(\"../delegations/types\").Delegation, ServiceError>>;\n\n /**\n * Revoke a delegation within this space.\n */\n revoke(cid: string): Promise<Result<void, ServiceError>>;\n}\n\n/**\n * Interface for space-scoped sharing operations.\n *\n * Provides sharing link management scoped to a specific space.\n */\nexport interface ISpaceScopedSharing {\n /**\n * Generate a sharing link for a resource in this space.\n */\n generate(\n params: Omit<import(\"../delegations/types\").GenerateShareParams, \"spaceId\">\n ): Promise<Result<import(\"../delegations/types\").ShareLink, ServiceError>>;\n\n /**\n * List active sharing links in this space.\n */\n list(): Promise<Result<import(\"../delegations/types\").ShareLink[], ServiceError>>;\n\n /**\n * Revoke a sharing link.\n */\n revoke(token: string): Promise<Result<void, ServiceError>>;\n}\n\n/**\n * Interface for a Space object.\n *\n * Provides scoped access to services within a specific space.\n */\nexport interface ISpace {\n /**\n * The space identifier.\n */\n readonly id: string;\n\n /**\n * The short name of the space.\n */\n readonly name: string;\n\n /**\n * KV operations scoped to this space.\n */\n readonly kv: IKVService;\n\n /**\n * Delegation operations scoped to this space.\n */\n readonly delegations: ISpaceScopedDelegations;\n\n /**\n * Sharing operations scoped to this space.\n */\n readonly sharing: ISpaceScopedSharing;\n\n /**\n * Get space metadata.\n */\n info(): Promise<Result<SpaceInfo, ServiceError>>;\n}\n\n/**\n * Configuration for creating a Space object.\n */\nexport interface SpaceConfig {\n /**\n * The space identifier (full URI).\n */\n id: string;\n\n /**\n * The short name of the space.\n */\n name: string;\n\n /**\n * Factory function to create a space-scoped KV service.\n */\n createKV: (spaceId: string) => IKVService;\n\n /**\n * Factory function to create space-scoped delegations.\n */\n createDelegations: (spaceId: string) => ISpaceScopedDelegations;\n\n /**\n * Factory function to create space-scoped sharing.\n */\n createSharing: (spaceId: string) => ISpaceScopedSharing;\n\n /**\n * Function to get space info.\n */\n getInfo: (spaceId: string) => Promise<Result<SpaceInfo, ServiceError>>;\n}\n\n/**\n * Space - Provides scoped access to services within a specific space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // KV operations scoped to this space\n * await space.kv.put('key', 'value');\n * const result = await space.kv.get('key');\n *\n * // Delegation operations scoped to this space\n * await space.delegations.create({\n * delegateDID: 'did:pkh:eip155:1:0x...',\n * path: '/shared/',\n * actions: ['tinycloud.kv/get']\n * });\n *\n * // Get space metadata\n * const info = await space.info();\n * ```\n */\nexport class Space implements ISpace {\n private readonly _id: string;\n private readonly _name: string;\n private readonly _kv: IKVService;\n private readonly _delegations: ISpaceScopedDelegations;\n private readonly _sharing: ISpaceScopedSharing;\n private readonly _getInfo: (spaceId: string) => Promise<Result<SpaceInfo, ServiceError>>;\n\n /**\n * Create a new Space instance.\n *\n * @param config - Space configuration\n */\n constructor(config: SpaceConfig) {\n this._id = config.id;\n this._name = config.name;\n this._kv = config.createKV(config.id);\n this._delegations = config.createDelegations(config.id);\n this._sharing = config.createSharing(config.id);\n this._getInfo = config.getInfo;\n }\n\n /**\n * The space identifier (full URI).\n */\n get id(): string {\n return this._id;\n }\n\n /**\n * The short name of the space.\n */\n get name(): string {\n return this._name;\n }\n\n /**\n * KV operations scoped to this space.\n */\n get kv(): IKVService {\n return this._kv;\n }\n\n /**\n * Delegation operations scoped to this space.\n */\n get delegations(): ISpaceScopedDelegations {\n return this._delegations;\n }\n\n /**\n * Sharing operations scoped to this space.\n */\n get sharing(): ISpaceScopedSharing {\n return this._sharing;\n }\n\n /**\n * Get space metadata.\n *\n * @returns Result containing space information\n */\n async info(): Promise<Result<SpaceInfo, ServiceError>> {\n return this._getInfo(this._id);\n }\n}\n","/**\n * Zod schemas for Space and SpaceService configuration types.\n *\n * These schemas provide runtime validation for space management types.\n * Types are derived from schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport { CreateDelegationParamsSchema } from \"../delegations/types.schema.js\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError extends ServiceError {\n code: \"VALIDATION_ERROR\";\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// SpaceConfig Schema\n// =============================================================================\n\n/**\n * Configuration for creating a Space object.\n *\n * Contains the space identifier, name, and factory functions for creating\n * space-scoped services.\n */\nexport const SpaceConfigSchema = z.object({\n /** The space identifier (full URI) */\n id: z.string(),\n /** The short name of the space */\n name: z.string(),\n /** Factory function to create a space-scoped KV service */\n createKV: z.function(),\n /** Factory function to create space-scoped delegations */\n createDelegations: z.function(),\n /** Factory function to create space-scoped sharing */\n createSharing: z.function(),\n /** Function to get space info */\n getInfo: z.function(),\n});\n\nexport type SpaceConfig = z.infer<typeof SpaceConfigSchema>;\n\n// =============================================================================\n// SpaceServiceConfig Schema\n// =============================================================================\n\n/**\n * Configuration for SpaceService.\n *\n * Contains all the dependencies needed for the SpaceService to manage\n * spaces, including hosts, session, and factory functions.\n */\nexport const SpaceServiceConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string()),\n /** Active session for authentication */\n session: z.unknown(),\n /** Platform-specific invoke function */\n invoke: z.function(),\n /** Optional custom fetch implementation */\n fetch: z.function().optional(),\n /** Optional capability key registry for delegated space discovery */\n capabilityRegistry: z.unknown().optional(),\n /** Factory function to create a space-scoped KV service */\n createKVService: z.function().optional(),\n /** User's PKH DID (derived from address or provided explicitly) */\n userDid: z.string().optional(),\n /** Optional SharingService for v2 sharing links (client-side) */\n sharingService: z.unknown().optional(),\n /** Factory function to create delegations using SIWE-based flow */\n createDelegation: z.function().optional(),\n});\n\nexport type SpaceServiceConfig = z.infer<typeof SpaceServiceConfigSchema>;\n\n// =============================================================================\n// SpaceDelegationParams Schema\n// =============================================================================\n\n/**\n * Parameters for creating a space-scoped delegation.\n *\n * Extends CreateDelegationParams with the spaceId field.\n */\nexport const SpaceDelegationParamsSchema = CreateDelegationParamsSchema.extend({\n /** The space ID to create the delegation for */\n spaceId: z.string(),\n});\n\nexport type SpaceDelegationParams = z.infer<typeof SpaceDelegationParamsSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate a SpaceConfig object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceConfig(config);\n * if (result.ok) {\n * const space = new Space(result.data);\n * } else {\n * console.error(\"Invalid config:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceConfig(\n data: unknown\n): Result<SpaceConfig, ValidationError> {\n const result = SpaceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate a SpaceServiceConfig object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceServiceConfig(config);\n * if (result.ok) {\n * const service = new SpaceService(result.data);\n * } else {\n * console.error(\"Invalid config:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceServiceConfig(\n data: unknown\n): Result<SpaceServiceConfig, ValidationError> {\n const result = SpaceServiceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate a SpaceDelegationParams object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceDelegationParams(params);\n * if (result.ok) {\n * await createDelegation(result.data);\n * } else {\n * console.error(\"Invalid params:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceDelegationParams(\n data: unknown\n): Result<SpaceDelegationParams, ValidationError> {\n const result = SpaceDelegationParamsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n// =============================================================================\n// Server Response Schemas\n// =============================================================================\n\n/**\n * Server's DelegationInfo structure (from capabilities/read response).\n * This schema validates the shape of delegation data received from the server.\n */\nexport const ServerDelegationInfoSchema = z.object({\n /** DID of the delegator */\n delegator: z.string(),\n /** DID of the delegate */\n delegate: z.string(),\n /** Parent delegation CIDs - accepts string or byte array format from server */\n parents: z.array(z.union([z.string(), z.array(z.number())])),\n /** Expiration time (ISO8601 string) */\n expiry: z.string().optional(),\n /** Not-before time (ISO8601 string) */\n not_before: z.string().optional(),\n /** Issued-at time (ISO8601 string) */\n issued_at: z.string().optional(),\n /** Capabilities granted by this delegation */\n capabilities: z.array(\n z.object({\n resource: z.string(),\n ability: z.string(),\n })\n ),\n});\n\nexport type ServerDelegationInfo = z.infer<typeof ServerDelegationInfoSchema>;\n\n/**\n * Server response for capabilities/read endpoint.\n * Returns a record mapping CID -> DelegationInfo.\n */\nexport const ServerDelegationsResponseSchema = z.record(\n z.string(),\n ServerDelegationInfoSchema\n);\n\nexport type ServerDelegationsResponse = z.infer<typeof ServerDelegationsResponseSchema>;\n\n/**\n * Server response for space/list endpoint.\n * Returns an array of owned space info.\n */\nexport const ServerOwnedSpaceSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name (optional, can be derived from id) */\n name: z.string().optional(),\n /** Owner DID */\n owner: z.string(),\n /** Creation timestamp */\n createdAt: z.string().optional(),\n});\n\nexport type ServerOwnedSpace = z.infer<typeof ServerOwnedSpaceSchema>;\n\nexport const ServerOwnedSpacesResponseSchema = z.array(ServerOwnedSpaceSchema);\n\nexport type ServerOwnedSpacesResponse = z.infer<typeof ServerOwnedSpacesResponseSchema>;\n\n/**\n * Server response for space/create endpoint.\n */\nexport const ServerCreateSpaceResponseSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name */\n name: z.string(),\n /** Owner DID */\n owner: z.string(),\n /** Creation timestamp */\n createdAt: z.string().optional(),\n});\n\nexport type ServerCreateSpaceResponse = z.infer<typeof ServerCreateSpaceResponseSchema>;\n\n/**\n * Server response for space/info endpoint.\n */\nexport const ServerSpaceInfoResponseSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name (optional) */\n name: z.string().optional(),\n /** Owner DID */\n owner: z.string(),\n /** Ownership type */\n type: z.enum([\"owned\", \"delegated\"]).optional(),\n /** Permissions the user has in this space */\n permissions: z.array(z.string()).optional(),\n /** Expiration for delegated access */\n expiresAt: z.string().optional(),\n});\n\nexport type ServerSpaceInfoResponse = z.infer<typeof ServerSpaceInfoResponseSchema>;\n\n// =============================================================================\n// Server Response Validation Helpers\n// =============================================================================\n\n/**\n * Validate server delegations response (capabilities/read).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerDelegationsResponse(\n data: unknown\n): Result<ServerDelegationsResponse, ValidationError> {\n // Handle null/undefined as empty response\n if (data === null || data === undefined) {\n return { ok: true, data: {} };\n }\n\n // Handle array format (legacy compatibility) - return as-is, validation happens elsewhere\n if (Array.isArray(data)) {\n return { ok: true, data: {} };\n }\n\n const result = ServerDelegationsResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server delegations response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server owned spaces response (space/list).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerOwnedSpacesResponse(\n data: unknown\n): Result<ServerOwnedSpacesResponse, ValidationError> {\n const result = ServerOwnedSpacesResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server owned spaces response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server create space response (space/create).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerCreateSpaceResponse(\n data: unknown\n): Result<ServerCreateSpaceResponse, ValidationError> {\n const result = ServerCreateSpaceResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server create space response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server space info response (space/info).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerSpaceInfoResponse(\n data: unknown\n): Result<ServerSpaceInfoResponse, ValidationError> {\n const result = ServerSpaceInfoResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server space info response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * Zod schemas for delegation management types.\n *\n * These schemas provide runtime validation for delegation, capability key management,\n * and sharing link functionality. Types are derived from schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type {\n FetchFunction,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\n\n// =============================================================================\n// Result Type (Generic)\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type and error type.\n * Result types provide explicit error handling instead of throwing.\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({ ok: z.literal(true), data: dataSchema }),\n z.object({ ok: z.literal(false), error: errorSchema }),\n ]);\n}\n\n/**\n * Result type pattern for delegation operations.\n */\nexport type Result<T, E = DelegationError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n// =============================================================================\n// JWK Type (JSON Web Key)\n// =============================================================================\n\n/**\n * JSON Web Key representation for cryptographic keys.\n * Follows the JWK specification (RFC 7517).\n */\nexport const JWKSchema = z.object({\n /** Key type (e.g., \"EC\", \"RSA\", \"OKP\") */\n kty: z.string(),\n /** Curve for EC/OKP keys (e.g., \"P-256\", \"Ed25519\") */\n crv: z.string().optional(),\n /** X coordinate for EC keys, public key for OKP */\n x: z.string().optional(),\n /** Y coordinate for EC keys */\n y: z.string().optional(),\n /** Private key value (d parameter) */\n d: z.string().optional(),\n /** Public exponent for RSA keys */\n e: z.string().optional(),\n /** Modulus for RSA keys */\n n: z.string().optional(),\n /** Key ID */\n kid: z.string().optional(),\n /** Algorithm */\n alg: z.string().optional(),\n /** Key use (e.g., \"sig\", \"enc\") */\n use: z.string().optional(),\n /** Key operations (e.g., [\"sign\", \"verify\"]) */\n key_ops: z.array(z.string()).optional(),\n});\n\nexport type JWK = z.infer<typeof JWKSchema>;\n\n// =============================================================================\n// Key Management Types\n// =============================================================================\n\n/**\n * Type of key in the capability registry.\n */\nexport const KeyTypeSchema = z.enum([\"main\", \"session\", \"ingested\"]);\nexport type KeyType = z.infer<typeof KeyTypeSchema>;\n\n/**\n * Information about a cryptographic key used for delegations.\n */\nexport const KeyInfoSchema = z.object({\n /** Unique identifier for this key */\n id: z.string(),\n /** DID associated with this key */\n did: z.string(),\n /** Type of key determining its authority level */\n type: KeyTypeSchema,\n /** Private key in JWK format */\n jwk: JWKSchema.optional(),\n /** Priority for key selection (lower = higher priority) */\n priority: z.number(),\n});\n\nexport type KeyInfo = z.infer<typeof KeyInfoSchema>;\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Error type for delegation operations.\n */\nexport const DelegationErrorSchema = z.object({\n /** Error code for programmatic handling */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** The service that produced the error */\n service: z.literal(\"delegation\"),\n /** Original error if wrapping another error */\n cause: z.instanceof(Error).optional(),\n /** Additional metadata about the error */\n meta: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type DelegationError = z.infer<typeof DelegationErrorSchema>;\n\n/**\n * Error codes for delegation operations.\n */\nexport const DelegationErrorCodes = {\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n NOT_INITIALIZED: \"NOT_INITIALIZED\",\n NOT_FOUND: \"NOT_FOUND\",\n REVOKED: \"REVOKED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n CREATION_FAILED: \"CREATION_FAILED\",\n REVOCATION_FAILED: \"REVOCATION_FAILED\",\n INVALID_TOKEN: \"INVALID_TOKEN\",\n KV_SERVICE_UNAVAILABLE: \"KV_SERVICE_UNAVAILABLE\",\n DATA_FETCH_FAILED: \"DATA_FETCH_FAILED\",\n VALIDATION_ERROR: \"VALIDATION_ERROR\",\n} as const;\n\nexport type DelegationErrorCode =\n (typeof DelegationErrorCodes)[keyof typeof DelegationErrorCodes];\n\n// =============================================================================\n// Delegation Types\n// =============================================================================\n\n/**\n * Represents a delegation from one DID to another.\n */\nexport const DelegationSchema = z.object({\n /** Content identifier (CID) of the delegation */\n cid: z.string(),\n /** DID of the delegate (the party receiving the delegation) */\n delegateDID: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /** Resource path this delegation grants access to */\n path: z.string(),\n /** Actions this delegation authorizes */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string from JSON) */\n expiry: z.coerce.date(),\n /** Whether this delegation has been revoked */\n isRevoked: z.boolean(),\n /** DID of the delegator (the party granting the delegation) */\n delegatorDID: z.string().optional(),\n /** When this delegation was created (accepts Date or ISO string from JSON) */\n createdAt: z.coerce.date().optional(),\n /** Parent delegation CID if this is a sub-delegation */\n parentCid: z.string().optional(),\n /** Whether sub-delegation is allowed */\n allowSubDelegation: z.boolean().optional(),\n /** Authorization header (UCAN bearer token) */\n authHeader: z.string().optional(),\n});\n\nexport type Delegation = z.infer<typeof DelegationSchema>;\n\n/**\n * Entry in the capability registry mapping a capability to available keys.\n */\nexport const CapabilityEntrySchema = z.object({\n /** Resource URI this capability applies to */\n resource: z.string(),\n /** Action this capability authorizes */\n action: z.string(),\n /** Keys that can exercise this capability, ordered by priority */\n keys: z.array(KeyInfoSchema),\n /** The delegation that grants this capability */\n delegation: DelegationSchema,\n /** When this capability expires (accepts Date or ISO string from JSON) */\n expiresAt: z.coerce.date().optional(),\n});\n\nexport type CapabilityEntry = z.infer<typeof CapabilityEntrySchema>;\n\n/**\n * Persistent record of a delegation stored in the system.\n */\nexport const DelegationRecordSchema = z.object({\n /** Content identifier (CID) of the delegation */\n cid: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /** DID of the delegator (grantor) */\n delegator: z.string(),\n /** DID of the delegatee (recipient) */\n delegatee: z.string(),\n /** Key ID used to sign/exercise this delegation */\n keyId: z.string().optional(),\n /** Resource path pattern this delegation grants access to */\n path: z.string(),\n /** Actions this delegation authorizes */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string from JSON) */\n expiry: z.coerce.date().optional(),\n /** When this delegation becomes valid (not before) (accepts Date or ISO string) */\n notBefore: z.coerce.date().optional(),\n /** Whether this delegation has been revoked */\n isRevoked: z.boolean(),\n /** When this delegation was created (accepts Date or ISO string from JSON) */\n createdAt: z.coerce.date(),\n /** Parent delegation CID if this is a sub-delegation */\n parentCid: z.string().optional(),\n});\n\nexport type DelegationRecord = z.infer<typeof DelegationRecordSchema>;\n\n/**\n * Parameters for creating a new delegation.\n */\nexport const CreateDelegationParamsSchema = z.object({\n /** DID of the delegate (the party receiving the delegation) */\n delegateDID: z.string(),\n /** Resource path this delegation grants access to */\n path: z.string(),\n /** Actions to authorize */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string) */\n expiry: z.coerce.date().optional(),\n /** Whether to disable sub-delegation */\n disableSubDelegation: z.boolean().optional(),\n /** Optional statement for the SIWE message */\n statement: z.string().optional(),\n});\n\nexport type CreateDelegationParams = z.infer<typeof CreateDelegationParamsSchema>;\n\n/**\n * A chain of delegations from root to leaf (array format).\n */\nexport const DelegationChainSchema = z.array(DelegationSchema);\nexport type DelegationChain = z.infer<typeof DelegationChainSchema>;\n\n/**\n * Structured delegation chain (v2 spec).\n */\nexport const DelegationChainV2Schema = z.object({\n /** The root delegation from the original authority */\n root: DelegationSchema,\n /** Intermediate delegations in the chain (may be empty) */\n chain: z.array(DelegationSchema),\n /** The final delegation to the current user */\n leaf: DelegationSchema,\n});\n\nexport type DelegationChainV2 = z.infer<typeof DelegationChainV2Schema>;\n\n// =============================================================================\n// Filtering and Query Types\n// =============================================================================\n\n/**\n * Direction of delegation to filter by.\n */\nexport const DelegationDirectionSchema = z.enum([\"granted\", \"received\", \"all\"]);\nexport type DelegationDirection = z.infer<typeof DelegationDirectionSchema>;\n\n/**\n * Filters for listing delegations.\n */\nexport const DelegationFiltersSchema = z.object({\n /** Filter by delegation direction */\n direction: DelegationDirectionSchema.optional(),\n /** Filter by resource path pattern */\n path: z.string().optional(),\n /** Filter by required actions */\n actions: z.array(z.string()).optional(),\n /** Include revoked delegations */\n includeRevoked: z.boolean().optional(),\n /** Filter by delegator DID */\n delegator: z.string().optional(),\n /** Filter by delegatee DID */\n delegatee: z.string().optional(),\n /** Only include delegations valid at this time */\n validAt: z.coerce.date().optional(),\n /** Maximum number of results to return */\n limit: z.number().optional(),\n /** Cursor for pagination */\n cursor: z.string().optional(),\n});\n\nexport type DelegationFilters = z.infer<typeof DelegationFiltersSchema>;\n\n// =============================================================================\n// Space Types\n// =============================================================================\n\n/**\n * Type of space ownership.\n */\nexport const SpaceOwnershipSchema = z.enum([\"owned\", \"delegated\"]);\nexport type SpaceOwnership = z.infer<typeof SpaceOwnershipSchema>;\n\n/**\n * Information about a space the user has access to.\n */\nexport const SpaceInfoSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Human-readable name for the space */\n name: z.string().optional(),\n /** DID of the space owner */\n owner: z.string(),\n /** Whether user owns or has delegated access */\n type: SpaceOwnershipSchema,\n /** Permissions the user has in this space */\n permissions: z.array(z.string()).optional(),\n /** When the access expires (for delegated spaces) */\n expiresAt: z.coerce.date().optional(),\n});\n\nexport type SpaceInfo = z.infer<typeof SpaceInfoSchema>;\n\n// =============================================================================\n// Share Link Types\n// =============================================================================\n\n/**\n * Schema for encoding share link data.\n */\nexport const ShareSchemaSchema = z.enum([\"base64\", \"compact\", \"ipfs\"]);\nexport type ShareSchema = z.infer<typeof ShareSchemaSchema>;\n\n/**\n * A shareable link containing delegation credentials.\n */\nexport const ShareLinkSchema = z.object({\n /** Unique token identifying this share link */\n token: z.string(),\n /** Full URL for sharing */\n url: z.string(),\n /** The delegation this link grants access to */\n delegation: DelegationSchema,\n /** Encoding schema used for the link */\n schema: ShareSchemaSchema,\n /** When this share link expires */\n expiresAt: z.coerce.date().optional(),\n /** Human-readable description of what is being shared */\n description: z.string().optional(),\n});\n\nexport type ShareLink = z.infer<typeof ShareLinkSchema>;\n\n/**\n * Data retrieved from a share link.\n */\nexport function createShareLinkDataSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The retrieved data */\n data: dataSchema,\n /** The delegation that authorized this access */\n delegation: DelegationSchema,\n /** The space the data belongs to */\n spaceId: z.string(),\n /** The resource path that was accessed */\n path: z.string(),\n });\n}\n\nexport const ShareLinkDataSchema = createShareLinkDataSchema(z.unknown());\nexport type ShareLinkData<T = unknown> = {\n data: T;\n delegation: Delegation;\n spaceId: string;\n path: string;\n};\n\n// =============================================================================\n// Ingestion Types\n// =============================================================================\n\n/**\n * Options for ingesting an external delegation.\n */\nexport const IngestOptionsSchema = z.object({\n /** Whether to persist the delegation to storage */\n persist: z.boolean().optional(),\n /** Whether to validate the full delegation chain */\n validateChain: z.boolean().optional(),\n /** Name for the ingested key */\n keyName: z.string().optional(),\n /** Whether to create a session key for this delegation */\n createSessionKey: z.boolean().optional(),\n /** Override the priority for the ingested key */\n priority: z.number().optional(),\n});\n\nexport type IngestOptions = z.infer<typeof IngestOptionsSchema>;\n\n// =============================================================================\n// Parameter Types\n// =============================================================================\n\n/**\n * Parameters for generating a share link.\n */\nexport const GenerateShareParamsSchema = z.object({\n /** Resource path to share */\n path: z.string(),\n /** Actions to authorize */\n actions: z.array(z.string()).optional(),\n /** When the share link expires */\n expiry: z.coerce.date().optional(),\n /** Encoding schema for the link */\n schema: ShareSchemaSchema.optional(),\n /** Human-readable description */\n description: z.string().optional(),\n /** Base URL for the share link */\n baseUrl: z.string().optional(),\n});\n\nexport type GenerateShareParams = z.infer<typeof GenerateShareParamsSchema>;\n\n// =============================================================================\n// Configuration Types\n// =============================================================================\n\n// Note: These types include functions and external types which cannot be fully validated at runtime.\n// We use z.unknown().refine() for runtime type checking while preserving TypeScript types.\n\n/**\n * Configuration for DelegationManager.\n * Note: ServiceSession, InvokeFunction, and FetchFunction are external types.\n */\nexport const DelegationManagerConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string()),\n /** Active session for authentication */\n session: z.unknown().refine(\n (val): val is ServiceSession => val !== null && typeof val === \"object\",\n { message: \"Expected a ServiceSession object\" }\n ),\n /** Platform-specific invoke function */\n invoke: z.unknown().refine(\n (val): val is InvokeFunction => typeof val === \"function\",\n { message: \"Expected an invoke function\" }\n ),\n /** Optional custom fetch implementation */\n fetch: z.unknown().refine(\n (val): val is FetchFunction => val === undefined || typeof val === \"function\",\n { message: \"Expected a fetch function or undefined\" }\n ).optional(),\n});\n\nexport type DelegationManagerConfig = z.infer<typeof DelegationManagerConfigSchema>;\n\n/**\n * Provider interface for cryptographic key operations.\n */\nexport const KeyProviderSchema = z.object({\n /** Generate a new session key, returns key ID */\n createSessionKey: z.unknown().refine(\n (val): val is (name: string) => Promise<string> => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n /** Get JWK for a key */\n getJWK: z.unknown().refine(\n (val): val is (keyId: string) => object => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n /** Get DID for a key */\n getDID: z.unknown().refine(\n (val): val is (keyId: string) => Promise<string> => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n});\n\nexport type KeyProvider = z.infer<typeof KeyProviderSchema>;\n\n// =============================================================================\n// API Response Types\n// =============================================================================\n\n/**\n * Response from the delegation API.\n */\nexport const DelegationApiResponseSchema = z.object({\n /** SIWE message content */\n siwe: z.string(),\n /** Signature of the SIWE message */\n signature: z.string(),\n /** Delegation version */\n version: z.number(),\n /** CID of the created delegation */\n cid: z.string().optional(),\n});\n\nexport type DelegationApiResponse = z.infer<typeof DelegationApiResponseSchema>;\n\n// =============================================================================\n// WASM Delegation Types\n// =============================================================================\n\n/**\n * A single (service, space, path, actions) entry inside a\n * createDelegation WASM result.\n *\n * Mirrors the Rust `DelegatedResource` struct in\n * `tinycloud-sdk-wasm/src/session.rs`. Field names match the manifest\n * {@link PermissionEntry} shape so callers can reconstruct what they sent\n * without having to re-parse the UCAN.\n *\n * `service` is the short form (e.g. `\"kv\"`, `\"sql\"`) as returned by the\n * Rust layer. The SDK layer translates to the long form\n * (`\"tinycloud.kv\"`) when comparing against manifests.\n */\nexport const DelegatedResourceSchema = z.object({\n /** Short-form service name, e.g. \"kv\", \"sql\", \"duckdb\", \"capabilities\", \"hooks\". */\n service: z.string(),\n /** Full space id string, e.g. \"tinycloud:pkh:eip155:1:0x....:default\". */\n space: z.string(),\n /** Resource path; empty string when the resource URI had no path segment. */\n path: z.string(),\n /** Full-URN ability strings, e.g. [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]. */\n actions: z.array(z.string()),\n});\n\nexport type DelegatedResource = z.infer<typeof DelegatedResourceSchema>;\n\n/**\n * Input parameters for the createDelegation WASM function.\n *\n * A single call may encode multiple `(service, path, actions)` entries\n * via the `abilities` map — the underlying UCAN will contain one\n * attenuation entry per `(service, path)` pair, all signed by the same\n * session key in one blob.\n *\n * The `abilities` shape is identical to what `prepareSession` accepts\n * (`Record<shortService, Record<path, actionURNs[]>>`), so manifest\n * resolution can feed both sides from one data structure.\n */\nexport const CreateDelegationWasmParamsSchema = z.object({\n /** The session containing delegation credentials */\n session: z.unknown().refine(\n (val): val is ServiceSession => val !== null && typeof val === \"object\",\n { message: \"Expected a ServiceSession object\" }\n ),\n /** DID of the delegate */\n delegateDID: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /**\n * Multi-resource abilities map: short-service → path → full-URN actions.\n * Matches the shape accepted by `prepareSession`.\n *\n * Example:\n * ```\n * {\n * kv: {\n * \"com.listen.app/\": [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]\n * },\n * sql: {\n * \"com.listen.app/data.sqlite\": [\"tinycloud.sql/read\"]\n * }\n * }\n * ```\n */\n abilities: z.record(z.string(), z.record(z.string(), z.array(z.string()))),\n /** Expiration time in seconds since Unix epoch */\n expirationSecs: z.number(),\n /** Optional not-before time in seconds since Unix epoch */\n notBeforeSecs: z.number().optional(),\n});\n\nexport type CreateDelegationWasmParams = z.infer<typeof CreateDelegationWasmParamsSchema>;\n\n/**\n * Result from the createDelegation WASM function.\n *\n * A single UCAN may cover multiple resources. The `resources` array\n * describes every `(service, space, path, actions)` entry granted, in\n * deterministic (service, path) lexicographic order (the Rust side sorts\n * the HashMap entries before signing).\n */\nexport const CreateDelegationWasmResultSchema = z.object({\n /** Base64url-encoded UCAN delegation */\n delegation: z.string(),\n /** CID of the delegation */\n cid: z.string(),\n /** DID of the delegate */\n delegateDID: z.string(),\n /** Expiration time */\n expiry: z.coerce.date(),\n /**\n * All (service, space, path, actions) entries granted by this delegation.\n * Always non-empty on success.\n */\n resources: z.array(DelegatedResourceSchema),\n});\n\nexport type CreateDelegationWasmResult = z.infer<typeof CreateDelegationWasmResultSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validates a Delegation object and returns a Result.\n */\nexport function validateDelegation(data: unknown): Result<Delegation, DelegationError> {\n const result = DelegationSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a CreateDelegationParams object and returns a Result.\n */\nexport function validateCreateDelegationParams(\n data: unknown\n): Result<CreateDelegationParams, DelegationError> {\n const result = CreateDelegationParamsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a DelegationFilters object and returns a Result.\n */\nexport function validateDelegationFilters(\n data: unknown\n): Result<DelegationFilters, DelegationError> {\n const result = DelegationFiltersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a ShareLink object and returns a Result.\n */\nexport function validateShareLink(data: unknown): Result<ShareLink, DelegationError> {\n const result = ShareLinkSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Generic validation function factory.\n */\nexport function createValidator<T>(\n schema: z.ZodType<T>\n): (data: unknown) => Result<T, DelegationError> {\n return (data: unknown): Result<T, DelegationError> => {\n const result = schema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n };\n}\n","/**\n * Shared space utilities for TinyCloud.\n *\n * These functions are platform-agnostic and can be used by both\n * web-sdk and node-sdk for space hosting and session activation.\n */\n\n/**\n * Result of a space hosting or session activation attempt.\n */\nexport interface SpaceHostResult {\n /** Whether the operation succeeded (2xx status) */\n success: boolean;\n /** HTTP status code */\n status: number;\n /** Error message if failed */\n error?: string;\n /** Space IDs that were successfully activated */\n activated?: string[];\n /** Space IDs that were skipped (e.g., space doesn't exist yet) */\n skipped?: string[];\n}\n\n/**\n * Fetch the peer ID from TinyCloud server for space hosting.\n *\n * The peer ID identifies the TinyCloud server instance that will host the space.\n *\n * @param host - TinyCloud server URL (e.g., \"https://node.tinycloud.xyz\")\n * @param spaceId - The space ID to host\n * @returns The peer ID string\n * @throws Error if the request fails\n */\nexport async function fetchPeerId(\n host: string,\n spaceId: string\n): Promise<string> {\n const res = await fetch(\n `${host}/peer/generate/${encodeURIComponent(spaceId)}`\n );\n\n if (!res.ok) {\n const error = await res.text().catch(() => res.statusText);\n throw new Error(`Failed to get peer ID: ${res.status} - ${error}`);\n }\n\n return res.text();\n}\n\n/**\n * Submit a space hosting delegation to TinyCloud server.\n *\n * This registers a new space with the server, allowing the user\n * to store data in it.\n *\n * @param host - TinyCloud server URL\n * @param headers - Delegation headers (from siweToDelegationHeaders)\n * @returns Result indicating success/failure\n */\nexport async function submitHostDelegation(\n host: string,\n headers: Record<string, string>\n): Promise<SpaceHostResult> {\n const res = await fetch(`${host}/delegate`, {\n method: \"POST\",\n headers,\n });\n\n return {\n success: res.ok,\n status: res.status,\n error: res.ok ? undefined : await res.text().catch(() => res.statusText),\n };\n}\n\n/**\n * Activate a session with TinyCloud server.\n *\n * This submits the session delegation to the server, enabling the session\n * key to perform operations on behalf of the user.\n *\n * @param host - TinyCloud server URL\n * @param delegationHeader - Session delegation header (from session.delegationHeader)\n * @returns Result indicating success/failure (404 means space doesn't exist)\n */\nexport async function activateSessionWithHost(\n host: string,\n delegationHeader: { Authorization: string }\n): Promise<SpaceHostResult> {\n const res = await fetch(`${host}/delegate`, {\n method: \"POST\",\n headers: delegationHeader,\n });\n\n if (res.ok) {\n try {\n const body = await res.json() as { activated?: string[]; skipped?: string[] };\n return {\n success: true,\n status: res.status,\n activated: body.activated ?? [],\n skipped: body.skipped ?? [],\n };\n } catch {\n // Fallback for older servers that return plain text CID\n return {\n success: true,\n status: res.status,\n activated: [],\n skipped: [],\n };\n }\n }\n\n return {\n success: false,\n status: res.status,\n error: await res.text().catch(() => res.statusText),\n };\n}\n","/**\n * DelegationManager - Handles delegation CRUD operations.\n *\n * This class manages the creation, revocation, listing, and querying\n * of delegations within TinyCloud. It extracts and improves upon the\n * delegation functionality previously in ITinyCloudStorage.\n *\n * @packageDocumentation\n */\n\nimport type {\n FetchFunction,\n FetchResponse,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\nimport {\n Result,\n DelegationError,\n DelegationErrorCodes,\n Delegation,\n CreateDelegationParams,\n DelegationChain,\n DelegationManagerConfig,\n DelegationApiResponse,\n} from \"./types\";\n\n/**\n * Delegation action constants.\n */\nconst DelegationAction = {\n CREATE: \"tinycloud.delegation/create\",\n REVOKE: \"tinycloud.delegation/revoke\",\n LIST: \"tinycloud.delegation/list\",\n GET: \"tinycloud.delegation/get\",\n CHECK: \"tinycloud.delegation/check\",\n} as const;\n\n/**\n * Creates a DelegationError with the given parameters.\n */\nfunction createError(\n code: string,\n message: string,\n cause?: Error,\n meta?: Record<string, unknown>\n): DelegationError {\n return {\n code,\n message,\n service: \"delegation\",\n cause,\n meta,\n };\n}\n\n/**\n * DelegationManager handles all delegation-related operations.\n *\n * @example\n * ```typescript\n * import { DelegationManager } from \"@tinycloud/sdk-core/delegations\";\n *\n * const delegations = new DelegationManager({\n * hosts: [\"https://node.tinycloud.xyz\"],\n * session,\n * invoke,\n * });\n *\n * // Create a delegation\n * const result = await delegations.create({\n * delegateDID: \"did:pkh:eip155:1:0x...\",\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/list\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours\n * });\n *\n * if (result.ok) {\n * console.log(\"Created delegation:\", result.data.cid);\n * }\n * ```\n */\nexport class DelegationManager {\n private hosts: string[];\n private session: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n\n /**\n * Creates a new DelegationManager instance.\n *\n * @param config - Configuration including hosts, session, and invoke function\n */\n constructor(config: DelegationManagerConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Updates the session (e.g., after re-authentication).\n *\n * @param session - New session to use for operations\n */\n public updateSession(session: ServiceSession): void {\n this.session = session;\n }\n\n /**\n * Gets the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Executes an invoke operation against the delegation API.\n */\n private async invokeOperation(\n path: string,\n action: string,\n body?: string\n ): Promise<FetchResponse> {\n const headers = this.invoke(this.session, \"delegation\", path, action);\n\n return this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n });\n }\n\n /**\n * Creates a new delegation.\n *\n * Delegates specific permissions to another DID for a given path.\n * The delegatee can then use these permissions to access resources\n * within the specified scope.\n *\n * @param params - Parameters for the delegation\n * @returns Result containing the created Delegation or an error\n *\n * @example\n * ```typescript\n * const result = await manager.create({\n * delegateDID: bob.did,\n * path: \"documents/shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days\n * });\n * ```\n */\n async create(params: CreateDelegationParams): Promise<Result<Delegation>> {\n // Validate inputs\n if (!params.delegateDID) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"delegateDID is required\"\n ),\n };\n }\n\n if (!params.path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n if (!params.actions || params.actions.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"at least one action is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({\n delegateDID: params.delegateDID,\n path: params.path,\n actions: params.actions,\n expiry: params.expiry?.toISOString(),\n disableSubDelegation: params.disableSubDelegation ?? false,\n statement: params.statement,\n });\n\n const response = await this.invokeOperation(\n params.path,\n DelegationAction.CREATE,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, path: params.path }\n ),\n };\n }\n\n const apiResponse = (await response.json()) as DelegationApiResponse;\n\n const delegation: Delegation = {\n cid: apiResponse.cid ?? \"\",\n delegateDID: params.delegateDID,\n spaceId: this.session.spaceId,\n path: params.path,\n actions: params.actions,\n expiry: params.expiry ?? new Date(Date.now() + 24 * 60 * 60 * 1000),\n isRevoked: false,\n allowSubDelegation: !(params.disableSubDelegation ?? false),\n createdAt: new Date(),\n };\n\n return { ok: true, data: delegation };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation creation: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Revokes an existing delegation.\n *\n * Once revoked, the delegation can no longer be used to access resources.\n * This also invalidates any sub-delegations derived from this delegation.\n *\n * @param cid - The CID of the delegation to revoke\n * @returns Result indicating success or an error\n *\n * @example\n * ```typescript\n * const result = await manager.revoke(\"bafy...\");\n * if (result.ok) {\n * console.log(\"Delegation revoked successfully\");\n * }\n * ```\n */\n async revoke(cid: string): Promise<Result<void>> {\n if (!cid) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"cid is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ cid });\n\n const response = await this.invokeOperation(\n cid,\n DelegationAction.REVOKE,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 404) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_FOUND,\n `Delegation not found: ${cid}`\n ),\n };\n }\n\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.REVOCATION_FAILED,\n `Failed to revoke delegation: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, cid }\n ),\n };\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation revocation: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Lists all delegations for the current session's space.\n *\n * Returns both delegations created by the current user (as delegator)\n * and delegations granted to the current user (as delegatee).\n *\n * @returns Result containing an array of Delegations or an error\n *\n * @example\n * ```typescript\n * const result = await manager.list();\n * if (result.ok) {\n * for (const delegation of result.data) {\n * console.log(`${delegation.cid}: ${delegation.path} -> ${delegation.delegateDID}`);\n * }\n * }\n * ```\n */\n async list(): Promise<Result<Delegation[]>> {\n try {\n const response = await this.invokeOperation(\"\", DelegationAction.LIST);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to list delegations: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status }\n ),\n };\n }\n\n const data = (await response.json()) as Array<{\n cid: string;\n delegateDID: string;\n delegatorDID?: string;\n spaceId: string;\n path: string;\n actions: string[];\n expiry: string;\n isRevoked: boolean;\n createdAt?: string;\n parentCid?: string;\n allowSubDelegation?: boolean;\n }>;\n\n const delegations: Delegation[] = data.map((item) => ({\n cid: item.cid,\n delegateDID: item.delegateDID,\n delegatorDID: item.delegatorDID,\n spaceId: item.spaceId,\n path: item.path,\n actions: item.actions,\n expiry: new Date(item.expiry),\n isRevoked: item.isRevoked,\n createdAt: item.createdAt ? new Date(item.createdAt) : undefined,\n parentCid: item.parentCid,\n allowSubDelegation: item.allowSubDelegation,\n }));\n\n return { ok: true, data: delegations };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation list: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Gets the full delegation chain for a given delegation.\n *\n * Returns the chain of delegations from the root (original delegator)\n * to the specified delegation, including all intermediate sub-delegations.\n *\n * @param cid - The CID of the delegation to get the chain for\n * @returns Result containing the DelegationChain or an error\n *\n * @example\n * ```typescript\n * const result = await manager.getChain(\"bafy...\");\n * if (result.ok) {\n * console.log(\"Chain length:\", result.data.length);\n * for (const delegation of result.data) {\n * console.log(`- ${delegation.delegatorDID} -> ${delegation.delegateDID}`);\n * }\n * }\n * ```\n */\n async getChain(cid: string): Promise<Result<DelegationChain>> {\n if (!cid) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"cid is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ cid, includeChain: true });\n\n const response = await this.invokeOperation(\n cid,\n DelegationAction.GET,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 404) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_FOUND,\n `Delegation not found: ${cid}`\n ),\n };\n }\n\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to get delegation chain: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, cid }\n ),\n };\n }\n\n const data = (await response.json()) as {\n chain: Array<{\n cid: string;\n delegateDID: string;\n delegatorDID?: string;\n spaceId: string;\n path: string;\n actions: string[];\n expiry: string;\n isRevoked: boolean;\n createdAt?: string;\n parentCid?: string;\n allowSubDelegation?: boolean;\n }>;\n };\n\n const chain: DelegationChain = data.chain.map((item) => ({\n cid: item.cid,\n delegateDID: item.delegateDID,\n delegatorDID: item.delegatorDID,\n spaceId: item.spaceId,\n path: item.path,\n actions: item.actions,\n expiry: new Date(item.expiry),\n isRevoked: item.isRevoked,\n createdAt: item.createdAt ? new Date(item.createdAt) : undefined,\n parentCid: item.parentCid,\n allowSubDelegation: item.allowSubDelegation,\n }));\n\n return { ok: true, data: chain };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during chain retrieval: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Checks if the current session has permission for a given path and action.\n *\n * This can be used to verify permissions before attempting an operation,\n * or to implement custom access control logic.\n *\n * @param path - The resource path to check\n * @param action - The action to check (e.g., \"tinycloud.kv/get\")\n * @returns Result containing a boolean indicating permission or an error\n *\n * @example\n * ```typescript\n * const result = await manager.checkPermission(\"documents/private/\", \"tinycloud.kv/put\");\n * if (result.ok && result.data) {\n * console.log(\"Permission granted\");\n * } else {\n * console.log(\"Permission denied\");\n * }\n * ```\n */\n async checkPermission(path: string, action: string): Promise<Result<boolean>> {\n if (!path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n if (!action) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"action is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ path, action });\n\n const response = await this.invokeOperation(\n path,\n DelegationAction.CHECK,\n body\n );\n\n if (!response.ok) {\n // 403 means permission denied, which is a valid result\n if (response.status === 403) {\n return { ok: true, data: false };\n }\n\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to check permission: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, path, action }\n ),\n };\n }\n\n const data = (await response.json()) as { allowed: boolean };\n return { ok: true, data: data.allowed };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during permission check: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n}\n","/**\n * Zod schemas for SharingService types.\n *\n * These schemas provide runtime validation for sharing link data,\n * receive options, and service configuration.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type {\n FetchFunction,\n IKVService,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\nimport {\n JWKSchema,\n DelegationSchema,\n KeyProviderSchema,\n IngestOptionsSchema,\n type Result,\n type DelegationError,\n DelegationErrorCodes,\n} from \"./types.schema.js\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry.js\";\nimport type { DelegationManager } from \"./DelegationManager.js\";\n\n// =============================================================================\n// EncodedShareData Schema\n// =============================================================================\n\n/**\n * Schema for data encoded in a sharing link.\n *\n * This is the primary validation point for external share link data.\n * The link is base64-decoded and JSON-parsed, then validated against this schema.\n */\nexport const EncodedShareDataSchema = z.object({\n /** Private key in JWK format (must include d parameter) */\n key: JWKSchema.refine(\n (jwk) => typeof jwk.d === \"string\" && jwk.d.length > 0,\n { message: \"JWK must include private key (d parameter)\" }\n ),\n /** DID of the key */\n keyDid: z.string().min(1, \"keyDid is required\"),\n /** The delegation granting access */\n delegation: DelegationSchema,\n /** Resource path this link grants access to */\n path: z.string().min(1, \"path is required\"),\n /** TinyCloud host URL */\n host: z.string().url(\"host must be a valid URL\"),\n /** Space ID */\n spaceId: z.string().min(1, \"spaceId is required\"),\n /** Schema version (must be 1) */\n version: z.literal(1),\n});\n\nexport type EncodedShareData = z.infer<typeof EncodedShareDataSchema>;\n\n// =============================================================================\n// ReceiveOptions Schema\n// =============================================================================\n\n/**\n * Schema for options when receiving a sharing link.\n */\nexport const ReceiveOptionsSchema = z.object({\n /**\n * Whether to automatically create a sub-delegation to the current session key.\n * Default: true\n */\n autoSubdelegate: z.boolean().optional(),\n /**\n * Whether to use the current session key for operations (requires autoSubdelegate).\n * Default: true\n */\n useSessionKey: z.boolean().optional(),\n /**\n * Ingestion options passed to CapabilityKeyRegistry.\n */\n ingestOptions: IngestOptionsSchema.optional(),\n});\n\nexport type ReceiveOptions = z.infer<typeof ReceiveOptionsSchema>;\n\n// =============================================================================\n// SharingServiceConfig Schema\n// =============================================================================\n\n/**\n * Schema for SharingService configuration.\n *\n * Note: Function fields use z.function() for shape validation only.\n * External types (ServiceSession, DelegationManager, ICapabilityKeyRegistry)\n * use z.unknown() with runtime type refinement.\n */\nexport const SharingServiceConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string().url()).min(1, \"At least one host URL is required\"),\n /**\n * Active session for authentication.\n * Required for generate(), optional for receive().\n */\n session: z\n .unknown()\n .refine(\n (val): val is ServiceSession =>\n val === undefined || (val !== null && typeof val === \"object\"),\n { message: \"Expected a ServiceSession object or undefined\" }\n )\n .optional(),\n /** Platform-specific invoke function */\n invoke: z\n .unknown()\n .refine((val): val is InvokeFunction => typeof val === \"function\", {\n message: \"Expected an invoke function\",\n }),\n /** Optional custom fetch implementation */\n fetch: z\n .unknown()\n .refine(\n (val): val is FetchFunction =>\n val === undefined || typeof val === \"function\",\n { message: \"Expected a fetch function or undefined\" }\n )\n .optional(),\n /** Key provider for cryptographic operations */\n keyProvider: KeyProviderSchema,\n /** Capability key registry for key/delegation management */\n registry: z\n .unknown()\n .refine(\n (val): val is ICapabilityKeyRegistry =>\n val !== null && typeof val === \"object\",\n { message: \"Expected an ICapabilityKeyRegistry object\" }\n ),\n /**\n * Delegation manager for creating delegations.\n * Required for generate(), optional for receive().\n */\n delegationManager: z\n .unknown()\n .refine(\n (val): val is DelegationManager =>\n val === undefined || (val !== null && typeof val === \"object\"),\n { message: \"Expected a DelegationManager object or undefined\" }\n )\n .optional(),\n /** Factory for creating KV service instances */\n createKVService: z.unknown().refine(\n (val): val is (config: {\n hosts: string[];\n session: ServiceSession;\n invoke: InvokeFunction;\n fetch?: FetchFunction;\n pathPrefix?: string;\n }) => IKVService => typeof val === \"function\",\n { message: \"Expected a createKVService factory function\" }\n ),\n /** Base URL for sharing links (e.g., \"https://share.myapp.com\") */\n baseUrl: z.string().optional(),\n /**\n * Custom delegation creation function.\n */\n createDelegation: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected a createDelegation function or undefined\",\n })\n .optional(),\n /**\n * WASM function for client-side delegation creation.\n */\n createDelegationWasm: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected a createDelegationWasm function or undefined\",\n })\n .optional(),\n /**\n * Path prefix for KV operations.\n */\n pathPrefix: z.string().optional(),\n /**\n * Session expiry time.\n */\n sessionExpiry: z.date().optional(),\n /**\n * Callback to create a DIRECT delegation from wallet to share key.\n * This is the preferred method for long-lived share links because it\n * bypasses the session delegation chain entirely.\n */\n onRootDelegationNeeded: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected an onRootDelegationNeeded function or undefined\",\n })\n .optional(),\n});\n\nexport type SharingServiceConfig = z.infer<typeof SharingServiceConfigSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validates encoded share data from a decoded link.\n *\n * @param data - Unknown data to validate (from JSON.parse)\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const parsed = JSON.parse(base64UrlDecode(linkData));\n * const result = validateEncodedShareData(parsed);\n * if (!result.ok) {\n * return result; // Forward the error\n * }\n * const shareData = result.data;\n * ```\n */\nexport function validateEncodedShareData(\n data: unknown\n): Result<EncodedShareData, DelegationError> {\n const result = EncodedShareDataSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid share data: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates receive options.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateReceiveOptions(\n data: unknown\n): Result<ReceiveOptions, DelegationError> {\n const result = ReceiveOptionsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid receive options: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates SharingService configuration.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateSharingServiceConfig(\n data: unknown\n): Result<SharingServiceConfig, DelegationError> {\n const result = SharingServiceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid SharingService config: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * TinyCloud App Manifest\n *\n * A declarative description of an app's identity and the capabilities it\n * needs. The manifest drives the SIWE recap at sign-in time, enabling a\n * single wallet prompt that covers the app's own permissions plus any\n * pre-declared delegations.\n *\n * The SDK does NOT fetch external manifests. Apps compose their own manifest\n * (optionally including backend or agent addenda) before handing it to the\n * SDK.\n *\n * Canonical spec: `.claude/specs/manifest.md`.\n *\n * @packageDocumentation\n */\n\nimport ms from \"ms\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A single permission entry inside a manifest. This is the shape apps write\n * in their `manifest.json` and the shape we compare against when performing\n * the capability-subset derivability check in the delegation flow.\n *\n * `service` uses the long form (e.g. `\"tinycloud.kv\"`, `\"tinycloud.sql\"`)\n * which matches the ability-namespace half of the full action URN.\n */\nexport interface PermissionEntry {\n /** Service namespace, e.g. \"tinycloud.kv\", \"tinycloud.sql\", \"tinycloud.duckdb\", \"tinycloud.capabilities\". */\n service: string;\n /** \"default\" for the user's personal space, or a specific space id. */\n space: string;\n /**\n * Service-specific path.\n * - tinycloud.kv: hierarchical prefix. \"/\" = all, \"foo/\" = prefix match, \"foo\" = exact key\n * - tinycloud.sql: database name/file (e.g. \"data.sqlite\") or \"/\" for all\n * - tinycloud.duckdb: database name/file\n * - tinycloud.capabilities: capability key URI or \"/\" for all\n */\n path: string;\n /**\n * Short action names (e.g. \"get\", \"put\", \"read\", \"ddl\"). The SDK expands\n * these to full URNs (e.g. `tinycloud.kv/get`) during resolution.\n * Already-expanded URNs are passed through unchanged.\n */\n actions: string[];\n /** When true, the manifest prefix is NOT prepended to `path`. Default false. */\n skipPrefix?: boolean;\n /** Per-entry expiry override, ms-format. */\n expiry?: string;\n}\n\n/**\n * A pre-declared delegation that will be included in the main SIWE recap as\n * an additional audience.\n */\nexport interface ManifestDelegation {\n /** DID of the delegate (e.g. a backend's wallet DID). */\n to: string;\n /** Informational display name. Optional. */\n name?: string;\n /** Expiry override for this delegation, ms-format. Optional. */\n expiry?: string;\n /**\n * Permissions to delegate. Same shape as the top-level `permissions`, and\n * the manifest prefix is inherited identically (unless `skipPrefix: true`).\n */\n permissions: PermissionEntry[];\n}\n\n/**\n * The valid values for `Manifest.defaults`.\n *\n * - `false` → no auto-included permissions\n * - `true` → standard tier (KV + SQL read/write + capabilities:read)\n * - `\"admin\"` → standard + SQL ddl + capabilities:admin\n * - `\"all\"` → everything the SDK supports (including DuckDB)\n *\n * Unknown string values silently fall back to `true`. Values are normalized\n * (lowercase + trim) before matching.\n */\nexport type ManifestDefaults = boolean | \"admin\" | \"all\";\n\n/**\n * The raw manifest shape an app declares. See `.claude/specs/manifest.md`.\n */\nexport interface Manifest {\n /** Schema version. Optional, defaults to 1. */\n version?: number;\n /** Bundle identifier — reverse DNS. Required. */\n id: string;\n /** Display name. Required. */\n name: string;\n /** One-line description. Optional. */\n description?: string;\n /** URL to app icon. Optional. */\n icon?: string;\n /** App version string. Optional. */\n appVersion?: string;\n /** Default expiry for permissions. ms-format (\"30d\", \"2h\", \"1y\"). Default \"30d\". */\n expiry?: string;\n /**\n * Path prefix auto-prepended to permission paths. Optional, defaults to\n * `id`. Set to `\"\"` to disable entirely. Individual permissions can opt\n * out with `skipPrefix: true`.\n */\n prefix?: string;\n /**\n * Default permission set to auto-include. Optional, defaults to `true`.\n * See {@link ManifestDefaults}.\n */\n defaults?: ManifestDefaults | string;\n /** Whether to include the public-space companion delegation. Default `true`. */\n includePublicSpace?: boolean;\n /**\n * Additional permissions beyond the defaults. Use for cross-space access,\n * DuckDB (opt-in), or `skipPrefix: true` entries.\n */\n permissions?: PermissionEntry[];\n /** Pre-delegations to other DIDs at sign-in. */\n delegations?: ManifestDelegation[];\n}\n\n/**\n * A resolved permission entry with fully-expanded paths and action URNs.\n * This is the shape the delegation flow compares against parsed recap\n * capabilities, and the shape the session-key delegation path actually uses.\n */\nexport interface ResourceCapability {\n /** Long-form service, e.g. \"tinycloud.kv\". */\n service: string;\n /** Space id — \"default\" stays as-is here; the caller resolves it to a full SpaceId at sign-in time. */\n space: string;\n /** Path with the manifest prefix applied (or skipped per `skipPrefix`). */\n path: string;\n /** Full-URN actions, e.g. [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]. */\n actions: string[];\n /** Per-entry expiry override in milliseconds. */\n expiryMs?: number;\n}\n\n/**\n * A resolved delegation entry with fully-expanded permissions.\n */\nexport interface ResolvedDelegate {\n /** DID of the delegate. */\n did: string;\n /** Informational display name. Optional. */\n name?: string;\n /** Expiry in milliseconds (per-delegation > manifest default > 30 days). */\n expiryMs: number;\n /** Fully resolved permissions. */\n permissions: ResourceCapability[];\n}\n\n/**\n * The output of {@link resolveManifest}: a fully-expanded capability set\n * ready to drive the SIWE recap.\n */\nexport interface ResolvedCapabilities {\n /** Bundle identifier copied from manifest.id. */\n id: string;\n /** All session-key resources with paths fully resolved (prefix applied). */\n resources: ResourceCapability[];\n /** Default expiry for the session, in milliseconds. */\n expiryMs: number;\n /** Whether to include the public-space companion. */\n includePublicSpace: boolean;\n /** Additional delegate targets with resolved paths. */\n additionalDelegates: ResolvedDelegate[];\n}\n\n/**\n * Thrown when the manifest fails validation (missing id/name, bad expiry,\n * empty actions on a permission, etc).\n */\nexport class ManifestValidationError extends Error {\n constructor(message: string) {\n super(`Manifest validation failed: ${message}`);\n this.name = \"ManifestValidationError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default expiry when neither the manifest, delegation, nor permission\n * specifies one. Spec: 30 days.\n */\nexport const DEFAULT_EXPIRY = \"30d\";\n\n/**\n * Default `defaults` value when the manifest omits it. Spec: standard tier.\n */\nexport const DEFAULT_DEFAULTS: ManifestDefaults = true;\n\n/**\n * Known services and their short-form (recap URI) names. The TinyCloud\n * node encodes the recap resource URI with the short service name, while\n * action URNs and manifest entries use the long `tinycloud.<short>` form.\n * This table is the canonical bridge between the two.\n */\nexport const SERVICE_SHORT_TO_LONG: Readonly<Record<string, string>> =\n Object.freeze({\n kv: \"tinycloud.kv\",\n sql: \"tinycloud.sql\",\n duckdb: \"tinycloud.duckdb\",\n capabilities: \"tinycloud.capabilities\",\n hooks: \"tinycloud.hooks\",\n });\n\n/**\n * Inverse of {@link SERVICE_SHORT_TO_LONG}.\n */\nexport const SERVICE_LONG_TO_SHORT: Readonly<Record<string, string>> =\n Object.freeze(\n Object.fromEntries(\n Object.entries(SERVICE_SHORT_TO_LONG).map(([s, l]) => [l, s])\n )\n );\n\n/**\n * Default permission entries for the `true` / standard tier.\n *\n * `tinycloud.capabilities:read` is ALWAYS present in any non-false default\n * so delegation chains can be verified.\n */\nconst DEFAULT_STANDARD_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] =\n [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\"],\n },\n ];\n\n/**\n * Default permission entries for the `\"admin\"` tier: standard + sql/ddl +\n * capabilities/admin.\n */\nconst DEFAULT_ADMIN_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] = [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\", \"ddl\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"admin\"],\n },\n];\n\n/**\n * Default permission entries for the `\"all\"` tier: admin + DuckDB.\n *\n * DuckDB is opt-in and only appears in this tier or in explicit manifest\n * `permissions` entries.\n */\nconst DEFAULT_ALL_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] = [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\", \"ddl\"],\n },\n {\n service: \"tinycloud.duckdb\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"admin\"],\n },\n];\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an ms-format duration string (e.g. \"30d\", \"2h\", \"1y\") into\n * milliseconds.\n *\n * @throws {ManifestValidationError} on empty string, non-string input, or\n * any input `ms()` cannot parse.\n */\nexport function parseExpiry(duration: string): number {\n if (typeof duration !== \"string\" || duration.length === 0) {\n throw new ManifestValidationError(\n `expiry must be a non-empty duration string (got ${JSON.stringify(duration)})`\n );\n }\n // `ms` returns `undefined` for unparseable input and can return a number\n // or a string depending on the call signature; cast explicitly.\n const parsed = (ms as unknown as (v: string) => number | undefined)(\n duration\n );\n if (typeof parsed !== \"number\" || !Number.isFinite(parsed) || parsed <= 0) {\n throw new ManifestValidationError(\n `invalid expiry duration: ${JSON.stringify(duration)}`\n );\n }\n return parsed;\n}\n\n/**\n * Expand a list of action short names (or already-expanded URNs) into full\n * ability URNs of the form `<service>/<action>`.\n *\n * Examples:\n * `expandActionShortNames(\"tinycloud.kv\", [\"get\", \"put\"])`\n * → `[\"tinycloud.kv/get\", \"tinycloud.kv/put\"]`\n * `expandActionShortNames(\"tinycloud.kv\", [\"tinycloud.kv/get\"])`\n * → `[\"tinycloud.kv/get\"]` (passed through unchanged)\n */\nexport function expandActionShortNames(\n service: string,\n actions: readonly string[]\n): string[] {\n return actions.map((a) => {\n if (a.includes(\"/\")) {\n // Already a full URN — pass through.\n return a;\n }\n return `${service}/${a}`;\n });\n}\n\n/**\n * Apply the manifest prefix to a permission path per the spec rules.\n *\n * - `skipPrefix: true` → path is returned as-is\n * - `prefix === \"\"` → path is returned as-is\n * - path starts with \"/\" → `prefix + path` (e.g. \"com.listen.app\" + \"/\" → \"com.listen.app/\")\n * - otherwise → `prefix + \"/\" + path` (e.g. \"com.listen.app\" + \"data.sqlite\" → \"com.listen.app/data.sqlite\")\n */\nexport function applyPrefix(\n prefix: string,\n path: string,\n skipPrefix: boolean\n): string {\n if (skipPrefix) {\n return path;\n }\n if (prefix === \"\") {\n return path;\n }\n if (path.startsWith(\"/\")) {\n return `${prefix}${path}`;\n }\n return `${prefix}/${path}`;\n}\n\n/**\n * Fetch and parse a manifest from a URL (browser) or file path (node).\n * The runtime decides the fetch strategy via `globalThis.fetch`; this is\n * platform-agnostic. Callers that want custom loading should JSON.parse a\n * Manifest themselves and skip this helper.\n *\n * @throws if the fetch fails, the JSON is invalid, or the manifest fails\n * validation.\n */\nexport async function loadManifest(url: string): Promise<Manifest> {\n const fetchFn: typeof fetch | undefined = (globalThis as { fetch?: typeof fetch }).fetch;\n if (typeof fetchFn !== \"function\") {\n throw new ManifestValidationError(\n \"loadManifest requires a global fetch; pass the manifest object directly on runtimes without fetch\"\n );\n }\n const res = await fetchFn(url);\n if (!res.ok) {\n throw new ManifestValidationError(\n `failed to fetch manifest from ${url}: HTTP ${res.status}`\n );\n }\n const json = (await res.json()) as unknown;\n return validateManifest(json);\n}\n\n/**\n * Validate a manifest-shaped object and return it strongly-typed.\n * Throws {@link ManifestValidationError} on any hard failure.\n */\nexport function validateManifest(input: unknown): Manifest {\n if (input === null || typeof input !== \"object\") {\n throw new ManifestValidationError(\"manifest must be an object\");\n }\n const m = input as Manifest;\n if (typeof m.id !== \"string\" || m.id.length === 0) {\n throw new ManifestValidationError(\"manifest.id is required and must be a non-empty string\");\n }\n if (typeof m.name !== \"string\" || m.name.length === 0) {\n throw new ManifestValidationError(\"manifest.name is required and must be a non-empty string\");\n }\n if (m.expiry !== undefined) {\n // Will throw with a clear error if invalid.\n parseExpiry(m.expiry);\n }\n if (m.permissions !== undefined) {\n if (!Array.isArray(m.permissions)) {\n throw new ManifestValidationError(\"manifest.permissions must be an array\");\n }\n m.permissions.forEach((p, i) =>\n validatePermissionEntry(p, `permissions[${i}]`)\n );\n }\n if (m.delegations !== undefined) {\n if (!Array.isArray(m.delegations)) {\n throw new ManifestValidationError(\"manifest.delegations must be an array\");\n }\n m.delegations.forEach((d, i) => {\n if (typeof d?.to !== \"string\" || d.to.length === 0) {\n throw new ManifestValidationError(\n `delegations[${i}].to is required and must be a non-empty DID string`\n );\n }\n if (d.expiry !== undefined) {\n parseExpiry(d.expiry);\n }\n if (!Array.isArray(d.permissions)) {\n throw new ManifestValidationError(\n `delegations[${i}].permissions must be an array`\n );\n }\n d.permissions.forEach((p, j) =>\n validatePermissionEntry(p, `delegations[${i}].permissions[${j}]`)\n );\n });\n }\n return m;\n}\n\nfunction validatePermissionEntry(p: unknown, path: string): void {\n if (p === null || typeof p !== \"object\") {\n throw new ManifestValidationError(`${path} must be an object`);\n }\n const entry = p as PermissionEntry;\n if (typeof entry.service !== \"string\" || entry.service.length === 0) {\n throw new ManifestValidationError(`${path}.service is required`);\n }\n if (typeof entry.space !== \"string\" || entry.space.length === 0) {\n throw new ManifestValidationError(`${path}.space is required`);\n }\n if (typeof entry.path !== \"string\") {\n throw new ManifestValidationError(\n `${path}.path is required (use \"\" or \"/\" for root)`\n );\n }\n if (!Array.isArray(entry.actions) || entry.actions.length === 0) {\n throw new ManifestValidationError(\n `${path}.actions must be a non-empty array`\n );\n }\n if (entry.expiry !== undefined) {\n parseExpiry(entry.expiry);\n }\n}\n\n/**\n * Normalize a `defaults` value: lowercase + trim, then match against known\n * tiers. Unknown string values silently fall back to `true` (standard).\n * Boolean values pass through.\n */\nexport function normalizeDefaults(\n value: Manifest[\"defaults\"] | undefined\n): ManifestDefaults {\n if (value === undefined) {\n return DEFAULT_DEFAULTS;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value !== \"string\") {\n // Spec says unknown values silently fall back to `true`.\n return true;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === \"admin\" || normalized === \"all\") {\n return normalized;\n }\n // Anything else, including \"true\"/\"false\"/\"standard\"/garbage, falls back\n // to the standard tier per spec.\n return true;\n}\n\n/**\n * Return the default permission entries for the given tier. Entries are\n * deep-cloned so callers can mutate them without affecting the constants.\n */\nfunction defaultEntriesForTier(\n tier: ManifestDefaults\n): PermissionEntry[] {\n if (tier === false) {\n return [];\n }\n const source =\n tier === \"admin\"\n ? DEFAULT_ADMIN_ENTRIES\n : tier === \"all\"\n ? DEFAULT_ALL_ENTRIES\n : DEFAULT_STANDARD_ENTRIES;\n return source.map((e) => ({\n service: e.service,\n space: e.space,\n path: e.path,\n actions: [...e.actions],\n }));\n}\n\n/**\n * Resolve a raw manifest into a {@link ResolvedCapabilities} object: expand\n * shortform actions, apply the prefix, merge defaults, and compute effective\n * expiries. Pure function — does no I/O.\n *\n * Resolution semantics (spec):\n * - `prefix` defaults to `id`; set to `\"\"` to disable prefix application entirely.\n * - `defaults` defaults to `true` (standard tier); unknown string values fall back to `true`.\n * - Per-entry expiry overrides per-delegation overrides manifest > `DEFAULT_EXPIRY`.\n * - Default entries use `skipPrefix: false` so they inherit the manifest prefix.\n * - Prefix inheritance applies identically to `permissions` and `delegations[*].permissions`.\n */\nexport function resolveManifest(\n input: Manifest\n): ResolvedCapabilities {\n const manifest = validateManifest(input);\n\n const prefix = manifest.prefix !== undefined ? manifest.prefix : manifest.id;\n const expiryMs = parseExpiry(manifest.expiry ?? DEFAULT_EXPIRY);\n const includePublicSpace = manifest.includePublicSpace ?? true;\n const tier = normalizeDefaults(manifest.defaults);\n\n const defaultEntries = defaultEntriesForTier(tier);\n const explicitEntries = manifest.permissions ?? [];\n\n // Merge order: defaults first, then explicit entries, so explicit entries\n // for the same (service, space, path) tuple override defaults.\n const allEntries: PermissionEntry[] = [...defaultEntries, ...explicitEntries];\n\n const resources: ResourceCapability[] = allEntries.map((entry) =>\n resolveEntry(entry, prefix, expiryMs)\n );\n\n const additionalDelegates: ResolvedDelegate[] = (\n manifest.delegations ?? []\n ).map((d) => ({\n did: d.to,\n name: d.name,\n expiryMs: parseExpiry(d.expiry ?? manifest.expiry ?? DEFAULT_EXPIRY),\n permissions: d.permissions.map((entry) =>\n resolveEntry(\n entry,\n prefix,\n parseExpiry(d.expiry ?? manifest.expiry ?? DEFAULT_EXPIRY)\n )\n ),\n }));\n\n return {\n id: manifest.id,\n resources,\n expiryMs,\n includePublicSpace,\n additionalDelegates,\n };\n}\n\n/**\n * Expand a single permission entry into a {@link ResourceCapability}:\n * apply the prefix to the path and expand short actions into full URNs.\n */\nfunction resolveEntry(\n entry: PermissionEntry,\n prefix: string,\n _inheritedExpiryMs: number\n): ResourceCapability {\n const resolvedPath = applyPrefix(\n prefix,\n entry.path,\n entry.skipPrefix === true\n );\n const resolvedActions = expandActionShortNames(entry.service, entry.actions);\n const entryExpiryMs =\n entry.expiry !== undefined ? parseExpiry(entry.expiry) : undefined;\n return {\n service: entry.service,\n space: entry.space,\n path: resolvedPath,\n actions: resolvedActions,\n // Only populate `expiryMs` when the entry had its own expiry override.\n // When absent, callers use the parent (delegation or manifest) expiry\n // which is carried on ResolvedDelegate.expiryMs / ResolvedCapabilities.expiryMs.\n ...(entryExpiryMs !== undefined ? { expiryMs: entryExpiryMs } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Abilities map construction (bridge to WASM prepareSession / createDelegation)\n// ---------------------------------------------------------------------------\n\n/**\n * The shape `prepareSession` and the multi-resource `createDelegation` WASM\n * export both accept:\n *\n * ```\n * { [shortService]: { [path]: [fullUrnAction, ...] } }\n * ```\n *\n * - `shortService` is the recap-level service segment (`\"kv\"`, `\"sql\"`,\n * `\"duckdb\"`, `\"capabilities\"`, `\"hooks\"`) — not the manifest long form.\n * - `path` is the fully-resolved path (prefix already applied). An empty\n * string means \"no path segment\" on the resource URI.\n * - Action strings are full URNs like `\"tinycloud.kv/get\"`.\n *\n * This is a single source of truth for both the session's own recap (at\n * sign-in) and the delegations it can derive (post sign-in). We re-use it\n * for both so one manifest drives both sides.\n */\nexport type AbilitiesMap = Record<string, Record<string, string[]>>;\n\n/**\n * Convert a list of {@link ResourceCapability} entries (manifest\n * long-form service, full-URN actions) into the {@link AbilitiesMap}\n * shape the WASM layer expects.\n *\n * When multiple entries target the same `(service, path)` pair, their\n * action lists are merged and deduped. Entries whose service has no\n * short-form mapping in {@link SERVICE_LONG_TO_SHORT} are rejected with\n * a {@link ManifestValidationError} — the SDK does not silently drop\n * unknown services because the recap encoding would lose them.\n *\n * Paths are kept verbatim: this function does NOT collapse\n * `\"com.listen.app/\"` and `\"com.listen.app\"` or reinterpret empty /\n * slash strings. Callers that care about path canonicalization should\n * normalize before calling.\n */\nexport function resourceCapabilitiesToAbilitiesMap(\n resources: readonly ResourceCapability[]\n): AbilitiesMap {\n const out: AbilitiesMap = {};\n for (const r of resources) {\n const shortService = SERVICE_LONG_TO_SHORT[r.service];\n if (shortService === undefined) {\n throw new ManifestValidationError(\n `unknown service '${r.service}' — no short-form mapping. Known services: ${Object.keys(SERVICE_LONG_TO_SHORT).join(\", \")}`\n );\n }\n if (out[shortService] === undefined) {\n out[shortService] = {};\n }\n const pathsMap = out[shortService];\n const existing = pathsMap[r.path];\n if (existing === undefined) {\n // Copy so downstream mutation can't leak back into the input.\n pathsMap[r.path] = [...r.actions];\n } else {\n // Merge + dedupe while preserving first-seen order.\n const seen = new Set(existing);\n for (const action of r.actions) {\n if (!seen.has(action)) {\n existing.push(action);\n seen.add(action);\n }\n }\n }\n }\n return out;\n}\n\n/**\n * Build the {@link AbilitiesMap} that a session should be signed with,\n * given a {@link ResolvedCapabilities} (i.e. the output of\n * {@link resolveManifest}).\n *\n * The resulting map is the **union** of:\n * 1. the app's own resources (`resolved.resources`), and\n * 2. every permission declared in every `additionalDelegates[*]` entry.\n *\n * The union is what makes the manifest's delegations ergonomic: at\n * sign-in, the session key acquires recap coverage for both the app's\n * runtime needs and every downstream delegation target. Post sign-in,\n * `delegateTo(backendDID, backendPermissions)` can then issue the\n * sub-delegation via the session key (no wallet prompt) because the\n * caps are already part of the granted set.\n *\n * Duplicate `(service, path, action)` triples across resources and\n * delegations are merged and deduped — the session SIWE doesn't need\n * them repeated.\n */\nexport function manifestAbilitiesUnion(\n resolved: ResolvedCapabilities\n): AbilitiesMap {\n const all: ResourceCapability[] = [...resolved.resources];\n for (const delegate of resolved.additionalDelegates) {\n for (const perm of delegate.permissions) {\n all.push(perm);\n }\n }\n return resourceCapabilitiesToAbilitiesMap(all);\n}\n","/**\n * SharingService - v2 sharing link service with embedded private keys.\n *\n * This service implements the v2 sharing specification, which embeds private keys\n * directly in sharing links. This allows recipients to exercise delegations\n * without requiring prior session setup.\n *\n * Key differences from v1 SharingLinks:\n * - Private keys are embedded in the link (not just tokens)\n * - Recipients can optionally sub-delegate to their own session key\n * - Pre-configured KV service returned for immediate use\n *\n * @packageDocumentation\n */\n\nimport type {\n IKVService,\n ServiceSession,\n InvokeFunction,\n FetchFunction,\n} from \"@tinycloud/sdk-services\";\nimport type {\n Result,\n DelegationError,\n Delegation,\n KeyInfo,\n KeyProvider,\n GenerateShareParams,\n ShareLink,\n ShareLinkData,\n ShareSchema,\n JWK,\n IngestOptions,\n CreateDelegationParams,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n} from \"./types\";\nimport { DelegationErrorCodes } from \"./types\";\nimport type { DelegationManager } from \"./DelegationManager\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry\";\nimport { validateEncodedShareData } from \"./SharingService.schema.js\";\nimport { SERVICE_LONG_TO_SHORT } from \"../manifest\";\n\n// ---------------------------------------------------------------------------\n// Local helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Infer the short-form service name (`\"kv\"`, `\"sql\"`, etc) that all of the\n * given full-URN action strings belong to.\n *\n * SharingService issues single-service delegations (KV-only, SQL-only, …) —\n * the multi-resource WASM `createDelegation` call requires the service\n * segment explicitly because it's keyed separately from the action list.\n * This helper extracts the namespace half (`\"tinycloud.kv\"`) from each URN,\n * maps it to the short form via {@link SERVICE_LONG_TO_SHORT}, and returns\n * `undefined` if the actions are not all from the same known service.\n *\n * Returning `undefined` is intentional: the caller must surface a clear\n * error rather than guessing.\n */\nfunction inferShortServiceFromActionUrns(\n actions: readonly string[]\n): string | undefined {\n let short: string | undefined;\n for (const action of actions) {\n const slash = action.indexOf(\"/\");\n if (slash === -1) return undefined;\n const longService = action.slice(0, slash);\n const candidate = SERVICE_LONG_TO_SHORT[longService];\n if (candidate === undefined) return undefined;\n if (short === undefined) {\n short = candidate;\n } else if (short !== candidate) {\n return undefined;\n }\n }\n return short;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default actions for read-only sharing links.\n */\nconst DEFAULT_READ_ACTIONS = [\"tinycloud.kv/get\", \"tinycloud.kv/metadata\"];\n\n/**\n * Default expiry for sharing links (24 hours).\n */\nconst DEFAULT_EXPIRY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Prefix for the base64 schema.\n */\nconst BASE64_PREFIX = \"tc1:\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Creates a DelegationError with the given parameters.\n */\nfunction createError(\n code: string,\n message: string,\n cause?: Error,\n meta?: Record<string, unknown>\n): DelegationError {\n return {\n code,\n message,\n service: \"delegation\",\n cause,\n meta,\n };\n}\n\n/**\n * Base64 encode for URLs (URL-safe base64).\n */\nfunction base64UrlEncode(data: string): string {\n // Use btoa for browser, Buffer for Node.js\n let base64: string;\n if (typeof btoa !== \"undefined\") {\n base64 = btoa(unescape(encodeURIComponent(data)));\n } else if (typeof Buffer !== \"undefined\") {\n base64 = Buffer.from(data, \"utf-8\").toString(\"base64\");\n } else {\n throw new Error(\"No base64 encoding available\");\n }\n // Make URL-safe\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * Base64 decode for URLs (URL-safe base64).\n */\nfunction base64UrlDecode(encoded: string): string {\n // Restore standard base64\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n // Decode\n if (typeof atob !== \"undefined\") {\n return decodeURIComponent(escape(atob(base64)));\n } else if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\").toString(\"utf-8\");\n } else {\n throw new Error(\"No base64 decoding available\");\n }\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Data encoded in a sharing link.\n */\nexport interface EncodedShareData {\n /** Private key in JWK format (includes d parameter) */\n key: JWK;\n /** DID of the key */\n keyDid: string;\n /** The delegation granting access */\n delegation: Delegation;\n /** Resource path this link grants access to */\n path: string;\n /** TinyCloud host URL */\n host: string;\n /** Space ID */\n spaceId: string;\n /** Schema version */\n version: 1;\n}\n\n/**\n * Options for receiving a sharing link.\n */\nexport interface ReceiveOptions {\n /**\n * Whether to automatically create a sub-delegation to the current session key.\n * Default: true\n */\n autoSubdelegate?: boolean;\n /**\n * Whether to use the current session key for operations (requires autoSubdelegate).\n * Default: true\n */\n useSessionKey?: boolean;\n /**\n * Ingestion options passed to CapabilityKeyRegistry.\n */\n ingestOptions?: IngestOptions;\n}\n\n/**\n * Result of receiving a sharing link.\n */\nexport interface ShareAccess {\n /** The delegation that was received/created */\n delegation: Delegation;\n /** Key info for the received key */\n key: KeyInfo;\n /** Pre-configured KV service for the shared path */\n kv: IKVService;\n /** The space ID */\n spaceId: string;\n /** The path prefix for this share */\n path: string;\n}\n\n/**\n * Configuration for SharingService.\n */\nexport interface SharingServiceConfig {\n /** TinyCloud host URLs */\n hosts: string[];\n /**\n * Active session for authentication.\n * Required for generate(), optional for receive().\n */\n session?: ServiceSession;\n /** Platform-specific invoke function */\n invoke: InvokeFunction;\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n /** Key provider for cryptographic operations */\n keyProvider: KeyProvider;\n /** Capability key registry for key/delegation management */\n registry: ICapabilityKeyRegistry;\n /**\n * Delegation manager for creating delegations (used if createDelegation not provided).\n * Required for generate(), optional for receive().\n */\n delegationManager?: DelegationManager;\n /** Factory for creating KV service instances */\n createKVService: (config: {\n hosts: string[];\n session: ServiceSession;\n invoke: InvokeFunction;\n fetch?: FetchFunction;\n pathPrefix?: string;\n }) => IKVService;\n /** Base URL for sharing links (e.g., \"https://share.myapp.com\") */\n baseUrl?: string;\n /**\n * Custom delegation creation function. When provided, this is used instead\n * of delegationManager.create(). This allows platforms to use their own\n * delegation creation logic (e.g., SIWE-based /delegate endpoint).\n */\n createDelegation?: (params: CreateDelegationParams) => Promise<Result<Delegation, DelegationError>>;\n /**\n * WASM function for client-side delegation creation.\n * When provided, this is preferred over server-side creation (createDelegation/delegationManager).\n * Creates UCAN delegations directly without requiring server roundtrip.\n */\n createDelegationWasm?: (params: CreateDelegationWasmParams) => CreateDelegationWasmResult;\n /**\n * Path prefix for KV operations.\n * When set, paths passed to generate() are prefixed with this value.\n * This ensures the share path matches the session's authorized paths.\n */\n pathPrefix?: string;\n /**\n * Session expiry time.\n * When set, sharing link expiry is clamped to not exceed this value\n * unless onRootDelegationNeeded is provided and returns a new delegation.\n */\n sessionExpiry?: Date;\n /**\n * Callback to create a DIRECT delegation from the root (wallet) to a share key.\n * This bypasses the session delegation chain, allowing share links with\n * expiry longer than the current session.\n *\n * When provided and share expiry > session expiry:\n * 1. SharingService creates the ephemeral share key\n * 2. This callback is invoked with the share key DID\n * 3. The callback signs a direct PKH -> share key delegation with the wallet\n * 4. The returned delegation is used for the share link\n *\n * This is the CORRECT solution for long-lived share links because:\n * - It creates a fresh delegation chain: PKH -> share key\n * - Not constrained by session expiry (no sub-delegation from session key)\n *\n * @param params - Parameters for creating the root delegation\n * @returns The delegation from wallet to share key, or undefined to fall back to session extension\n */\n onRootDelegationNeeded?: (params: {\n /** DID of the share key to delegate to */\n shareKeyDID: string;\n /** Space ID */\n spaceId: string;\n /** Path to grant access to */\n path: string;\n /** Actions to grant */\n actions: string[];\n /** Requested expiry time */\n requestedExpiry: Date;\n }) => Promise<Delegation | undefined>;\n}\n\n/**\n * Interface for the SharingService.\n */\nexport interface ISharingService {\n /**\n * Generate a sharing link with an embedded private key.\n *\n * This creates a new session key, delegates to it, and encodes\n * the key and delegation into a shareable link.\n */\n generate(params: GenerateShareParams): Promise<Result<ShareLink, DelegationError>>;\n\n /**\n * Receive and activate a sharing link.\n *\n * Decodes the link, ingests the key into the registry, and optionally\n * creates a sub-delegation to the current session key.\n */\n receive(link: string, options?: ReceiveOptions): Promise<Result<ShareAccess, DelegationError>>;\n\n /**\n * Encode sharing data into a link string.\n */\n encodeLink(data: EncodedShareData, schema?: ShareSchema): string;\n\n /**\n * Decode a link string into sharing data.\n */\n decodeLink(link: string): EncodedShareData;\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * SharingService - v2 sharing link service with embedded private keys.\n *\n * @example\n * ```typescript\n * import { SharingService } from \"@tinycloud/sdk-core/delegations\";\n *\n * const sharing = new SharingService({\n * hosts: [\"https://node.tinycloud.xyz\"],\n * session,\n * invoke,\n * keyProvider,\n * registry,\n * delegationManager,\n * createKVService,\n * baseUrl: \"https://share.myapp.com\"\n * });\n *\n * // Generate a sharing link\n * const result = await sharing.generate({\n * path: \"/kv/documents/report.pdf\",\n * actions: [\"tinycloud.kv/get\"],\n * expiry: new Date(\"2024-12-31\")\n * });\n *\n * if (result.ok) {\n * console.log(\"Share this URL:\", result.data.url);\n * }\n *\n * // Receive a sharing link\n * const receiveResult = await sharing.receive(shareUrl);\n * if (receiveResult.ok) {\n * // Use the pre-configured KV service\n * const data = await receiveResult.data.kv.get(\"report.pdf\");\n * }\n * ```\n */\nexport class SharingService implements ISharingService {\n private hosts: string[];\n private session?: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n private keyProvider: KeyProvider;\n private registry: ICapabilityKeyRegistry;\n private delegationManager?: DelegationManager;\n private createKVService: SharingServiceConfig[\"createKVService\"];\n private baseUrl: string;\n private createDelegationFn?: SharingServiceConfig[\"createDelegation\"];\n private createDelegationWasmFn?: SharingServiceConfig[\"createDelegationWasm\"];\n private pathPrefix: string;\n private sessionExpiry?: Date;\n private onRootDelegationNeeded?: SharingServiceConfig[\"onRootDelegationNeeded\"];\n\n /**\n * Creates a new SharingService instance.\n */\n constructor(config: SharingServiceConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.keyProvider = config.keyProvider;\n this.registry = config.registry;\n this.delegationManager = config.delegationManager;\n this.createKVService = config.createKVService;\n this.baseUrl = (config.baseUrl ?? \"\").replace(/\\/$/, \"\"); // Remove trailing slash\n this.createDelegationFn = config.createDelegation;\n this.createDelegationWasmFn = config.createDelegationWasm;\n this.pathPrefix = config.pathPrefix ?? \"\";\n this.sessionExpiry = config.sessionExpiry;\n this.onRootDelegationNeeded = config.onRootDelegationNeeded;\n }\n\n /**\n * Gets the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Updates the session (e.g., after re-authentication).\n */\n public updateSession(session: ServiceSession): void {\n this.session = session;\n }\n\n /**\n * Updates the service configuration.\n * Used to add full capabilities (session, delegationManager, createDelegation, createDelegationWasm) after signIn.\n */\n public updateConfig(config: Partial<Pick<SharingServiceConfig, \"session\" | \"delegationManager\" | \"createDelegation\" | \"createDelegationWasm\" | \"sessionExpiry\" | \"onRootDelegationNeeded\">>): void {\n if (config.session !== undefined) {\n this.session = config.session;\n }\n if (config.delegationManager !== undefined) {\n this.delegationManager = config.delegationManager;\n }\n if (config.createDelegation !== undefined) {\n this.createDelegationFn = config.createDelegation;\n }\n if (config.createDelegationWasm !== undefined) {\n this.createDelegationWasmFn = config.createDelegationWasm;\n }\n if (config.sessionExpiry !== undefined) {\n this.sessionExpiry = config.sessionExpiry;\n }\n if (config.onRootDelegationNeeded !== undefined) {\n this.onRootDelegationNeeded = config.onRootDelegationNeeded;\n }\n }\n\n /**\n * Generate a sharing link with an embedded private key.\n *\n * Flow:\n * 1. Spawn new session key (unique per share)\n * 2. Create delegation from current session to spawned key\n * 3. Package: { key (with private!), delegation, path, host }\n * 4. Encode based on schema (base64 for now)\n * 5. Return link string\n */\n async generate(params: GenerateShareParams): Promise<Result<ShareLink, DelegationError>> {\n // Require session for generating (not for receiving)\n if (!this.session) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"Session required for generating sharing links. Call signIn() first.\"\n ),\n };\n }\n\n // Require delegation capability\n if (!this.createDelegationWasmFn && !this.createDelegationFn && !this.delegationManager) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"DelegationManager, createDelegation, or createDelegationWasm function required for generating sharing links.\"\n ),\n };\n }\n\n // Validate path\n if (!params.path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n const actions = params.actions ?? DEFAULT_READ_ACTIONS;\n const requestedExpiry = params.expiry ?? new Date(Date.now() + DEFAULT_EXPIRY_MS);\n let expiry = requestedExpiry;\n\n const schema: ShareSchema = params.schema ?? \"base64\";\n\n // Build full path with prefix (matches how KVService stores data)\n // If pathPrefix is \"demo-app\" and path is \"hello\", fullPath is \"demo-app/hello\"\n const fullPath = this.pathPrefix\n ? `${this.pathPrefix}/${params.path}`.replace(/\\/+/g, \"/\") // Normalize slashes\n : params.path;\n\n // Only base64 schema is implemented in v1\n if (schema !== \"base64\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n `Schema '${schema}' not implemented. Only 'base64' is supported.`\n ),\n };\n }\n\n // Step 1: Spawn a new session key unique to this share\n // We create this FIRST so we can pass its DID to onRootDelegationNeeded if needed\n let keyId: string;\n let keyDid: string;\n let keyJwk: JWK;\n\n try {\n const shareKeyName = `share:${Date.now()}:${Math.random().toString(36).substring(2, 10)}`;\n keyId = await this.keyProvider.createSessionKey(shareKeyName);\n keyDid = await this.keyProvider.getDID(keyId);\n keyJwk = this.keyProvider.getJWK(keyId) as JWK;\n\n // Ensure the private key is included\n if (!keyJwk.d) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n \"KeyProvider did not return private key (d parameter) in JWK\"\n ),\n };\n }\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to generate session key for share: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n // Step 2: Check if any existing key can satisfy this delegation\n // Only prompt for root delegation if NO existing key in the registry can handle it\n let delegation: Delegation;\n // Strip fragment from DID URL to get plain DID for UCAN audience\n // getDID() returns \"did:key:z6Mk...#z6Mk...\" but audience needs \"did:key:z6Mk...\"\n const plainDID = keyDid.split('#')[0];\n\n // Helper to handle delegation result (returns early on error)\n const handleDelegationResult = (\n result: Awaited<ReturnType<typeof this.createSessionDelegation>>\n ): Delegation | { ok: false; error: DelegationError } => {\n if (result && typeof result === 'object' && 'ok' in result) {\n return result as { ok: false; error: DelegationError };\n }\n return result as Delegation;\n };\n\n // Check if any key in the registry can satisfy this delegation request\n // A key can satisfy the request if it has a delegation that:\n // 1. Covers the required path and actions\n // 2. Has sufficient expiry (delegation.expiry >= requestedExpiry)\n // 3. Allows sub-delegation\n const canSatisfyFromRegistry = this.findSuitableKeyForDelegation(\n fullPath,\n actions,\n requestedExpiry\n );\n\n if (canSatisfyFromRegistry) {\n // An existing key can satisfy this request - use session delegation (no prompt)\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n } else if (this.onRootDelegationNeeded) {\n // No existing key can satisfy the request - try root delegation\n try {\n const rootDelegation = await this.onRootDelegationNeeded({\n shareKeyDID: plainDID,\n spaceId: this.session.spaceId,\n path: fullPath,\n actions,\n requestedExpiry,\n });\n\n if (rootDelegation) {\n delegation = rootDelegation;\n expiry = requestedExpiry;\n } else {\n // Root delegation declined, clamp to session expiry\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n } catch (err) {\n // Root delegation failed, clamp to session expiry\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n } else {\n // No root delegation callback, clamp to what session can provide\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n\n // Step 3: Package the share data\n const shareData: EncodedShareData = {\n key: keyJwk,\n keyDid,\n delegation,\n path: fullPath,\n host: this.host,\n spaceId: this.session.spaceId,\n version: 1,\n };\n\n // Step 4: Encode the link\n const encodedData = this.encodeLink(shareData, schema);\n\n // Step 5: Build the full URL\n const baseUrl = params.baseUrl ?? this.baseUrl;\n const url = baseUrl ? `${baseUrl}/share/${encodedData}` : encodedData;\n\n const shareLink: ShareLink = {\n token: encodedData,\n url,\n delegation,\n schema,\n expiresAt: expiry,\n description: params.description,\n };\n\n return { ok: true, data: shareLink };\n }\n\n /**\n * Check if any key in the registry can satisfy the delegation request.\n * A key can satisfy if it has a delegation that:\n * 1. Covers the required path (exact match or parent path)\n * 2. Has all required actions\n * 3. Has sufficient expiry (delegation.expiry >= requestedExpiry)\n * 4. Allows sub-delegation\n * @internal\n */\n private findSuitableKeyForDelegation(\n path: string,\n actions: string[],\n requestedExpiry: Date\n ): boolean {\n // Check session expiry first (most common case)\n if (this.sessionExpiry && requestedExpiry <= this.sessionExpiry) {\n return true;\n }\n\n // Check registry for keys with sufficient capabilities\n const allKeys = this.registry.getAllKeys();\n for (const key of allKeys) {\n const delegations = this.registry.getDelegationsForKey(key.id);\n for (const delegation of delegations) {\n // Check if delegation is valid and not expired\n if (!this.registry.isDelegationValid(delegation)) {\n continue;\n }\n\n // Check if delegation has sufficient expiry\n if (delegation.expiry < requestedExpiry) {\n continue;\n }\n\n // Check if delegation allows sub-delegation\n if (delegation.allowSubDelegation === false) {\n continue;\n }\n\n // Check if delegation covers the path (exact match or parent path)\n const delegationPath = delegation.path || '';\n if (!this.pathMatches(delegationPath, path)) {\n continue;\n }\n\n // Check if delegation has all required actions\n const delegationActions = delegation.actions || [];\n const hasAllActions = actions.every(action =>\n delegationActions.includes(action) || delegationActions.includes('*')\n );\n if (!hasAllActions) {\n continue;\n }\n\n // Found a suitable key\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a delegation path matches/covers the requested path.\n * A delegation path covers the request if:\n * - It's an exact match\n * - It's a parent path (e.g., delegation for \"\" covers \"foo/bar\")\n * - It uses wildcards that match\n * @internal\n */\n private pathMatches(delegationPath: string, requestedPath: string): boolean {\n // Empty delegation path covers everything\n if (delegationPath === '' || delegationPath === '*') {\n return true;\n }\n\n // Exact match\n if (delegationPath === requestedPath) {\n return true;\n }\n\n // Check if delegation path is a parent of requested path\n const normalizedDelegation = delegationPath.replace(/\\/$/, '');\n const normalizedRequest = requestedPath.replace(/\\/$/, '');\n\n if (normalizedRequest.startsWith(normalizedDelegation + '/')) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Handle fallback to session extension when root delegation is not available.\n * @internal\n */\n private async handleSessionExtensionFallback(requestedExpiry: Date): Promise<{ expiry: Date }> {\n // Clamp to current session expiry\n return { expiry: this.sessionExpiry ?? requestedExpiry };\n }\n\n /**\n * Create a delegation from the current session to a share key.\n * This is the fallback path when root delegation is not available.\n * @internal\n */\n private async createSessionDelegation(\n delegateDID: string,\n path: string,\n actions: string[],\n expiry: Date\n ): Promise<Delegation | Result<never, DelegationError>> {\n if (!this.session) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"Session required for creating delegation\"\n ),\n };\n }\n\n if (this.createDelegationWasmFn) {\n // Client-side delegation creation via WASM.\n //\n // SharingService always issues single-resource delegations (one\n // path, one action list). The multi-resource WASM API takes an\n // `abilities` map shaped `Record<shortService, Record<path,\n // actions[]>>`, so we infer the short service from the first\n // action URN (every action in a share call shares the same\n // service namespace by construction — KV-only, SQL-only, etc).\n //\n // The result comes back with a `resources` array; for a\n // single-entry call it always has exactly one entry, and we\n // mirror that entry's `path` + `actions` back into the flat\n // Delegation shape that the rest of SharingService works with.\n try {\n if (actions.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.VALIDATION_ERROR,\n \"createDelegation requires at least one action\"\n ),\n };\n }\n const shortService = inferShortServiceFromActionUrns(actions);\n if (shortService === undefined) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.VALIDATION_ERROR,\n `createDelegation: cannot infer service from actions ${JSON.stringify(actions)} — expected full URNs like \"tinycloud.kv/get\"`\n ),\n };\n }\n\n const wasmResult = this.createDelegationWasmFn({\n session: this.session,\n delegateDID,\n spaceId: this.session.spaceId,\n abilities: {\n [shortService]: {\n [path]: [...actions],\n },\n },\n expirationSecs: Math.floor(expiry.getTime() / 1000),\n });\n\n // Register the delegation with the server\n const registerRes = await this.fetchFn(`${this.host}/delegate`, {\n method: \"POST\",\n headers: {\n Authorization: wasmResult.delegation,\n },\n });\n\n if (!registerRes.ok) {\n const errorText = await registerRes.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to register delegation with server: ${registerRes.status} ${errorText}`\n ),\n };\n }\n\n // Single-entry call → resources[0] is authoritative for the\n // flat Delegation shape. We assert length here because a\n // zero-length result would mean the Rust side dropped our\n // single input — that's a protocol bug, not a runtime\n // condition to silently coerce.\n if (wasmResult.resources.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n \"createDelegation WASM returned empty resources array for a single-entry request\"\n ),\n };\n }\n const primary = wasmResult.resources[0];\n return {\n cid: wasmResult.cid,\n delegateDID: wasmResult.delegateDID,\n spaceId: this.session.spaceId,\n path: primary.path,\n actions: primary.actions,\n expiry: wasmResult.expiry,\n isRevoked: false,\n authHeader: wasmResult.delegation,\n allowSubDelegation: true,\n createdAt: new Date(),\n };\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation via WASM: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n } else {\n // Server-side delegation creation (fallback)\n const delegationParams: CreateDelegationParams = {\n delegateDID,\n path,\n actions,\n expiry,\n disableSubDelegation: false,\n };\n\n const delegationResult = this.createDelegationFn\n ? await this.createDelegationFn(delegationParams)\n : await this.delegationManager!.create(delegationParams);\n\n if (!delegationResult.ok) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation for share: ${delegationResult.error.message}`,\n delegationResult.error.cause,\n delegationResult.error.meta\n ),\n };\n }\n\n return delegationResult.data;\n }\n }\n\n /**\n * Receive and activate a sharing link.\n *\n * Flow:\n * 1. Decode link -> extract { key, delegation, path, host }\n * 2. Ingest key into CapabilityKeyRegistry\n * 3. If autoSubdelegate (default true) + useSessionKey:\n * - Create sub-delegation from ingested key -> current session\n * - Register sub-delegation capabilities\n * 4. Return ShareAccess with pre-configured KV service\n */\n async receive(\n link: string,\n options: ReceiveOptions = {}\n ): Promise<Result<ShareAccess, DelegationError>> {\n const {\n autoSubdelegate = true,\n useSessionKey = true,\n ingestOptions,\n } = options;\n\n // Step 1: Decode and validate the link\n const decodeResult = this.decodeLinkWithValidation(link);\n if (!decodeResult.ok) {\n return decodeResult;\n }\n const shareData = decodeResult.data;\n\n // Schema validation ensures key.d and delegation exist, but we need\n // to check business rules (expiry, revocation) separately\n\n // Check delegation expiry\n const delegationExpiry = new Date(shareData.delegation.expiry);\n if (delegationExpiry < new Date()) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.AUTH_EXPIRED,\n \"Sharing link has expired\"\n ),\n };\n }\n\n // Check delegation revocation\n if (shareData.delegation.isRevoked) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.REVOKED,\n \"Sharing link has been revoked\"\n ),\n };\n }\n\n // Step 2: Create KeyInfo and ingest into registry\n const keyInfo: KeyInfo = {\n id: `ingested:${shareData.keyDid}`,\n did: shareData.keyDid,\n type: \"ingested\",\n jwk: shareData.key,\n priority: 2, // Ingested keys have lowest priority\n };\n\n this.registry.ingestKey(keyInfo, shareData.delegation, ingestOptions);\n\n // The delegation and key to use for operations\n let activeDelegation = shareData.delegation;\n let activeKey = keyInfo;\n\n // Step 3: Auto-subdelegate if requested\n if (autoSubdelegate && useSessionKey && this.session) {\n try {\n // Get current session key DID\n // Note: We need to create a sub-delegation from the ingested key to the session key\n // This requires the session key DID, which should be available from the session\n\n // For now, we'll register the ingested key's capabilities directly\n // The auto-subdelegation would require additional infrastructure to sign with the ingested key\n // This is a simplification - full implementation would sign a new delegation with the ingested key\n\n // TODO: Implement full auto-subdelegation when signing infrastructure is available\n // For now, the ingested key can be used directly via the registry\n\n } catch (err) {\n // Log but don't fail - can still use the ingested key directly\n console.warn(\"Auto-subdelegation failed, using ingested key directly:\", err);\n }\n }\n\n // Step 4: Create pre-configured KV service for the shared path\n // Construct session from share data - no need for existing session\n // Use the authHeader if available, otherwise fall back to constructing from CID\n const authHeader = shareData.delegation.authHeader ?? `Bearer ${shareData.delegation.cid}`;\n const shareSession: ServiceSession = {\n delegationHeader: { Authorization: authHeader },\n delegationCid: shareData.delegation.cid,\n spaceId: shareData.spaceId,\n verificationMethod: shareData.keyDid,\n jwk: shareData.key,\n };\n\n const kvService = this.createKVService({\n hosts: [shareData.host],\n session: shareSession,\n invoke: this.invoke,\n fetch: this.fetchFn,\n pathPrefix: shareData.path,\n });\n\n const shareAccess: ShareAccess = {\n delegation: activeDelegation,\n key: activeKey,\n kv: kvService,\n spaceId: shareData.spaceId,\n path: shareData.path,\n };\n\n return { ok: true, data: shareAccess };\n }\n\n /**\n * Encode sharing data into a link string.\n *\n * @param data - The share data to encode\n * @param schema - The encoding schema (default: \"base64\")\n * @returns Encoded link string\n */\n encodeLink(data: EncodedShareData, schema: ShareSchema = \"base64\"): string {\n if (schema !== \"base64\") {\n throw new Error(`Schema '${schema}' not implemented. Only 'base64' is supported.`);\n }\n\n const jsonString = JSON.stringify(data);\n const encoded = base64UrlEncode(jsonString);\n return `${BASE64_PREFIX}${encoded}`;\n }\n\n /**\n * Decode a link string into sharing data.\n *\n * @param link - The encoded link string (may include URL prefix)\n * @returns Decoded share data\n * @throws Error if link format is invalid or data fails validation\n */\n decodeLink(link: string): EncodedShareData {\n const result = this.decodeLinkWithValidation(link);\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return result.data;\n }\n\n /**\n * Decode and validate a link string into sharing data.\n *\n * Internal method that returns a Result instead of throwing.\n * Used by receive() for proper error handling.\n *\n * @param link - The encoded link string (may include URL prefix)\n * @returns Result with decoded share data or validation error\n */\n private decodeLinkWithValidation(link: string): Result<EncodedShareData, DelegationError> {\n // Extract the encoded data from the link\n let encoded = link;\n\n // Handle full URL format: https://share.example.com/share/tc1:...\n if (link.includes(\"/share/\")) {\n const parts = link.split(\"/share/\");\n encoded = parts[parts.length - 1];\n }\n\n // Handle query parameter format: ?share=tc1:...\n if (link.includes(\"?share=\")) {\n try {\n const url = new URL(link);\n encoded = url.searchParams.get(\"share\") ?? encoded;\n } catch {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n \"Invalid URL format in sharing link\"\n ),\n };\n }\n }\n\n // Remove the schema prefix\n if (!encoded.startsWith(BASE64_PREFIX)) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Invalid sharing link format. Expected prefix '${BASE64_PREFIX}'`\n ),\n };\n }\n\n const base64Data = encoded.slice(BASE64_PREFIX.length);\n\n let jsonString: string;\n try {\n jsonString = base64UrlDecode(base64Data);\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Failed to decode base64 data: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonString);\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Failed to parse share data JSON: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n // Convert delegation expiry to Date before validation if it's a string\n // This is needed because JSON.parse doesn't restore Date objects\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"delegation\" in parsed &&\n parsed.delegation &&\n typeof parsed.delegation === \"object\" &&\n \"expiry\" in parsed.delegation &&\n typeof parsed.delegation.expiry === \"string\"\n ) {\n (parsed.delegation as { expiry: Date }).expiry = new Date(parsed.delegation.expiry);\n }\n\n // Validate against schema\n const validationResult = validateEncodedShareData(parsed);\n if (!validationResult.ok) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n validationResult.error.message,\n undefined,\n validationResult.error.meta\n ),\n };\n }\n\n return { ok: true, data: validationResult.data };\n }\n}\n\n/**\n * Create a new SharingService instance.\n */\nexport function createSharingService(config: SharingServiceConfig): ISharingService {\n return new SharingService(config);\n}\n","/**\n * CapabilityKeyRegistry - Tracks keys and their capabilities for automatic key selection.\n *\n * The registry maintains mappings between:\n * - Keys and their associated delegations\n * - Capabilities (resource/action pairs) and the keys that can exercise them\n *\n * This enables automatic key selection when performing operations, choosing\n * the most appropriate key based on priority and validity.\n *\n * @packageDocumentation\n */\n\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport { ok, err, serviceError } from \"@tinycloud/sdk-services\";\nimport type {\n KeyInfo,\n CapabilityEntry,\n Delegation,\n IngestOptions,\n} from \"../delegations/types\";\n\n// =============================================================================\n// Service Name\n// =============================================================================\n\nconst SERVICE_NAME = \"capability-key-registry\";\n\n// =============================================================================\n// Error Codes\n// =============================================================================\n\n/**\n * Error codes specific to CapabilityKeyRegistry operations.\n */\nexport const CapabilityKeyRegistryErrorCodes = {\n /** Key not found in registry */\n KEY_NOT_FOUND: \"KEY_NOT_FOUND\",\n /** No key available for the requested capability */\n NO_CAPABLE_KEY: \"NO_CAPABLE_KEY\",\n /** Delegation has expired */\n DELEGATION_EXPIRED: \"DELEGATION_EXPIRED\",\n /** Delegation has been revoked */\n DELEGATION_REVOKED: \"DELEGATION_REVOKED\",\n /** Invalid delegation data */\n INVALID_DELEGATION: \"INVALID_DELEGATION\",\n /** Key already registered */\n KEY_EXISTS: \"KEY_EXISTS\",\n} as const;\n\nexport type CapabilityKeyRegistryErrorCode =\n (typeof CapabilityKeyRegistryErrorCodes)[keyof typeof CapabilityKeyRegistryErrorCodes];\n\n// =============================================================================\n// Storage Types\n// =============================================================================\n\n/**\n * Stored delegation with chain information.\n */\nexport interface StoredDelegationChain {\n /** The delegation itself */\n delegation: Delegation;\n /** Parent delegation CID if this is a sub-delegation */\n parentCid?: string;\n /** Key ID used to sign/exercise this delegation */\n keyId: string;\n /** When this was stored */\n storedAt: Date;\n}\n\n/**\n * Internal delegation store structure.\n */\ninterface DelegationStore {\n /** Delegations indexed by key ID */\n byKey: Map<string, Delegation[]>;\n /** Delegations indexed by CID */\n byCid: Map<string, StoredDelegationChain>;\n /** Capability entries indexed by \"resource|action\" key */\n byCapability: Map<string, CapabilityEntry[]>;\n}\n\n// =============================================================================\n// Interface\n// =============================================================================\n\n/**\n * Interface for the CapabilityKeyRegistry.\n *\n * Tracks keys and their capabilities for automatic key selection.\n */\nexport interface ICapabilityKeyRegistry {\n /**\n * Register a key with its associated delegations.\n *\n * @param key - Key information\n * @param delegations - Delegations granted to this key\n */\n registerKey(key: KeyInfo, delegations: Delegation[]): void;\n\n /**\n * Remove a key and all its associated delegations.\n *\n * @param keyId - The key ID to remove\n */\n removeKey(keyId: string): void;\n\n /**\n * Get a key that can exercise the specified capability.\n *\n * Uses the key selection algorithm:\n * 1. Filter keys that have the required capability\n * 2. Check delegation validity (not expired, not revoked)\n * 3. Sort by priority (session=0, main=1, ingested=2)\n * 4. Return highest priority valid key\n *\n * @param resource - Resource URI (e.g., \"tinycloud://space-id/kv/my-data\")\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @returns The best matching key, or null if none available\n */\n getKeyForCapability(resource: string, action: string): KeyInfo | null;\n\n /**\n * Get all registered capabilities.\n *\n * @returns All capability entries in the registry\n */\n getAllCapabilities(): CapabilityEntry[];\n\n /**\n * Get all delegations for a specific key.\n *\n * @param keyId - The key ID\n * @returns Array of delegations for this key\n */\n getDelegationsForKey(keyId: string): Delegation[];\n\n /**\n * Ingest a key and delegation from an external source (e.g., sharing link).\n *\n * @param key - Key information to ingest\n * @param delegation - Delegation to associate with the key\n * @param options - Ingestion options\n */\n ingestKey(\n key: KeyInfo,\n delegation: Delegation,\n options?: IngestOptions\n ): void;\n\n /**\n * Check if a delegation is currently valid.\n *\n * @param delegation - The delegation to check\n * @returns true if valid, false if expired or revoked\n */\n isDelegationValid(delegation: Delegation): boolean;\n\n /**\n * Get a key by its ID.\n *\n * @param keyId - The key ID\n * @returns The key info, or undefined if not found\n */\n getKey(keyId: string): KeyInfo | undefined;\n\n /**\n * Get all registered keys.\n *\n * @returns Array of all registered keys\n */\n getAllKeys(): KeyInfo[];\n\n /**\n * Clear all registered keys and delegations.\n */\n clear(): void;\n\n /**\n * Revoke a delegation by CID.\n *\n * @param cid - The delegation CID to revoke\n * @returns Result indicating success or failure\n */\n revokeDelegation(cid: string): Result<void, ServiceError>;\n\n /**\n * Find capabilities that match a resource path pattern.\n *\n * @param resourcePattern - Resource pattern (supports wildcards)\n * @param action - Optional action filter\n * @returns Matching capability entries\n */\n findCapabilities(\n resourcePattern: string,\n action?: string\n ): CapabilityEntry[];\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * CapabilityKeyRegistry - Tracks keys and their capabilities for automatic key selection.\n *\n * @example\n * ```typescript\n * const registry = new CapabilityKeyRegistry();\n *\n * // Register a session key with its delegations\n * registry.registerKey(sessionKey, [rootDelegation]);\n *\n * // Get the best key for an operation\n * const key = registry.getKeyForCapability(\n * \"tinycloud://my-space/kv/data\",\n * \"tinycloud.kv/get\"\n * );\n *\n * if (key) {\n * // Use this key for the operation\n * console.log(\"Using key:\", key.id);\n * }\n * ```\n */\nexport class CapabilityKeyRegistry implements ICapabilityKeyRegistry {\n /**\n * Registry of all keys indexed by ID.\n */\n private keys: Map<string, KeyInfo> = new Map();\n\n /**\n * Delegation storage.\n */\n private store: DelegationStore = {\n byKey: new Map(),\n byCid: new Map(),\n byCapability: new Map(),\n };\n\n // ===========================================================================\n // Key Management\n // ===========================================================================\n\n /**\n * Register a key with its associated delegations.\n *\n * @param key - Key information\n * @param delegations - Delegations granted to this key\n */\n registerKey(key: KeyInfo, delegations: Delegation[]): void {\n // Store the key\n this.keys.set(key.id, key);\n\n // Initialize delegation storage for this key\n if (!this.store.byKey.has(key.id)) {\n this.store.byKey.set(key.id, []);\n }\n\n // Process each delegation\n for (const delegation of delegations) {\n this.addDelegation(key, delegation);\n }\n }\n\n /**\n * Remove a key and all its associated delegations.\n *\n * @param keyId - The key ID to remove\n */\n removeKey(keyId: string): void {\n // Get delegations for this key\n const delegations = this.store.byKey.get(keyId) || [];\n\n // Remove from byCid\n for (const delegation of delegations) {\n this.store.byCid.delete(delegation.cid);\n }\n\n // Remove from byCapability\n for (const [capKey, entries] of this.store.byCapability) {\n const filtered = entries.filter(\n (entry) => !entry.keys.some((k: KeyInfo) => k.id === keyId)\n );\n if (filtered.length === 0) {\n this.store.byCapability.delete(capKey);\n } else {\n // Remove this key from entries that have multiple keys\n for (const entry of filtered) {\n entry.keys = entry.keys.filter((k: KeyInfo) => k.id !== keyId);\n }\n this.store.byCapability.set(capKey, filtered.filter((e) => e.keys.length > 0));\n }\n }\n\n // Remove from byKey\n this.store.byKey.delete(keyId);\n\n // Remove the key itself\n this.keys.delete(keyId);\n }\n\n // ===========================================================================\n // Capability Lookup\n // ===========================================================================\n\n /**\n * Get a key that can exercise the specified capability.\n *\n * Key selection algorithm:\n * 1. Filter keys that have the required capability\n * 2. Check delegation validity (not expired, not revoked)\n * 3. Sort by priority (session=0, main=1, ingested=2)\n * 4. Return highest priority valid key\n *\n * @param resource - Resource URI\n * @param action - Action to perform\n * @returns The best matching key, or null if none available\n */\n getKeyForCapability(resource: string, action: string): KeyInfo | null {\n // Find matching capabilities\n const matchingEntries = this.findMatchingEntries(resource, action);\n\n if (matchingEntries.length === 0) {\n return null;\n }\n\n // Collect all valid keys from matching entries\n const validKeys: KeyInfo[] = [];\n\n for (const entry of matchingEntries) {\n // Check if the delegation is valid\n if (!this.isDelegationValid(entry.delegation)) {\n continue;\n }\n\n // Add keys from this entry\n for (const key of entry.keys) {\n if (!validKeys.some((k: KeyInfo) => k.id === key.id)) {\n validKeys.push(key);\n }\n }\n }\n\n if (validKeys.length === 0) {\n return null;\n }\n\n // Sort by priority (lower is better)\n validKeys.sort((a: KeyInfo, b: KeyInfo) => a.priority - b.priority);\n\n return validKeys[0];\n }\n\n /**\n * Get all registered capabilities.\n *\n * @returns All capability entries in the registry\n */\n getAllCapabilities(): CapabilityEntry[] {\n const all: CapabilityEntry[] = [];\n for (const entries of this.store.byCapability.values()) {\n all.push(...entries);\n }\n return all;\n }\n\n // ===========================================================================\n // Delegation Tracking\n // ===========================================================================\n\n /**\n * Get all delegations for a specific key.\n *\n * @param keyId - The key ID\n * @returns Array of delegations for this key\n */\n getDelegationsForKey(keyId: string): Delegation[] {\n return this.store.byKey.get(keyId) || [];\n }\n\n // ===========================================================================\n // Ingestion\n // ===========================================================================\n\n /**\n * Ingest a key and delegation from an external source.\n *\n * @param key - Key information to ingest\n * @param delegation - Delegation to associate with the key\n * @param options - Ingestion options\n */\n ingestKey(\n key: KeyInfo,\n delegation: Delegation,\n options?: IngestOptions\n ): void {\n // Apply priority override if specified\n const keyToStore: KeyInfo = options?.priority !== undefined\n ? { ...key, priority: options.priority }\n : key;\n\n // Store the key\n this.keys.set(keyToStore.id, keyToStore);\n\n // Initialize delegation storage\n if (!this.store.byKey.has(keyToStore.id)) {\n this.store.byKey.set(keyToStore.id, []);\n }\n\n // Add the delegation\n this.addDelegation(keyToStore, delegation);\n }\n\n // ===========================================================================\n // Validation\n // ===========================================================================\n\n /**\n * Check if a delegation is currently valid.\n *\n * @param delegation - The delegation to check\n * @returns true if valid, false if expired or revoked\n */\n isDelegationValid(delegation: Delegation): boolean {\n // Check if revoked\n if (delegation.isRevoked) {\n return false;\n }\n\n // Check expiry\n const now = new Date();\n if (delegation.expiry && delegation.expiry < now) {\n return false;\n }\n\n return true;\n }\n\n // ===========================================================================\n // Key Access\n // ===========================================================================\n\n /**\n * Get a key by its ID.\n *\n * @param keyId - The key ID\n * @returns The key info, or undefined if not found\n */\n getKey(keyId: string): KeyInfo | undefined {\n return this.keys.get(keyId);\n }\n\n /**\n * Get all registered keys.\n *\n * @returns Array of all registered keys\n */\n getAllKeys(): KeyInfo[] {\n return Array.from(this.keys.values());\n }\n\n // ===========================================================================\n // Clear\n // ===========================================================================\n\n /**\n * Clear all registered keys and delegations.\n */\n clear(): void {\n this.keys.clear();\n this.store.byKey.clear();\n this.store.byCid.clear();\n this.store.byCapability.clear();\n }\n\n // ===========================================================================\n // Revocation\n // ===========================================================================\n\n /**\n * Revoke a delegation by CID.\n *\n * @param cid - The delegation CID to revoke\n * @returns Result indicating success or failure\n */\n revokeDelegation(cid: string): Result<void, ServiceError> {\n const stored = this.store.byCid.get(cid);\n\n if (!stored) {\n return err(\n serviceError(\n CapabilityKeyRegistryErrorCodes.KEY_NOT_FOUND,\n `Delegation not found: ${cid}`,\n SERVICE_NAME\n )\n );\n }\n\n // Mark the delegation as revoked\n stored.delegation.isRevoked = true;\n\n // Update in byKey\n const keyDelegations = this.store.byKey.get(stored.keyId);\n if (keyDelegations) {\n const delegation = keyDelegations.find((d) => d.cid === cid);\n if (delegation) {\n delegation.isRevoked = true;\n }\n }\n\n // Update in byCapability\n for (const entries of this.store.byCapability.values()) {\n for (const entry of entries) {\n if (entry.delegation.cid === cid) {\n entry.delegation.isRevoked = true;\n }\n }\n }\n\n return ok(undefined);\n }\n\n // ===========================================================================\n // Search\n // ===========================================================================\n\n /**\n * Find capabilities that match a resource path pattern.\n *\n * @param resourcePattern - Resource pattern (supports wildcards)\n * @param action - Optional action filter\n * @returns Matching capability entries\n */\n findCapabilities(\n resourcePattern: string,\n action?: string\n ): CapabilityEntry[] {\n const results: CapabilityEntry[] = [];\n\n for (const entries of this.store.byCapability.values()) {\n for (const entry of entries) {\n // Check action match if specified\n if (action && entry.action !== action) {\n continue;\n }\n\n // Check resource pattern match\n if (this.matchesResourcePattern(entry.resource, resourcePattern)) {\n results.push(entry);\n }\n }\n }\n\n return results;\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * Add a delegation to the store.\n *\n * @param key - The key associated with this delegation\n * @param delegation - The delegation to add\n */\n private addDelegation(key: KeyInfo, delegation: Delegation): void {\n // Add to byKey\n const keyDelegations = this.store.byKey.get(key.id) || [];\n if (!keyDelegations.some((d) => d.cid === delegation.cid)) {\n keyDelegations.push(delegation);\n this.store.byKey.set(key.id, keyDelegations);\n }\n\n // Add to byCid\n if (!this.store.byCid.has(delegation.cid)) {\n this.store.byCid.set(delegation.cid, {\n delegation,\n parentCid: delegation.parentCid,\n keyId: key.id,\n storedAt: new Date(),\n });\n }\n\n // Add to byCapability for each action\n for (const action of delegation.actions) {\n const capKey = this.makeCapabilityKey(delegation.path, action);\n const entries = this.store.byCapability.get(capKey) || [];\n\n // Check if we already have an entry for this exact delegation\n const existingEntry = entries.find((e) => e.delegation.cid === delegation.cid);\n\n if (existingEntry) {\n // Add this key if not already present\n if (!existingEntry.keys.some((k: KeyInfo) => k.id === key.id)) {\n existingEntry.keys.push(key);\n // Re-sort by priority\n existingEntry.keys.sort((a: KeyInfo, b: KeyInfo) => a.priority - b.priority);\n }\n } else {\n // Create new capability entry\n const entry: CapabilityEntry = {\n resource: delegation.path,\n action,\n keys: [key],\n delegation,\n expiresAt: delegation.expiry,\n };\n entries.push(entry);\n this.store.byCapability.set(capKey, entries);\n }\n }\n }\n\n /**\n * Create a capability key for indexing.\n *\n * @param resource - Resource path\n * @param action - Action\n * @returns Combined key string\n */\n private makeCapabilityKey(resource: string, action: string): string {\n return `${resource}|${action}`;\n }\n\n /**\n * Find capability entries that match a resource and action.\n *\n * @param resource - Resource to match\n * @param action - Action to match\n * @returns Matching entries\n */\n private findMatchingEntries(\n resource: string,\n action: string\n ): CapabilityEntry[] {\n const results: CapabilityEntry[] = [];\n\n // Exact match\n const exactKey = this.makeCapabilityKey(resource, action);\n const exactEntries = this.store.byCapability.get(exactKey);\n if (exactEntries) {\n results.push(...exactEntries);\n }\n\n // Wildcard matches - check all entries for patterns that match this resource\n for (const [capKey, entries] of this.store.byCapability) {\n if (capKey === exactKey) continue; // Already handled\n\n for (const entry of entries) {\n // Check if the entry's action matches\n if (!this.actionMatches(entry.action, action)) {\n continue;\n }\n\n // Check if the entry's resource pattern matches the requested resource\n if (this.resourceMatchesPattern(resource, entry.resource)) {\n if (!results.some((r) => r.delegation.cid === entry.delegation.cid)) {\n results.push(entry);\n }\n }\n }\n }\n\n return results;\n }\n\n /**\n * Check if an action pattern matches a specific action.\n *\n * @param pattern - Action pattern (may include wildcard like \"tinycloud.kv/*\")\n * @param action - Specific action to check\n * @returns true if pattern matches action\n */\n private actionMatches(pattern: string, action: string): boolean {\n // Exact match\n if (pattern === action) {\n return true;\n }\n\n // Wildcard match (e.g., \"tinycloud.kv/*\" matches \"tinycloud.kv/get\")\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n return action.startsWith(prefix + \"/\") || action === prefix;\n }\n\n return false;\n }\n\n /**\n * Check if a resource matches a pattern.\n *\n * Patterns support:\n * - Exact match: \"/kv/data\" matches \"/kv/data\"\n * - Wildcard suffix: \"/kv/*\" matches \"/kv/anything\"\n * - Double wildcard: \"/kv/**\" matches \"/kv/any/nested/path\"\n *\n * @param resource - The specific resource being accessed\n * @param pattern - The pattern from the delegation\n * @returns true if resource matches pattern\n */\n private resourceMatchesPattern(resource: string, pattern: string): boolean {\n // Exact match\n if (pattern === resource) {\n return true;\n }\n\n // Double wildcard (**) - matches any nested path\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n return resource.startsWith(prefix);\n }\n\n // Single wildcard (*) - matches one path segment\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n if (!resource.startsWith(prefix)) {\n return false;\n }\n const remainder = resource.slice(prefix.length);\n // Should be a single segment (no more slashes except possibly trailing)\n return !remainder.includes(\"/\") || remainder === \"/\";\n }\n\n // Prefix match for paths ending with /\n if (pattern.endsWith(\"/\") && resource.startsWith(pattern)) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Check if a specific resource matches a resource pattern for searching.\n *\n * @param entryResource - The resource from a capability entry\n * @param searchPattern - The pattern to search for\n * @returns true if entry resource matches search pattern\n */\n private matchesResourcePattern(\n entryResource: string,\n searchPattern: string\n ): boolean {\n // Use the same logic as resourceMatchesPattern\n return this.resourceMatchesPattern(entryResource, searchPattern) ||\n this.resourceMatchesPattern(searchPattern, entryResource);\n }\n}\n\n/**\n * Create a new CapabilityKeyRegistry instance.\n *\n * @returns A new registry instance\n */\nexport function createCapabilityKeyRegistry(): ICapabilityKeyRegistry {\n return new CapabilityKeyRegistry();\n}\n","/**\n * SignStrategy types for TinyCloud authorization.\n *\n * These types define how sign requests are handled across different\n * SDK implementations (web-sdk, node-sdk). The pattern allows for\n * automatic signing, rejection, callback-based approval, or event-driven\n * workflows.\n *\n * @packageDocumentation\n */\n\n/**\n * Sign request passed to callback or event handlers.\n */\nexport interface SignRequest {\n /** Ethereum address of the signer */\n address: string;\n /** Chain ID for the signing context */\n chainId: number;\n /** Message to be signed */\n message: string;\n /** Type of sign operation */\n type: \"siwe\" | \"message\";\n}\n\n/**\n * Sign response from callback or event handlers.\n */\nexport interface SignResponse {\n /** Whether the sign request was approved */\n approved: boolean;\n /** The signature if approved */\n signature?: string;\n /** Reason for rejection if not approved */\n reason?: string;\n}\n\n/**\n * Callback handler type for sign requests.\n */\nexport type SignCallback = (request: SignRequest) => Promise<SignResponse>;\n\n/**\n * Auto-sign strategy: automatically signs all requests.\n *\n * Use cases:\n * - Trusted backend services\n * - Automated scripts\n * - CI/CD pipelines\n *\n * @example\n * ```typescript\n * const strategy: AutoSignStrategy = { type: 'auto-sign' };\n * ```\n */\nexport interface AutoSignStrategy {\n type: \"auto-sign\";\n}\n\n/**\n * Auto-reject strategy: rejects all sign requests.\n *\n * Use cases:\n * - Read-only applications\n * - Testing rejection flows\n *\n * @example\n * ```typescript\n * const strategy: AutoRejectStrategy = { type: 'auto-reject' };\n * ```\n */\nexport interface AutoRejectStrategy {\n type: \"auto-reject\";\n}\n\n/**\n * Callback strategy: delegates sign decisions to a callback function.\n *\n * Use cases:\n * - CLI applications with user prompts\n * - Custom approval workflows\n * - Interactive sign flows\n *\n * @example\n * ```typescript\n * const strategy: CallbackStrategy = {\n * type: 'callback',\n * handler: async (req) => {\n * const approved = await promptUser(`Sign message for ${req.address}?`);\n * return { approved, signature: approved ? await signer.sign(req.message) : undefined };\n * }\n * };\n * ```\n */\nexport interface CallbackStrategy {\n type: \"callback\";\n handler: SignCallback;\n}\n\n/**\n * Event emitter strategy: emits sign requests as events.\n *\n * Uses EventTarget for cross-platform compatibility (browser + Node.js).\n *\n * Events emitted:\n * - 'sign-request': When a sign request is received\n *\n * Use cases:\n * - Async approval workflows\n * - External signing services\n * - Multi-step authorization flows\n *\n * @example\n * ```typescript\n * const emitter = new EventTarget();\n * const strategy: EventEmitterStrategy = { type: 'event-emitter', emitter };\n *\n * emitter.addEventListener('sign-request', async (event) => {\n * const { request, respond } = (event as CustomEvent).detail;\n * const approved = await externalApprovalService.check(request);\n * respond({ approved, signature: approved ? await sign(request.message) : undefined });\n * });\n * ```\n */\nexport interface EventEmitterStrategy {\n type: \"event-emitter\";\n emitter: EventTarget;\n /** Timeout in milliseconds for waiting on event response (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Sign strategy union type.\n *\n * Determines how sign requests are handled in UserAuthorization implementations.\n */\nexport type SignStrategy =\n | AutoSignStrategy\n | AutoRejectStrategy\n | CallbackStrategy\n | EventEmitterStrategy;\n\n/**\n * Default sign strategy is auto-sign for convenience.\n */\nexport const defaultSignStrategy: SignStrategy = { type: \"auto-sign\" };\n","/**\n * Space creation handler types for TinyCloud authorization.\n *\n * These types abstract space creation confirmation, allowing different\n * implementations for web (modal) vs node (auto-approve) environments.\n *\n * @packageDocumentation\n */\n\n/**\n * Context passed to space creation handlers.\n */\nexport interface SpaceCreationContext {\n /** The unique identifier for the space being created */\n spaceId: string;\n /** Ethereum address of the user creating the space */\n address: string;\n /** Chain ID for the creation context */\n chainId: number;\n /** Host URL where the space will be created */\n host: string;\n}\n\n/**\n * Interface for handling space creation confirmation.\n *\n * Implementations can provide different UX patterns:\n * - Auto-approve for backend services\n * - Modal confirmation for web apps\n * - CLI prompts for terminal apps\n *\n * @example\n * ```typescript\n * class ModalSpaceCreationHandler implements ISpaceCreationHandler {\n * async confirmSpaceCreation(context: SpaceCreationContext): Promise<boolean> {\n * return await showConfirmationModal(`Create space ${context.spaceId}?`);\n * }\n *\n * onSpaceCreated(context: SpaceCreationContext): void {\n * showToast(`Space ${context.spaceId} created!`);\n * }\n *\n * onSpaceCreationFailed(context: SpaceCreationContext, error: Error): void {\n * showErrorModal(`Failed to create space: ${error.message}`);\n * }\n * }\n * ```\n */\nexport interface ISpaceCreationHandler {\n /**\n * Called when a new space needs to be created.\n * Returns true if space should be created, false to skip.\n *\n * @param context - Information about the space to be created\n * @returns Promise resolving to true to proceed, false to cancel\n */\n confirmSpaceCreation(context: SpaceCreationContext): Promise<boolean>;\n\n /**\n * Called after successful space creation.\n * Optional - implement to show success UI or perform cleanup.\n *\n * @param context - Information about the created space\n */\n onSpaceCreated?(context: SpaceCreationContext): void;\n\n /**\n * Called if space creation fails.\n * Optional - implement to show error UI or perform recovery.\n *\n * @param context - Information about the space that failed to create\n * @param error - The error that occurred\n */\n onSpaceCreationFailed?(context: SpaceCreationContext, error: Error): void;\n}\n\n/**\n * Default handler that auto-approves all space creation.\n *\n * Use cases:\n * - Backend services\n * - Automated scripts\n * - Node.js applications without UI\n *\n * @example\n * ```typescript\n * const handler = new AutoApproveSpaceCreationHandler();\n * const config = { spaceCreationHandler: handler };\n * ```\n */\nexport class AutoApproveSpaceCreationHandler implements ISpaceCreationHandler {\n /**\n * Always returns true to auto-approve space creation.\n */\n async confirmSpaceCreation(): Promise<boolean> {\n return true;\n }\n}\n\n/**\n * Default space creation handler that auto-approves all requests.\n */\nexport const defaultSpaceCreationHandler: ISpaceCreationHandler =\n new AutoApproveSpaceCreationHandler();\n","/**\n * Protocol version checking for SDK-to-node compatibility.\n *\n * @packageDocumentation\n */\n\nexport class ProtocolMismatchError extends Error {\n name = \"ProtocolMismatchError\" as const;\n constructor(\n public readonly sdkProtocol: number,\n public readonly nodeProtocol: number,\n public readonly nodeVersion: string,\n public readonly host: string\n ) {\n super(\n `SDK protocol version ${sdkProtocol} is incompatible with node protocol version ${nodeProtocol} (node v${nodeVersion}) at ${host}. ` +\n (sdkProtocol < nodeProtocol\n ? \"Please update your SDK.\"\n : \"Please update the TinyCloud node.\")\n );\n }\n}\n\nexport class VersionCheckError extends Error {\n name = \"VersionCheckError\" as const;\n constructor(\n public readonly host: string,\n public readonly cause?: Error\n ) {\n super(\n `Failed to fetch node info at ${host}. Ensure the node is running and the /info endpoint is accessible.`\n );\n }\n}\n\nexport class UnsupportedFeatureError extends Error {\n name = \"UnsupportedFeatureError\" as const;\n constructor(\n public readonly feature: string,\n public readonly host: string,\n public readonly availableFeatures: string[]\n ) {\n super(\n `Feature \"${feature}\" is not supported by the node at ${host}. ` +\n `Available features: ${availableFeatures.join(\", \") || \"none\"}.`\n );\n }\n}\n\nexport interface NodeInfo {\n features: string[];\n quotaUrl?: string;\n}\n\nexport async function checkNodeInfo(\n host: string,\n sdkProtocol: number,\n fetchFn: typeof globalThis.fetch = globalThis.fetch.bind(globalThis)\n): Promise<NodeInfo> {\n let response: Response;\n try {\n response = await fetchFn(`${host}/info`, {\n signal: AbortSignal.timeout(5000),\n });\n } catch (err) {\n throw new VersionCheckError(host, err as Error);\n }\n\n if (!response.ok) {\n throw new VersionCheckError(host);\n }\n\n const data = (await response.json()) as {\n protocol: number;\n version: string;\n features: string[];\n quota_url?: string;\n };\n\n if (sdkProtocol !== data.protocol) {\n throw new ProtocolMismatchError(\n sdkProtocol,\n data.protocol,\n data.version,\n host\n );\n }\n\n return {\n features: data.features ?? [],\n quotaUrl: data.quota_url,\n };\n}\n","/**\n * Capability subset checking and recap parsing.\n *\n * This module powers the capability-chain delegation flow. The key decision\n * a `delegateTo` call has to make is: \"are the requested capabilities a\n * subset of what the current session already grants?\"\n *\n * - If yes → issue the delegation via the session-key UCAN path (no wallet prompt).\n * - If no → raise {@link PermissionNotInManifestError} so the caller can\n * trigger an escalation flow via `requestPermissions`.\n *\n * Canonical spec: `.claude/specs/capability-chain.md`.\n *\n * @packageDocumentation\n */\n\nimport {\n type PermissionEntry,\n SERVICE_SHORT_TO_LONG,\n expandActionShortNames,\n} from \"./manifest\";\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a `delegateTo` call requests capabilities that the current\n * session does not already grant. The caller can catch this and trigger\n * `requestPermissions(missing)` to show an escalation modal.\n */\nexport class PermissionNotInManifestError extends Error {\n public readonly missing: PermissionEntry[];\n public readonly granted: PermissionEntry[];\n\n constructor(missing: PermissionEntry[], granted: PermissionEntry[]) {\n super(\n `Requested capabilities exceed current session. Missing ${missing.length} entries.`\n );\n this.name = \"PermissionNotInManifestError\";\n this.missing = missing;\n this.granted = granted;\n }\n}\n\n/**\n * Thrown when the current session has expired (or will expire within the\n * safety margin). The caller should trigger a fresh sign-in.\n */\nexport class SessionExpiredError extends Error {\n public readonly expiredAt: Date;\n\n constructor(expiredAt: Date) {\n super(`Session expired at ${expiredAt.toISOString()}`);\n this.name = \"SessionExpiredError\";\n this.expiredAt = expiredAt;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Space normalization\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a space identifier to its short-name form.\n *\n * Recap resource URIs in a signed SIWE encode the space as a full URI of the\n * form `tinycloud:pkh:eip155:{chainId}:{address}:{name}` (e.g.\n * `tinycloud:pkh:eip155:1:0xd559...:default`). Manifest permissions and\n * backend-advertised permissions use the short `{name}` form (e.g.\n * `\"default\"`).\n *\n * Strict string comparison between these two forms would always fail, so we\n * normalize both sides to the short name before comparing. The trailing\n * segment after the last `:` in a `tinycloud:` URI is the space name.\n *\n * Short names (`\"default\"`, `\"work-space\"`) are returned unchanged.\n * Any non-`tinycloud:` string is returned unchanged. A malformed URI with a\n * trailing colon is returned unchanged (so the check degrades to a strict\n * mismatch rather than collapsing to an empty string).\n *\n * @internal\n */\nexport function normalizeSpace(space: string): string {\n if (!space.startsWith(\"tinycloud:\")) {\n return space;\n }\n const lastColon = space.lastIndexOf(\":\");\n if (lastColon === -1 || lastColon === space.length - 1) {\n return space;\n }\n return space.slice(lastColon + 1);\n}\n\n// ---------------------------------------------------------------------------\n// Subset check\n// ---------------------------------------------------------------------------\n\nexport interface SubsetCheckResult {\n /** True when every requested entry is covered by a granted entry. */\n subset: boolean;\n /** Entries the granted set does not cover (empty when `subset` is true). */\n missing: PermissionEntry[];\n}\n\n/**\n * Check whether `requested` is a strict subset of `granted`.\n *\n * Matching rules for each `requested[i]`:\n * - `service` matches exactly.\n * - `space` matches exactly.\n * - Path containment:\n * - If `granted.path` ends with `/`, it covers any `requested.path` that\n * starts with `granted.path`.\n * - Otherwise, the paths must match exactly.\n * - Action containment: every URN in `requested.actions` must appear in\n * `granted.actions` (set subset).\n *\n * Any `requested` entry that does not find a matching `granted` entry is\n * added to `missing` and the overall result is non-subset.\n *\n * Both sides are expected to be in the canonical long-form shape (service\n * starts with `tinycloud.`, actions are full URNs). Use {@link parseRecapCapabilities}\n * or `expandActionShortNames` to normalize inputs first.\n */\nexport function isCapabilitySubset(\n requested: readonly PermissionEntry[],\n granted: readonly PermissionEntry[]\n): SubsetCheckResult {\n const missing: PermissionEntry[] = [];\n\n for (const req of requested) {\n const match = granted.find((g) => canonicalizeEntryMatches(req, g));\n if (match === undefined) {\n missing.push(cloneEntry(req));\n continue;\n }\n // `match` is confirmed to cover `req`; nothing to record.\n }\n\n return { subset: missing.length === 0, missing };\n}\n\n/**\n * Returns true when `granted` fully covers `requested` — same service, same\n * space, path containment per spec, and action set containment.\n */\nfunction canonicalizeEntryMatches(\n requested: PermissionEntry,\n granted: PermissionEntry\n): boolean {\n if (requested.service !== granted.service) {\n return false;\n }\n // Normalize both sides so callers passing short names (`\"default\"`) match\n // recap-parsed full URIs (`\"tinycloud:pkh:eip155:1:0xd559...:default\"`) and\n // vice versa. Idempotent for short names.\n if (normalizeSpace(requested.space) !== normalizeSpace(granted.space)) {\n return false;\n }\n if (!pathContains(granted.path, requested.path)) {\n return false;\n }\n // Normalize actions to full URN form on both sides before set comparison,\n // so a caller passing short names (\"get\") against a granted entry with\n // full URNs still behaves correctly.\n const reqActions = new Set(\n expandActionShortNames(requested.service, requested.actions)\n );\n const grantedActions = new Set(\n expandActionShortNames(granted.service, granted.actions)\n );\n for (const a of reqActions) {\n if (!grantedActions.has(a)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Path containment per spec:\n * - `granted.path` ends with `/` → prefix match (requested starts with granted)\n * - otherwise → exact string match\n *\n * The empty string is treated as \"no path constraint\" and matches anything.\n * The single-character `\"/\"` also matches anything (it is a trailing-slash\n * prefix of zero-length).\n */\nfunction pathContains(grantedPath: string, requestedPath: string): boolean {\n if (grantedPath === \"\" || grantedPath === \"/\") {\n return true;\n }\n if (grantedPath.endsWith(\"/\")) {\n return requestedPath.startsWith(grantedPath);\n }\n return requestedPath === grantedPath;\n}\n\nfunction cloneEntry(entry: PermissionEntry): PermissionEntry {\n return {\n service: entry.service,\n space: entry.space,\n path: entry.path,\n actions: [...entry.actions],\n ...(entry.skipPrefix !== undefined ? { skipPrefix: entry.skipPrefix } : {}),\n ...(entry.expiry !== undefined ? { expiry: entry.expiry } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Recap parsing (WASM wrapper)\n// ---------------------------------------------------------------------------\n\n/**\n * The raw shape returned from the WASM `parseRecapFromSiwe` export. The\n * Rust layer encodes the service in the short form (e.g. `\"kv\"`) because\n * that is what the SIWE recap resource URI actually contains. We normalize\n * to the manifest long form (`\"tinycloud.kv\"`) in {@link parseRecapCapabilities}.\n *\n * @internal\n */\nexport interface WasmRecapEntry {\n service: string;\n space: string;\n path: string;\n actions: string[];\n}\n\n/**\n * Signature of the WASM `parseRecapFromSiwe` export. Accepts the signed\n * SIWE message string and returns an array of raw recap entries. Throws if\n * the SIWE is malformed or the recap statement has been tampered.\n *\n * Exposed as an interface so the SDK can inject the web or node binding\n * without `capabilities.ts` needing to know which.\n */\nexport type ParseRecapFromSiwe = (siweString: string) => WasmRecapEntry[];\n\n/**\n * Parse a signed SIWE message into an array of {@link PermissionEntry}\n * objects in the canonical long-form manifest shape.\n *\n * This is a thin wrapper around the WASM `parseRecapFromSiwe` export that:\n * 1. Normalizes short-form services (`\"kv\"`) to long-form (`\"tinycloud.kv\"`).\n * 2. Returns entries in a deterministic order (sorted by space, then service,\n * then path) so downstream equality checks are stable.\n *\n * Returns an empty array when the SIWE has no recap resource (plain auth\n * SIWE); this matches the WASM function's behavior and the spec.\n *\n * @param parseWasm The WASM `parseRecapFromSiwe` binding.\n * @param siwe The signed SIWE message string (exactly what `session.siwe` stores).\n */\nexport function parseRecapCapabilities(\n parseWasm: ParseRecapFromSiwe,\n siwe: string\n): PermissionEntry[] {\n const raw = parseWasm(siwe);\n if (!Array.isArray(raw)) {\n throw new Error(\n \"parseRecapFromSiwe returned a non-array value; wasm binding may be out of sync\"\n );\n }\n const normalized: PermissionEntry[] = raw.map((entry) => {\n const longService =\n SERVICE_SHORT_TO_LONG[entry.service] ??\n // Unknown short names pass through. If the recap already contained a\n // long-form service (e.g. a future tinycloud-node version emits long\n // form directly), don't double-prefix.\n (entry.service.startsWith(\"tinycloud.\")\n ? entry.service\n : `tinycloud.${entry.service}`);\n return {\n service: longService,\n // The Rust layer emits the space as a full `tinycloud:pkh:...:name`\n // URI (the recap target URI). Normalize to the short name so the\n // returned entries match the shape manifests use.\n space: normalizeSpace(entry.space),\n path: entry.path,\n actions: [...entry.actions],\n };\n });\n\n // Sort for determinism (callers do equality checks on arrays of entries\n // in tests; deterministic ordering keeps those stable).\n normalized.sort((a, b) => {\n if (a.space !== b.space) return a.space < b.space ? -1 : 1;\n if (a.service !== b.service) return a.service < b.service ? -1 : 1;\n if (a.path !== b.path) return a.path < b.path ? -1 : 1;\n return 0;\n });\n\n return normalized;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMA,iBAAkB;AAClB,kBAA4B;AAUrB,IAAM,gBAAgB,aAAE,OAAO;AAAA,EACpC,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACvC,WAAW,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC;AAeM,IAAM,mBAAmB,aAC7B,OAAO;AAAA,EACN,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,KAAK,aAAE,OAAO,EAAE,SAAS;AAAA,EACzB,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,gBAAgB,aAAE,OAAO,EAAE,SAAS;AAAA,EACpC,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS;AAC1C,CAAC,EACA,YAAY;AAoBR,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,SAAS,aAAE,OAAO;AAAA,EAClB,eAAe,aAAE,OAAO;AAAA,EACxB,SAAS,aAAE,OAAO;AAAA,EAClB,YAAY,aAAE,OAAO;AAAA,EACrB,MAAM,aAAE,OAAO;AAAA,EACf,WAAW,aAAE,OAAO;AAAA,EACpB,KAAK,cAAc,SAAS;AAC9B,CAAC;AAMM,SAAS,sBAAsB,MAAqC;AACzE,QAAM,SAAS,oBAAoB,UAAU,IAAI;AACjD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;;;ACvDO,IAAM,4BAAN,MAAgE;AAAA,EACrE,UAAgB;AAAA,EAAC;AAAA,EACjB,UAAgB;AAAA,EAAC;AAAA,EACjB,QAAc;AAAA,EAAC;AACjB;;;ACxBA,IAAAA,cAAkB;AAUlB,IAAM,yBAAyB;AASxB,IAAMC,iBAAgB,cAAE,OAAO;AAAA;AAAA,EAEpC,QAAQ,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EAEvC,WAAW,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC;AAWM,IAAM,kCAAkC,cAAE,OAAO;AAAA;AAAA,EAEtD,kBAAkB,cAAE,OAAO;AAAA,IACzB,eAAe,cAAE,OAAO;AAAA,EAC1B,CAAC;AAAA;AAAA,EAED,eAAe,cAAE,OAAO;AAAA;AAAA,EAExB,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,QAAQ,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAElD,oBAAoB,cAAE,OAAO;AAC/B,CAAC;AAeM,IAAM,6BAA6B,cAAE,OAAO;AAAA;AAAA,EAEjD,SAAS,cACN,OAAO,EACP,MAAM,wBAAwB,0BAA0B;AAAA;AAAA,EAE3D,SAAS,cAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA;AAAA,EAEnC,YAAY,cAAE,OAAO;AAAA;AAAA,EAErB,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,WAAW,cAAE,OAAO;AAAA;AAAA,EAEpB,kBAAkB,gCAAgC,SAAS;AAAA;AAAA,EAE3D,WAAW,cAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA;AAAA,EAE/C,WAAW,cAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA;AAAA,EAE/C,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,KAAKA,eAAc,SAAS;AAC9B,CAAC;AAaM,IAAM,yBAAyB,cAAE,OAAO;AAAA;AAAA,EAE7C,SAAS,cAAE,OAAO,EAAE,MAAM,wBAAwB,0BAA0B;AAAA;AAAA,EAE5E,SAAS,cAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA;AAAA,EAEnC,YAAY,cAAE,OAAO;AAAA;AAAA,EAErB,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,QAAQ,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAElD,eAAe,cAAE,OAAO;AAAA;AAAA,EAExB,kBAAkB,cAAE,OAAO;AAAA,IACzB,eAAe,cAAE,OAAO;AAAA,EAC1B,CAAC;AAAA;AAAA,EAED,oBAAoB,cAAE,OAAO;AAAA;AAAA,EAE7B,KAAK,cAAE,OAAO,CAAC,CAAC,EAAE,YAAY;AAAA;AAAA,EAE9B,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,WAAW,cAAE,OAAO;AACtB,CAAC;AAoCM,SAAS,6BACd,MAC+C;AAC/C,QAAM,SAAS,2BAA2B,UAAU,IAAI;AACxD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,OAAO,MAAM;AAAA,QACtB,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;;;ACpLA,IAAAC,uBA0BO;;;ACbP,0BAAsC;;;AC6I/B,IAAM,QAAN,MAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAanC,YAAY,QAAqB;AAC/B,SAAK,MAAM,OAAO;AAClB,SAAK,QAAQ,OAAO;AACpB,SAAK,MAAM,OAAO,SAAS,OAAO,EAAE;AACpC,SAAK,eAAe,OAAO,kBAAkB,OAAO,EAAE;AACtD,SAAK,WAAW,OAAO,cAAc,OAAO,EAAE;AAC9C,SAAK,WAAW,OAAO;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAuC;AACzC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAiD;AACrD,WAAO,KAAK,SAAS,KAAK,GAAG;AAAA,EAC/B;AACF;;;ACvNA,IAAAC,cAAkB;;;ACAlB,IAAAC,cAAkB;AAwCX,IAAM,YAAY,cAAE,OAAO;AAAA;AAAA,EAEhC,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,KAAK,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEzB,GAAG,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEvB,GAAG,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEvB,GAAG,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEvB,GAAG,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEvB,GAAG,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEvB,KAAK,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEzB,KAAK,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEzB,KAAK,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEzB,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AACxC,CAAC;AAWM,IAAM,gBAAgB,cAAE,KAAK,CAAC,QAAQ,WAAW,UAAU,CAAC;AAM5D,IAAM,gBAAgB,cAAE,OAAO;AAAA;AAAA,EAEpC,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,MAAM;AAAA;AAAA,EAEN,KAAK,UAAU,SAAS;AAAA;AAAA,EAExB,UAAU,cAAE,OAAO;AACrB,CAAC;AAWM,IAAM,wBAAwB,cAAE,OAAO;AAAA;AAAA,EAE5C,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,SAAS,cAAE,QAAQ,YAAY;AAAA;AAAA,EAE/B,OAAO,cAAE,WAAW,KAAK,EAAE,SAAS;AAAA;AAAA,EAEpC,MAAM,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,QAAQ,CAAC,EAAE,SAAS;AACnD,CAAC;AAOM,IAAM,uBAAuB;AAAA,EAClC,eAAe;AAAA,EACf,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,eAAe;AAAA,EACf,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,kBAAkB;AACpB;AAYO,IAAM,mBAAmB,cAAE,OAAO;AAAA;AAAA,EAEvC,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,aAAa,cAAE,OAAO;AAAA;AAAA,EAEtB,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC;AAAA;AAAA,EAE3B,QAAQ,cAAE,OAAO,KAAK;AAAA;AAAA,EAEtB,WAAW,cAAE,QAAQ;AAAA;AAAA,EAErB,cAAc,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAElC,WAAW,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEpC,WAAW,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE/B,oBAAoB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAEzC,YAAY,cAAE,OAAO,EAAE,SAAS;AAClC,CAAC;AAOM,IAAM,wBAAwB,cAAE,OAAO;AAAA;AAAA,EAE5C,UAAU,cAAE,OAAO;AAAA;AAAA,EAEnB,QAAQ,cAAE,OAAO;AAAA;AAAA,EAEjB,MAAM,cAAE,MAAM,aAAa;AAAA;AAAA,EAE3B,YAAY;AAAA;AAAA,EAEZ,WAAW,cAAE,OAAO,KAAK,EAAE,SAAS;AACtC,CAAC;AAOM,IAAM,yBAAyB,cAAE,OAAO;AAAA;AAAA,EAE7C,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,WAAW,cAAE,OAAO;AAAA;AAAA,EAEpB,WAAW,cAAE,OAAO;AAAA;AAAA,EAEpB,OAAO,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE3B,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC;AAAA;AAAA,EAE3B,QAAQ,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEjC,WAAW,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEpC,WAAW,cAAE,QAAQ;AAAA;AAAA,EAErB,WAAW,cAAE,OAAO,KAAK;AAAA;AAAA,EAEzB,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAOM,IAAM,+BAA+B,cAAE,OAAO;AAAA;AAAA,EAEnD,aAAa,cAAE,OAAO;AAAA;AAAA,EAEtB,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC;AAAA;AAAA,EAE3B,QAAQ,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEjC,sBAAsB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAE3C,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAOM,IAAM,wBAAwB,cAAE,MAAM,gBAAgB;AAMtD,IAAM,0BAA0B,cAAE,OAAO;AAAA;AAAA,EAE9C,MAAM;AAAA;AAAA,EAEN,OAAO,cAAE,MAAM,gBAAgB;AAAA;AAAA,EAE/B,MAAM;AACR,CAAC;AAWM,IAAM,4BAA4B,cAAE,KAAK,CAAC,WAAW,YAAY,KAAK,CAAC;AAMvE,IAAM,0BAA0B,cAAE,OAAO;AAAA;AAAA,EAE9C,WAAW,0BAA0B,SAAS;AAAA;AAAA,EAE9C,MAAM,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE1B,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAEtC,gBAAgB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAErC,WAAW,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE/B,WAAW,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE/B,SAAS,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAElC,OAAO,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE3B,QAAQ,cAAE,OAAO,EAAE,SAAS;AAC9B,CAAC;AAWM,IAAM,uBAAuB,cAAE,KAAK,CAAC,SAAS,WAAW,CAAC;AAM1D,IAAM,kBAAkB,cAAE,OAAO;AAAA;AAAA,EAEtC,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,MAAM,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE1B,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,MAAM;AAAA;AAAA,EAEN,aAAa,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAE1C,WAAW,cAAE,OAAO,KAAK,EAAE,SAAS;AACtC,CAAC;AAWM,IAAM,oBAAoB,cAAE,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC;AAM9D,IAAM,kBAAkB,cAAE,OAAO;AAAA;AAAA,EAEtC,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,YAAY;AAAA;AAAA,EAEZ,QAAQ;AAAA;AAAA,EAER,WAAW,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEpC,aAAa,cAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAOM,SAAS,0BAAkD,YAAe;AAC/E,SAAO,cAAE,OAAO;AAAA;AAAA,IAEd,MAAM;AAAA;AAAA,IAEN,YAAY;AAAA;AAAA,IAEZ,SAAS,cAAE,OAAO;AAAA;AAAA,IAElB,MAAM,cAAE,OAAO;AAAA,EACjB,CAAC;AACH;AAEO,IAAM,sBAAsB,0BAA0B,cAAE,QAAQ,CAAC;AAejE,IAAM,sBAAsB,cAAE,OAAO;AAAA;AAAA,EAE1C,SAAS,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAE9B,eAAe,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAEpC,SAAS,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE7B,kBAAkB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAEvC,UAAU,cAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAWM,IAAM,4BAA4B,cAAE,OAAO;AAAA;AAAA,EAEhD,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAEtC,QAAQ,cAAE,OAAO,KAAK,EAAE,SAAS;AAAA;AAAA,EAEjC,QAAQ,kBAAkB,SAAS;AAAA;AAAA,EAEnC,aAAa,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEjC,SAAS,cAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAeM,IAAM,gCAAgC,cAAE,OAAO;AAAA;AAAA,EAEpD,OAAO,cAAE,MAAM,cAAE,OAAO,CAAC;AAAA;AAAA,EAEzB,SAAS,cAAE,QAAQ,EAAE;AAAA,IACnB,CAAC,QAA+B,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAC/D,EAAE,SAAS,mCAAmC;AAAA,EAChD;AAAA;AAAA,EAEA,QAAQ,cAAE,QAAQ,EAAE;AAAA,IAClB,CAAC,QAA+B,OAAO,QAAQ;AAAA,IAC/C,EAAE,SAAS,8BAA8B;AAAA,EAC3C;AAAA;AAAA,EAEA,OAAO,cAAE,QAAQ,EAAE;AAAA,IACjB,CAAC,QAA8B,QAAQ,UAAa,OAAO,QAAQ;AAAA,IACnE,EAAE,SAAS,yCAAyC;AAAA,EACtD,EAAE,SAAS;AACb,CAAC;AAOM,IAAM,oBAAoB,cAAE,OAAO;AAAA;AAAA,EAExC,kBAAkB,cAAE,QAAQ,EAAE;AAAA,IAC5B,CAAC,QAAkD,OAAO,QAAQ;AAAA,IAClE,EAAE,SAAS,sBAAsB;AAAA,EACnC;AAAA;AAAA,EAEA,QAAQ,cAAE,QAAQ,EAAE;AAAA,IAClB,CAAC,QAA0C,OAAO,QAAQ;AAAA,IAC1D,EAAE,SAAS,sBAAsB;AAAA,EACnC;AAAA;AAAA,EAEA,QAAQ,cAAE,QAAQ,EAAE;AAAA,IAClB,CAAC,QAAmD,OAAO,QAAQ;AAAA,IACnE,EAAE,SAAS,sBAAsB;AAAA,EACnC;AACF,CAAC;AAWM,IAAM,8BAA8B,cAAE,OAAO;AAAA;AAAA,EAElD,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,WAAW,cAAE,OAAO;AAAA;AAAA,EAEpB,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,KAAK,cAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAqBM,IAAM,0BAA0B,cAAE,OAAO;AAAA;AAAA,EAE9C,SAAS,cAAE,OAAO;AAAA;AAAA,EAElB,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC;AAC7B,CAAC;AAgBM,IAAM,mCAAmC,cAAE,OAAO;AAAA;AAAA,EAEvD,SAAS,cAAE,QAAQ,EAAE;AAAA,IACnB,CAAC,QAA+B,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAC/D,EAAE,SAAS,mCAAmC;AAAA,EAChD;AAAA;AAAA,EAEA,aAAa,cAAE,OAAO;AAAA;AAAA,EAEtB,SAAS,cAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBlB,WAAW,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,CAAC;AAAA;AAAA,EAEzE,gBAAgB,cAAE,OAAO;AAAA;AAAA,EAEzB,eAAe,cAAE,OAAO,EAAE,SAAS;AACrC,CAAC;AAYM,IAAM,mCAAmC,cAAE,OAAO;AAAA;AAAA,EAEvD,YAAY,cAAE,OAAO;AAAA;AAAA,EAErB,KAAK,cAAE,OAAO;AAAA;AAAA,EAEd,aAAa,cAAE,OAAO;AAAA;AAAA,EAEtB,QAAQ,cAAE,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,WAAW,cAAE,MAAM,uBAAuB;AAC5C,CAAC;;;ADpkBM,IAAM,oBAAoB,cAAE,OAAO;AAAA;AAAA,EAExC,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,UAAU,cAAE,SAAS;AAAA;AAAA,EAErB,mBAAmB,cAAE,SAAS;AAAA;AAAA,EAE9B,eAAe,cAAE,SAAS;AAAA;AAAA,EAE1B,SAAS,cAAE,SAAS;AACtB,CAAC;AAcM,IAAM,2BAA2B,cAAE,OAAO;AAAA;AAAA,EAE/C,OAAO,cAAE,MAAM,cAAE,OAAO,CAAC;AAAA;AAAA,EAEzB,SAAS,cAAE,QAAQ;AAAA;AAAA,EAEnB,QAAQ,cAAE,SAAS;AAAA;AAAA,EAEnB,OAAO,cAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EAE7B,oBAAoB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAEzC,iBAAiB,cAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EAEvC,SAAS,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE7B,gBAAgB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,EAErC,kBAAkB,cAAE,SAAS,EAAE,SAAS;AAC1C,CAAC;AAaM,IAAM,8BAA8B,6BAA6B,OAAO;AAAA;AAAA,EAE7E,SAAS,cAAE,OAAO;AACpB,CAAC;AAsHM,IAAM,6BAA6B,cAAE,OAAO;AAAA;AAAA,EAEjD,WAAW,cAAE,OAAO;AAAA;AAAA,EAEpB,UAAU,cAAE,OAAO;AAAA;AAAA,EAEnB,SAAS,cAAE,MAAM,cAAE,MAAM,CAAC,cAAE,OAAO,GAAG,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAAA;AAAA,EAE3D,QAAQ,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE5B,YAAY,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEhC,WAAW,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE/B,cAAc,cAAE;AAAA,IACd,cAAE,OAAO;AAAA,MACP,UAAU,cAAE,OAAO;AAAA,MACnB,SAAS,cAAE,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AACF,CAAC;AAQM,IAAM,kCAAkC,cAAE;AAAA,EAC/C,cAAE,OAAO;AAAA,EACT;AACF;AAQO,IAAM,yBAAyB,cAAE,OAAO;AAAA;AAAA,EAE7C,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,MAAM,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE1B,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAIM,IAAM,kCAAkC,cAAE,MAAM,sBAAsB;AAOtE,IAAM,kCAAkC,cAAE,OAAO;AAAA;AAAA,EAEtD,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,MAAM,cAAE,OAAO;AAAA;AAAA,EAEf,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAOM,IAAM,gCAAgC,cAAE,OAAO;AAAA;AAAA,EAEpD,IAAI,cAAE,OAAO;AAAA;AAAA,EAEb,MAAM,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE1B,OAAO,cAAE,OAAO;AAAA;AAAA,EAEhB,MAAM,cAAE,KAAK,CAAC,SAAS,WAAW,CAAC,EAAE,SAAS;AAAA;AAAA,EAE9C,aAAa,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EAE1C,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAcM,SAAS,kCACd,MACoD;AAEpD,MAAI,SAAS,QAAQ,SAAS,QAAW;AACvC,WAAO,EAAE,IAAI,MAAM,MAAM,CAAC,EAAE;AAAA,EAC9B;AAGA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,EAAE,IAAI,MAAM,MAAM,CAAC,EAAE;AAAA,EAC9B;AAEA,QAAM,SAAS,gCAAgC,UAAU,IAAI;AAC7D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,wCAAwC,OAAO,MAAM,OAAO;AAAA,QACrE,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;AAQO,SAAS,kCACd,MACoD;AACpD,QAAM,SAAS,gCAAgC,UAAU,IAAI;AAC7D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,yCAAyC,OAAO,MAAM,OAAO;AAAA,QACtE,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;AAQO,SAAS,kCACd,MACoD;AACpD,QAAM,SAAS,gCAAgC,UAAU,IAAI;AAC7D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,yCAAyC,OAAO,MAAM,OAAO;AAAA,QACtE,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;AAQO,SAAS,gCACd,MACkD;AAClD,QAAM,SAAS,8BAA8B,UAAU,IAAI;AAC3D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,uCAAuC,OAAO,MAAM,OAAO;AAAA,QACpE,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;;;AFlXA,IAAM,eAAe;AAKd,IAAM,kBAAkB;AAAA;AAAA,EAE7B,WAAW;AAAA;AAAA,EAEX,gBAAgB;AAAA;AAAA,EAEhB,iBAAiB;AAAA;AAAA,EAEjB,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,eAAe;AAAA;AAAA,EAEf,iBAAiB;AACnB;AAwHO,SAAS,kBAAkB,SAAiB,SAAyB;AAC1E,SAAO,wBAAwB,OAAO,IAAI,OAAO;AACnD;AAeO,SAAS,cACd,KAC4E;AAE5E,QAAM,eAAe,IAAI;AAAA,IACvB;AAAA,EACF;AACA,MAAI,cAAc;AAChB,UAAM,CAAC,EAAE,SAAS,SAAS,IAAI,IAAI;AACnC,WAAO;AAAA,MACL,OAAO,kBAAkB,OAAO,IAAI,OAAO;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,mBAAmB,KAAK,GAAG,GAAG;AAChC,WAAO;AAAA,MACL,OAAO;AAAA;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,cAAc,OAAe,MAAsB;AAEjE,QAAM,WAAW,MAAM,MAAM,4CAA4C;AACzE,MAAI,UAAU;AACZ,UAAM,CAAC,EAAE,SAAS,OAAO,IAAI;AAC7B,WAAO,wBAAwB,OAAO,IAAI,OAAO,IAAI,IAAI;AAAA,EAC3D;AAEA,SAAO,aAAa,KAAK,IAAI,IAAI;AACnC;AAkBA,SAAS,2BACP,eACA,gBACc;AACd,QAAM,SAAuB,CAAC;AAE9B,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,aAAa,GAAG;AAEvD,UAAM,eAAe,KAAK;AAC1B,QAAI,OAAO;AACX,QAAI,UAAU;AACd,UAAM,UAAoB,CAAC;AAE3B,eAAW,OAAO,cAAc;AAC9B,cAAQ,KAAK,IAAI,OAAO;AAGxB,YAAM,gBAAgB,IAAI,SAAS;AAAA,QACjC;AAAA,MACF;AACA,UAAI,eAAe;AACjB,kBAAU,cAAc,CAAC;AACzB,eAAO,cAAc,CAAC,KAAK;AAAA,MAC7B;AAAA,IACF;AAGA,UAAM,oBAAoB,KAAK,SAAS,KAAK,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAEtF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,GAAI;AAAA,MACvF,WAAW;AAAA,MACX,WAAW,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,MACvD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAiCO,IAAM,eAAN,MAA4C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBjD,YAAY,QAA4B;AAbxC;AAAA,SAAQ,aAAkC,oBAAI,IAAI;AAGlD;AAAA,SAAQ,YAAgE,oBAAI,IAAI;AAGhF;AAAA,SAAiB,WAAW,IAAI,KAAK;AAQnC,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO;AACtB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,SAAS,WAAW,MAAM,KAAK,UAAU;AAC/D,SAAK,qBAAqB,OAAO;AACjC,SAAK,oBAAoB,OAAO;AAChC,SAAK,WAAW,OAAO;AACvB,SAAK,iBAAiB,OAAO;AAC7B,SAAK,qBAAqB,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,QAA2C;AACtD,QAAI,OAAO,MAAO,MAAK,QAAQ,OAAO;AACtC,QAAI,OAAO,QAAS,MAAK,UAAU,OAAO;AAC1C,QAAI,OAAO,OAAQ,MAAK,SAAS,OAAO;AACxC,QAAI,OAAO,MAAO,MAAK,UAAU,OAAO;AACxC,QAAI,OAAO,mBAAoB,MAAK,qBAAqB,OAAO;AAChE,QAAI,OAAO,gBAAiB,MAAK,oBAAoB,OAAO;AAC5D,QAAI,OAAO,YAAY,OAAW,MAAK,WAAW,OAAO;AACzD,QAAI,OAAO,eAAgB,MAAK,iBAAiB,OAAO;AACxD,QAAI,OAAO,iBAAkB,MAAK,qBAAqB,OAAO;AAG9D,SAAK,WAAW,MAAM;AACtB,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAwC;AACtC,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,OAAe;AACzB,WAAO,KAAK,MAAM,CAAC;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,UAA8B;AAExC,QAAI,KAAK,UAAU;AACjB,aAAO,KAAK;AAAA,IACd;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,OAAmD;AACvD,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAO;AAAA,YACL,kCAAa,gBAAgB,eAAe,2BAA2B,YAAY;AAAA,MACrF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAsB,CAAC;AAG7B,YAAM,cAAc,MAAM,KAAK,gBAAgB;AAC/C,UAAI,YAAY,IAAI;AAClB,eAAO,KAAK,GAAG,YAAY,IAAI;AAAA,MACjC;AAGA,UAAI,KAAK,oBAAoB;AAC3B,cAAM,kBAAkB,KAAK,wBAAwB;AACrD,eAAO,KAAK,GAAG,eAAe;AAAA,MAChC;AAGA,YAAM,eAAe,KAAK,kBAAkB,MAAM;AAElD,iBAAO,wBAAG,YAAY;AAAA,IACxB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gBAAgB;AAAA,UAChB,0BAA0B,OAAO,KAAK,CAAC;AAAA,UACvC;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAA8D;AAC1E,QAAI;AACF,YAAM,UAAU,KAAK,OAAO,KAAK,SAAS,SAAS,IAAI,sBAAsB;AAE7E,YAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,QACzD,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,gCAAgC,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9D;AAAA,YACA,EAAE,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,SAAS,KAAK;AAGpC,YAAM,mBAAmB,kCAAkC,OAAO;AAClE,UAAI,CAAC,iBAAiB,IAAI;AACxB,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,iBAAiB,MAAM;AAAA,YACvB;AAAA,YACA,EAAE,MAAM,iBAAiB,MAAM,KAAK;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SAAsB,iBAAiB,KAAK,IAAI,CAAC,UAAU;AAAA,QAC/D,IAAI,KAAK;AAAA,QACT,MAAM,KAAK,QAAQ,KAAK,kBAAkB,KAAK,EAAE;AAAA,QACjD,OAAO,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,aAAa,CAAC,GAAG;AAAA;AAAA,MACnB,EAAE;AAEF,iBAAO,wBAAG,MAAM;AAAA,IAClB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gBAAgB;AAAA,UAChB,uCAAuC,OAAO,KAAK,CAAC;AAAA,UACpD;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAAuC;AAC7C,QAAI,CAAC,KAAK,oBAAoB;AAC5B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAiC,oBAAI,IAAI;AAG/C,UAAM,eAAe,KAAK,mBAAmB,mBAAmB;AAEhE,eAAW,cAAc,cAAc;AACrC,YAAM,UAAU,WAAW,WAAW;AAGtC,UAAI,OAAO,IAAI,OAAO,GAAG;AACvB,cAAM,WAAW,OAAO,IAAI,OAAO;AAEnC,YAAI,SAAS,aAAa;AACxB,gBAAM,UAAU,WAAW,WAAW;AACtC,qBAAW,UAAU,SAAS;AAC5B,gBAAI,CAAC,SAAS,YAAY,SAAS,MAAM,GAAG;AAC1C,uBAAS,YAAY,KAAK,MAAM;AAAA,YAClC;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,YAAY,KAAK,SAAS,SAAS;AACrC;AAAA,MACF;AAEA,YAAM,SAAS,cAAc,OAAO;AAEpC,aAAO,IAAI,SAAS;AAAA,QAClB,IAAI;AAAA,QACJ,MAAM,QAAQ,QAAQ,KAAK,kBAAkB,OAAO;AAAA,QACpD,OAAO,WAAW,WAAW,gBAAgB,QAAQ,SAAS;AAAA,QAC9D,MAAM;AAAA,QACN,aAAa,CAAC,GAAG,WAAW,WAAW,OAAO;AAAA,QAC9C,WAAW,WAAW;AAAA,MACxB,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,KAAK,OAAO,OAAO,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,IAAoB;AAC5C,UAAM,SAAS,cAAc,EAAE;AAC/B,QAAI,QAAQ;AACV,aAAO,OAAO;AAAA,IAChB;AAEA,UAAM,QAAQ,GAAG,MAAM,GAAG;AAC1B,WAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,QAAkC;AAC1D,UAAM,OAAO,oBAAI,IAAuB;AAExC,eAAW,SAAS,QAAQ;AAC1B,YAAM,WAAW,KAAK,IAAI,MAAM,EAAE;AAClC,UAAI,CAAC,YAAa,SAAS,SAAS,eAAe,MAAM,SAAS,SAAU;AAC1E,aAAK,IAAI,MAAM,IAAI,KAAK;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OAAO,MAAwD;AACnE,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAO;AAAA,YACL,kCAAa,gBAAgB,eAAe,2BAA2B,YAAY;AAAA,MACrF;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,CAAC,mBAAmB,KAAK,IAAI,GAAG;AAC3C,iBAAO;AAAA,YACL;AAAA,UACE,gBAAgB;AAAA,UAChB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,KAAK,OAAO,KAAK,SAAS,SAAS,MAAM,wBAAwB;AAEjF,YAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,QACzD,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;AAAA,MAC/B,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AAEtC,YAAI,SAAS,WAAW,KAAK;AAC3B,qBAAO;AAAA,gBACL;AAAA,cACE,gBAAgB;AAAA,cAChB,UAAU,IAAI;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,2BAA2B,SAAS,MAAM,MAAM,SAAS;AAAA,YACzD;AAAA,YACA,EAAE,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,SAAS,KAAK;AAGpC,YAAM,mBAAmB,kCAAkC,OAAO;AAClE,UAAI,CAAC,iBAAiB,IAAI;AACxB,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,iBAAiB,MAAM;AAAA,YACvB;AAAA,YACA,EAAE,MAAM,iBAAiB,MAAM,KAAK;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YAAuB;AAAA,QAC3B,IAAI,iBAAiB,KAAK;AAAA,QAC1B,MAAM,iBAAiB,KAAK,QAAQ;AAAA,QACpC,OAAO,iBAAiB,KAAK,SAAS,KAAK,WAAW;AAAA,QACtD,MAAM;AAAA,QACN,aAAa,CAAC,GAAG;AAAA,MACnB;AAGA,WAAK,UAAU,IAAI,UAAU,IAAI,EAAE,MAAM,WAAW,UAAU,KAAK,IAAI,EAAE,CAAC;AAE1E,iBAAO,wBAAG,SAAS;AAAA,IACrB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gBAAgB;AAAA,UAChB,iCAAiC,OAAO,KAAK,CAAC;AAAA,UAC9C;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,IAAI,WAA2B;AAE7B,UAAM,UAAU,KAAK,eAAe,SAAS;AAG7C,UAAM,SAAS,KAAK,WAAW,IAAI,OAAO;AAC1C,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,cAAc,OAAO;AACpC,UAAM,OAAO,QAAQ,QAAQ,KAAK,kBAAkB,OAAO;AAE3D,UAAM,SAAsB;AAAA,MAC1B,IAAI;AAAA,MACJ;AAAA,MACA,UAAU,KAAK,oBAAoB,KAAK,IAAI;AAAA,MAC5C,mBAAmB,KAAK,6BAA6B,KAAK,IAAI;AAAA,MAC9D,eAAe,KAAK,yBAAyB,KAAK,IAAI;AAAA,MACtD,SAAS,KAAK,aAAa,KAAK,IAAI;AAAA,IACtC;AAEA,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,SAAK,WAAW,IAAI,SAAS,KAAK;AAElC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,WAA2B;AAChD,UAAM,SAAS,cAAc,SAAS;AAEtC,QAAI,CAAC,QAAQ;AAEX,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,OAAO;AAEhB,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,SAAS;AAChB,aAAO,cAAc,KAAK,SAAS,OAAO,IAAI;AAAA,IAChD;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAA2D;AACtE,UAAM,UAAU,KAAK,eAAe,SAAS;AAG7C,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO;AACzC,QAAI,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,UAAU;AAC1D,iBAAO,wBAAG,IAAI;AAAA,IAChB;AAGA,UAAM,aAAa,MAAM,KAAK,aAAa,OAAO;AAClD,eAAO,wBAAG,WAAW,EAAE;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,aAAa,SAA2D;AAEpF,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO;AACzC,QAAI,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,UAAU;AAC1D,iBAAO,wBAAG,OAAO,IAAI;AAAA,IACvB;AAEA,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAO;AAAA,YACL,kCAAa,gBAAgB,eAAe,2BAA2B,YAAY;AAAA,MACrF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,KAAK,OAAO,KAAK,SAAS,SAAS,SAAS,sBAAsB;AAElF,YAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,QACzD,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,KAAK;AAC3B,qBAAO;AAAA,gBACL,kCAAa,gBAAgB,WAAW,oBAAoB,OAAO,IAAI,YAAY;AAAA,UACrF;AAAA,QACF;AAEA,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,6BAA6B,SAAS,MAAM,MAAM,SAAS;AAAA,YAC3D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,SAAS,KAAK;AAGpC,YAAM,mBAAmB,gCAAgC,OAAO;AAChE,UAAI,CAAC,iBAAiB,IAAI;AACxB,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB,iBAAiB,MAAM;AAAA,YACvB;AAAA,YACA,EAAE,MAAM,iBAAiB,MAAM,KAAK;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,iBAAiB;AAC9B,YAAM,YAAuB;AAAA,QAC3B,IAAI,KAAK;AAAA,QACT,MAAM,KAAK,QAAQ,KAAK,kBAAkB,KAAK,EAAE;AAAA,QACjD,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK,SAAS,KAAK,UAAU,KAAK,UAAU,UAAU;AAAA,QAC5D,aAAa,KAAK;AAAA,QAClB,WAAW,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,MACzD;AAGA,WAAK,UAAU,IAAI,SAAS,EAAE,MAAM,WAAW,UAAU,KAAK,IAAI,EAAE,CAAC;AAErE,iBAAO,wBAAG,SAAS;AAAA,IACrB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gBAAgB;AAAA,UAChB,qCAAqC,OAAO,KAAK,CAAC;AAAA,UAClD;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,oBAAoB,SAA6B;AACvD,QAAI,KAAK,mBAAmB;AAC1B,aAAO,KAAK,kBAAkB,OAAO;AAAA,IACvC;AAGA,WAAO,IAAI,MAAM,CAAC,GAAiB;AAAA,MACjC,KAAK,MAAM;AACT,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,6BAA6B,SAA0C;AAC7E,UAAM,OAAO;AAEb,WAAO;AAAA,MACL,MAAM,OAAoD;AAExD,YAAI;AAEF,gBAAM,QAAQ;AAAA,YACZ;AAAA,cACE,wBAAwB;AAAA,gBACtB,MAAM;AAAA,gBACN,SAAS,EAAE,WAAW,UAAU;AAAA,cAClC;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,UAAU,KAAK;AAAA,YACnB,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,YACzD,QAAQ;AAAA,YACR;AAAA,UACF,CAAC;AAED,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,YAAY,MAAM,SAAS,KAAK;AACtC,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,+BAA+B,SAAS,MAAM,MAAM,SAAS;AAAA,gBAC7D;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,UAAU,MAAM,SAAS,KAAK;AAGpC,gBAAM,mBAAmB,kCAAkC,OAAO;AAClE,cAAI,CAAC,iBAAiB,IAAI;AACxB,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,iBAAiB,MAAM;AAAA,gBACvB;AAAA,gBACA,EAAE,MAAM,iBAAiB,MAAM,KAAK;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,cAAc,2BAA2B,iBAAiB,MAAM,OAAO;AAC7E,qBAAO,wBAAG,WAAW;AAAA,QACvB,SAAS,OAAO;AACd,qBAAO;AAAA,gBACL;AAAA,cACE,gBAAgB;AAAA,cAChB,sCAAsC,OAAO,KAAK,CAAC;AAAA,cACnD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,eAA4D;AAEhE,YAAI;AAEF,gBAAM,QAAQ;AAAA,YACZ;AAAA,cACE,wBAAwB;AAAA,gBACtB,MAAM;AAAA,gBACN,SAAS,EAAE,WAAW,WAAW;AAAA,cACnC;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,UAAU,KAAK;AAAA,YACnB,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,YACzD,QAAQ;AAAA,YACR;AAAA,UACF,CAAC;AAED,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,YAAY,MAAM,SAAS,KAAK;AACtC,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,wCAAwC,SAAS,MAAM,MAAM,SAAS;AAAA,gBACtE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,UAAU,MAAM,SAAS,KAAK;AAGpC,gBAAM,mBAAmB,kCAAkC,OAAO;AAClE,cAAI,CAAC,iBAAiB,IAAI;AACxB,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,iBAAiB,MAAM;AAAA,gBACvB;AAAA,gBACA,EAAE,MAAM,iBAAiB,MAAM,KAAK;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,cAAc,2BAA2B,iBAAiB,MAAM,OAAO;AAC7E,qBAAO,wBAAG,WAAW;AAAA,QACvB,SAAS,OAAO;AACd,qBAAO;AAAA,gBACL;AAAA,cACE,gBAAgB;AAAA,cAChB,+CAA+C,OAAO,KAAK,CAAC;AAAA,cAC5D;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OACJ,QAC2C;AAE3C,YAAI,KAAK,oBAAoB;AAC3B,iBAAO,KAAK,mBAAmB,EAAE,GAAG,QAAQ,QAAQ,CAAC;AAAA,QACvD;AAKA,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB;AAAA,YAEA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,KAAkD;AAC7D,YAAI;AACF,gBAAM,UAAU,KAAK;AAAA,YACnB,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,YACzD,QAAQ;AAAA,YACR;AAAA,YACA,MAAM,KAAK,UAAU,EAAE,KAAK,QAAQ,CAAC;AAAA,UACvC,CAAC;AAED,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,YAAY,MAAM,SAAS,KAAK;AACtC,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,gCAAgC,SAAS,MAAM,MAAM,SAAS;AAAA,gBAC9D;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,qBAAO,wBAAG,MAAS;AAAA,QACrB,SAAS,OAAO;AACd,qBAAO;AAAA,gBACL;AAAA,cACE,gBAAgB;AAAA,cAChB,sCAAsC,OAAO,KAAK,CAAC;AAAA,cACnD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,yBAAyB,SAAsC;AACrE,UAAM,OAAO;AAEb,WAAO;AAAA,MACL,MAAM,SACJ,QAC0C;AAE1C,YAAI,KAAK,gBAAgB;AAIvB,gBAAM,SAAS,MAAM,KAAK,eAAe,SAAS,MAAM;AACxD,cAAI,CAAC,OAAO,IAAI;AACd,uBAAO;AAAA,kBACL;AAAA,gBACE,gBAAgB;AAAA,gBAChB,OAAO,MAAM,WAAW;AAAA,gBACxB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,qBAAO,wBAAG,OAAO,IAAI;AAAA,QACvB;AAGA,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OAAmD;AAGvD,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,OAAoD;AAG/D,mBAAO;AAAA,cACL;AAAA,YACE,gBAAgB;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,mBAAmB,QAA2C;AAC5E,SAAO,IAAI,aAAa,MAAM;AAChC;;;AD5hCO,IAAM,YAAN,MAAM,WAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwCrB,YAAY,mBAAuC,QAA0B;AAzB7E;AAAA;AAAA;AAAA,SAAQ,aAA0B,CAAC;AAYnC;AAAA;AAAA;AAAA,SAAQ,YAAmC,oBAAI,IAAI;AAKnD;AAAA;AAAA;AAAA,SAAQ,uBAAgC;AAStC,SAAK,oBAAoB;AACzB,SAAK,SAAS,UAAU,CAAC;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,mBACL,QACA,OACA,SACM;AACN,UAAM,kBAAkB,UAAU,KAAK,OAAO;AAC9C,UAAM,iBAAiB,SAAS,KAAK,OAAO;AAE5C,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAEA,QAAI,CAAC,kBAAkB,eAAe,WAAW,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAGA,SAAK,kBAAkB,IAAI,oCAAe;AAAA,MACxC,QAAQ;AAAA,MACR,WAAW,KAAK,OAAO;AAAA,MACvB,OAAO,WAAW,KAAK,OAAO,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,MACvE,OAAO;AAAA,MACP,aAAa,KAAK,OAAO;AAAA,IAC3B,CAAC;AAGD,UAAM,sBAA0D;AAAA,MAC9D,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,GAAG,KAAK,OAAO;AAAA,IACjB;AAGA,eAAW,CAAC,MAAM,YAAY,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AACtE,YAAM,gBAAgB,KAAK,OAAO,iBAAiB,IAAI,KAAK,CAAC;AAC7D,YAAM,UAAU,IAAI,aAAa,aAAa;AAC9C,cAAQ,WAAW,KAAK,eAAe;AACvC,WAAK,gBAAgB,gBAAgB,MAAM,OAAO;AAClD,WAAK,UAAU,IAAI,MAAM,OAAO;AAAA,IAClC;AAEA,SAAK,uBAAuB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,iBAAkC;AAC3C,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,WAA+B,MAA6B;AACjE,WAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,KAAiB;AAC1B,QAAI,CAAC,KAAK,sBAAsB;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,KAAK,UAAU,IAAI,IAAI;AACvC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,MAAmB;AAC5B,QAAI,CAAC,KAAK,sBAAsB;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,KAAK,UAAU,IAAI,KAAK;AACxC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAyB;AAClC,QAAI,CAAC,KAAK,sBAAsB;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,KAAK,UAAU,IAAI,QAAQ;AAC3C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,QAAuB;AAChC,QAAI,CAAC,KAAK,sBAAsB;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,KAAK,UAAU,IAAI,OAAO;AAC1C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,QAA2B;AACpC,QAAI,CAAC,KAAK,sBAAsB;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,KAAK,UAAU,IAAI,OAAO;AAG1C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,8BAA8B,SAAsC;AAC1E,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,WAAW,OAAO;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,yBAA+B;AACrC,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBACN,eACuB;AACvB,QAAI,CAAC,cAAe,QAAO;AAG3B,UAAM,YAAa,cAAsB;AACzC,QAAI,CAAC,UAAW,QAAO;AAEvB,WAAO;AAAA,MACL,kBAAkB,UAAU;AAAA,MAC5B,eAAe,UAAU;AAAA,MACzB,SAAS,UAAU;AAAA,MACnB,oBAAoB,UAAU;AAAA,MAC9B,KAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAO,WAA4B;AACxC,SAAK,WAAW,KAAK,SAAS;AAC9B,SAAK,kBAAkB,OAAO,SAAS;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,mBAAmB,WAA4B;AACpD,WAAO,KAAK,WAAW,KAAK,CAAC,QAAQ,IAAI,cAAc,SAAS;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,UAAqC;AAC9C,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,aAAsB;AAC/B,WAAO,CAAC,CAAC,KAAK,kBAAkB;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,SAAiC;AAC5C,UAAM,UAAU,MAAM,KAAK,kBAAkB,OAAO;AAGpD,UAAM,iBAAiB,KAAK,iBAAiB,OAAO;AACpD,SAAK,8BAA8B,cAAc;AAEjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,UAAyB;AAEpC,SAAK,uBAAuB;AAE5B,UAAM,KAAK,kBAAkB,QAAQ;AAGrC,SAAK,YAAY;AAGjB,SAAK,8BAA8B,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKO,UAA8B;AACnC,WAAO,KAAK,kBAAkB,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKO,UAA8B;AACnC,WAAO,KAAK,kBAAkB,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,YAAY,SAAkC;AACzD,WAAO,KAAK,kBAAkB,YAAY,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,OAAO,kBAAkB,SAAiB,SAAyB;AACjE,WAAO,kBAAkB,SAAS,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,oBAAyD;AACpE,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,WAAW,CAAC,SAAS;AACxB,iBAAO;AAAA,YACL;AAAA,UACE,gCAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,iBAAiB;AACzB,iBAAO;AAAA,YACL;AAAA,UACE,gCAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,kBAAkB,SAAS,OAAO;AAGlD,QAAI;AACF,YAAM,UAAU,KAAK,gBAAgB;AACrC,UAAI,CAAC,SAAS;AACZ,mBAAO;AAAA,cACL;AAAA,YACE,gCAAW;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,gBAAgB;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,KAAK,gBAAgB;AAAA,QAC1C,GAAG,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,QAChC,EAAE,QAAQ,QAAQ,SAAS,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC,EAAE;AAAA,MAC/D;AAEA,UAAI,SAAS,IAAI;AACf,mBAAO,yBAAG,MAAS;AAAA,MACrB;AAEA,UAAI,SAAS,WAAW,KAAK;AAE3B,cAAM,gBAAgB,KAAK,gBAAgB;AAAA,UACzC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,cAAM,iBAAiB,MAAM,KAAK,gBAAgB;AAAA,UAChD,GAAG,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,UAChC;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,MAAM,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAAA,UACzC;AAAA,QACF;AAEA,YAAI,CAAC,eAAe,IAAI;AAEtB,cAAI,eAAe,WAAW,KAAK;AACjC,uBAAO,yBAAG,MAAS;AAAA,UACrB;AACA,gBAAMC,aAAY,MAAM,eAAe,KAAK;AAC5C,qBAAO;AAAA,gBACL;AAAA,cACE,gCAAW;AAAA,cACX,kCAAkC,eAAe,MAAM,MAAMA,UAAS;AAAA,cACtE;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAO,yBAAG,MAAS;AAAA,MACrB;AAGA,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,iBAAO;AAAA,YACL;AAAA,UACE,gCAAW;AAAA,UACX,iCAAiC,SAAS,MAAM,MAAM,SAAS;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gCAAW;AAAA,UACX,wCAAwC,OAAO,KAAK,CAAC;AAAA,UACrD;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAW,WAAuB;AAChC,QAAI,CAAC,KAAK,wBAAwB,CAAC,KAAK,iBAAiB;AACvD,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,WAAW,CAAC,SAAS;AACxB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAGA,QAAI,KAAK,WAAW;AAClB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,gBAAgB,kBAAkB,SAAS,OAAO;AACxD,UAAM,UAAU,KAAK,gBAAgB;AACrC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAGA,UAAM,WAAW,IAAI,+BAAU,EAAE,QAAQ,GAAG,CAAC;AAC7C,UAAM,gBAAgB,IAAI,oCAAe;AAAA,MACvC,QAAQ,KAAK,gBAAgB;AAAA,MAC7B,OAAO,KAAK,gBAAgB;AAAA,MAC5B,OAAO,KAAK,gBAAgB;AAAA,MAC5B,aAAa,KAAK,OAAO;AAAA,IAC3B,CAAC;AACD,kBAAc,WAAW;AAAA,MACvB,GAAG;AAAA,MACH,SAAS;AAAA,IACX,CAAC;AACD,aAAS,WAAW,aAAa;AAEjC,SAAK,YAAY;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,aAAa,gBACX,MACA,SACA,KACA,SACkC;AAClC,UAAM,UAAU,WAAW,WAAW,MAAM,KAAK,UAAU;AAC3D,UAAM,aAAa,IAAI,MAAM,GAAG,EAAE,IAAI,kBAAkB,EAAE,KAAK,GAAG;AAClE,UAAM,MAAM,GAAG,IAAI,WAAW,mBAAmB,OAAO,CAAC,OAAO,UAAU;AAE1E,QAAI;AACF,YAAM,WAAW,MAAM,QAAQ,KAAK,EAAE,QAAQ,MAAM,CAAC;AAErD,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,KAAK;AAC3B,qBAAO;AAAA,gBACL;AAAA,cACE,gCAAW;AAAA,cACX,kBAAkB,GAAG,aAAa,OAAO;AAAA,cACzC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAO;AAAA,cACL;AAAA,YACE,gCAAW;AAAA,YACX,gCAAgC,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9D;AAAA,YACA,EAAE,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,UAAI;AACJ,UAAI,aAAa,SAAS,kBAAkB,GAAG;AAC7C,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B,OAAO;AACL,cAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAI;AACF,iBAAO,KAAK,MAAM,IAAI;AAAA,QACxB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,iBAAO,yBAAG,IAAI;AAAA,IAChB,SAAS,OAAO;AACd,iBAAO;AAAA,YACL;AAAA,UACE,gCAAW;AAAA,UACX,uCAAuC,OAAO,KAAK,CAAC;AAAA,UACpD;AAAA,UACA,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,OAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,cACX,MACA,SACA,SACA,KACA,SACkC;AAClC,UAAM,UAAU,kBAAkB,SAAS,OAAO;AAClD,WAAO,WAAU,gBAAmB,MAAM,SAAS,KAAK,OAAO;AAAA,EACjE;AACF;;;AJzrBA,IAAAC,uBAyGO;;;ASzIP,eAAsB,YACpB,MACA,SACiB;AACjB,QAAM,MAAM,MAAM;AAAA,IAChB,GAAG,IAAI,kBAAkB,mBAAmB,OAAO,CAAC;AAAA,EACtD;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,QAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AACzD,UAAM,IAAI,MAAM,0BAA0B,IAAI,MAAM,MAAM,KAAK,EAAE;AAAA,EACnE;AAEA,SAAO,IAAI,KAAK;AAClB;AAYA,eAAsB,qBACpB,MACA,SAC0B;AAC1B,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,aAAa;AAAA,IAC1C,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,OAAO,IAAI,KAAK,SAAY,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAAA,EACzE;AACF;AAYA,eAAsB,wBACpB,MACA,kBAC0B;AAC1B,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,aAAa;AAAA,IAC1C,QAAQ;AAAA,IACR,SAAS;AAAA,EACX,CAAC;AAED,MAAI,IAAI,IAAI;AACV,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,IAAI;AAAA,QACZ,WAAW,KAAK,aAAa,CAAC;AAAA,QAC9B,SAAS,KAAK,WAAW,CAAC;AAAA,MAC5B;AAAA,IACF,QAAQ;AAEN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,IAAI;AAAA,QACZ,WAAW,CAAC;AAAA,QACZ,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,IAAI;AAAA,IACZ,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAAA,EACpD;AACF;;;ACzFA,IAAM,mBAAmB;AAAA,EACvB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AACT;AAKA,SAAS,YACP,MACA,SACA,OACA,MACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AA4BO,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW7B,YAAY,QAAiC;AAC3C,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO;AACtB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,SAA+B;AAClD,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,OAAe;AACzB,WAAO,KAAK,MAAM,CAAC;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBACZ,MACA,QACA,MACwB;AACxB,UAAM,UAAU,KAAK,OAAO,KAAK,SAAS,cAAc,MAAM,MAAM;AAEpE,WAAO,KAAK,QAAQ,GAAG,KAAK,IAAI,WAAW;AAAA,MACzC,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,OAAO,QAA6D;AAExE,QAAI,CAAC,OAAO,aAAa;AACvB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,MAAM;AAChB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,WAAW,OAAO,QAAQ,WAAW,GAAG;AAClD,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,KAAK,UAAU;AAAA,QAC1B,aAAa,OAAO;AAAA,QACpB,MAAM,OAAO;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO,QAAQ,YAAY;AAAA,QACnC,sBAAsB,OAAO,wBAAwB;AAAA,QACrD,WAAW,OAAO;AAAA,MACpB,CAAC;AAED,YAAM,WAAW,MAAM,KAAK;AAAA,QAC1B,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,gCAAgC,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9D;AAAA,YACA,EAAE,QAAQ,SAAS,QAAQ,MAAM,OAAO,KAAK;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAe,MAAM,SAAS,KAAK;AAEzC,YAAM,aAAyB;AAAA,QAC7B,KAAK,YAAY,OAAO;AAAA,QACxB,aAAa,OAAO;AAAA,QACpB,SAAS,KAAK,QAAQ;AAAA,QACtB,MAAM,OAAO;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO,UAAU,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,GAAI;AAAA,QAClE,WAAW;AAAA,QACX,oBAAoB,EAAE,OAAO,wBAAwB;AAAA,QACrD,WAAW,oBAAI,KAAK;AAAA,MACtB;AAEA,aAAO,EAAE,IAAI,MAAM,MAAM,WAAW;AAAA,IACtC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB,6CAA6C,OAAO,KAAK,CAAC;AAAA,UAC1D,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,OAAO,KAAoC;AAC/C,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,KAAK,UAAU,EAAE,IAAI,CAAC;AAEnC,YAAM,WAAW,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AAEtC,YAAI,SAAS,WAAW,KAAK;AAC3B,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAO;AAAA,cACL,qBAAqB;AAAA,cACrB,yBAAyB,GAAG;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,gCAAgC,SAAS,MAAM,MAAM,SAAS;AAAA,YAC9D;AAAA,YACA,EAAE,QAAQ,SAAS,QAAQ,IAAI;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,IAAI,MAAM,MAAM,OAAU;AAAA,IACrC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB,+CAA+C,OAAO,KAAK,CAAC;AAAA,UAC5D,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,OAAsC;AAC1C,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,gBAAgB,IAAI,iBAAiB,IAAI;AAErE,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,+BAA+B,SAAS,MAAM,MAAM,SAAS;AAAA,YAC7D;AAAA,YACA,EAAE,QAAQ,SAAS,OAAO;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAclC,YAAM,cAA4B,KAAK,IAAI,CAAC,UAAU;AAAA,QACpD,KAAK,KAAK;AAAA,QACV,aAAa,KAAK;AAAA,QAClB,cAAc,KAAK;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,QAAQ,IAAI,KAAK,KAAK,MAAM;AAAA,QAC5B,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,QACvD,WAAW,KAAK;AAAA,QAChB,oBAAoB,KAAK;AAAA,MAC3B,EAAE;AAEF,aAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AAAA,IACvC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB,yCAAyC,OAAO,KAAK,CAAC;AAAA,UACtD,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,SAAS,KAA+C;AAC5D,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,KAAK,UAAU,EAAE,KAAK,cAAc,KAAK,CAAC;AAEvD,YAAM,WAAW,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AAEtC,YAAI,SAAS,WAAW,KAAK;AAC3B,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAO;AAAA,cACL,qBAAqB;AAAA,cACrB,yBAAyB,GAAG;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,mCAAmC,SAAS,MAAM,MAAM,SAAS;AAAA,YACjE;AAAA,YACA,EAAE,QAAQ,SAAS,QAAQ,IAAI;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAgBlC,YAAM,QAAyB,KAAK,MAAM,IAAI,CAAC,UAAU;AAAA,QACvD,KAAK,KAAK;AAAA,QACV,aAAa,KAAK;AAAA,QAClB,cAAc,KAAK;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,QAAQ,IAAI,KAAK,KAAK,MAAM;AAAA,QAC5B,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,IAAI;AAAA,QACvD,WAAW,KAAK;AAAA,QAChB,oBAAoB,KAAK;AAAA,MAC3B,EAAE;AAEF,aAAO,EAAE,IAAI,MAAM,MAAM,MAAM;AAAA,IACjC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB,yCAAyC,OAAO,KAAK,CAAC;AAAA,UACtD,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,gBAAgB,MAAc,QAA0C;AAC5E,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAE5C,YAAM,WAAW,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAEhB,YAAI,SAAS,WAAW,KAAK;AAC3B,iBAAO,EAAE,IAAI,MAAM,MAAM,MAAM;AAAA,QACjC;AAEA,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,+BAA+B,SAAS,MAAM,MAAM,SAAS;AAAA,YAC7D;AAAA,YACA,EAAE,QAAQ,SAAS,QAAQ,MAAM,OAAO;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,aAAO,EAAE,IAAI,MAAM,MAAM,KAAK,QAAQ;AAAA,IACxC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,qBAAqB;AAAA,UACrB,0CAA0C,OAAO,KAAK,CAAC;AAAA,UACvD,iBAAiB,QAAQ,QAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5mBA,IAAAC,cAAkB;AA6BX,IAAM,yBAAyB,cAAE,OAAO;AAAA;AAAA,EAE7C,KAAK,UAAU;AAAA,IACb,CAAC,QAAQ,OAAO,IAAI,MAAM,YAAY,IAAI,EAAE,SAAS;AAAA,IACrD,EAAE,SAAS,6CAA6C;AAAA,EAC1D;AAAA;AAAA,EAEA,QAAQ,cAAE,OAAO,EAAE,IAAI,GAAG,oBAAoB;AAAA;AAAA,EAE9C,YAAY;AAAA;AAAA,EAEZ,MAAM,cAAE,OAAO,EAAE,IAAI,GAAG,kBAAkB;AAAA;AAAA,EAE1C,MAAM,cAAE,OAAO,EAAE,IAAI,0BAA0B;AAAA;AAAA,EAE/C,SAAS,cAAE,OAAO,EAAE,IAAI,GAAG,qBAAqB;AAAA;AAAA,EAEhD,SAAS,cAAE,QAAQ,CAAC;AACtB,CAAC;AAWM,IAAM,uBAAuB,cAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3C,iBAAiB,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtC,eAAe,cAAE,QAAQ,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAIpC,eAAe,oBAAoB,SAAS;AAC9C,CAAC;AAeM,IAAM,6BAA6B,cAAE,OAAO;AAAA;AAAA,EAEjD,OAAO,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,mCAAmC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3E,SAAS,cACN,QAAQ,EACR;AAAA,IACC,CAAC,QACC,QAAQ,UAAc,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACvD,EAAE,SAAS,gDAAgD;AAAA,EAC7D,EACC,SAAS;AAAA;AAAA,EAEZ,QAAQ,cACL,QAAQ,EACR,OAAO,CAAC,QAA+B,OAAO,QAAQ,YAAY;AAAA,IACjE,SAAS;AAAA,EACX,CAAC;AAAA;AAAA,EAEH,OAAO,cACJ,QAAQ,EACR;AAAA,IACC,CAAC,QACC,QAAQ,UAAa,OAAO,QAAQ;AAAA,IACtC,EAAE,SAAS,yCAAyC;AAAA,EACtD,EACC,SAAS;AAAA;AAAA,EAEZ,aAAa;AAAA;AAAA,EAEb,UAAU,cACP,QAAQ,EACR;AAAA,IACC,CAAC,QACC,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACjC,EAAE,SAAS,4CAA4C;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAKF,mBAAmB,cAChB,QAAQ,EACR;AAAA,IACC,CAAC,QACC,QAAQ,UAAc,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACvD,EAAE,SAAS,mDAAmD;AAAA,EAChE,EACC,SAAS;AAAA;AAAA,EAEZ,iBAAiB,cAAE,QAAQ,EAAE;AAAA,IAC3B,CAAC,QAMmB,OAAO,QAAQ;AAAA,IACnC,EAAE,SAAS,8CAA8C;AAAA,EAC3D;AAAA;AAAA,EAEA,SAAS,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAI7B,kBAAkB,cACf,QAAQ,EACR,OAAO,CAAC,QAAQ,QAAQ,UAAa,OAAO,QAAQ,YAAY;AAAA,IAC/D,SAAS;AAAA,EACX,CAAC,EACA,SAAS;AAAA;AAAA;AAAA;AAAA,EAIZ,sBAAsB,cACnB,QAAQ,EACR,OAAO,CAAC,QAAQ,QAAQ,UAAa,OAAO,QAAQ,YAAY;AAAA,IAC/D,SAAS;AAAA,EACX,CAAC,EACA,SAAS;AAAA;AAAA;AAAA;AAAA,EAIZ,YAAY,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAIhC,eAAe,cAAE,KAAK,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjC,wBAAwB,cACrB,QAAQ,EACR,OAAO,CAAC,QAAQ,QAAQ,UAAa,OAAO,QAAQ,YAAY;AAAA,IAC/D,SAAS;AAAA,EACX,CAAC,EACA,SAAS;AACd,CAAC;AAwBM,SAAS,yBACd,MAC2C;AAC3C,QAAM,SAAS,uBAAuB,UAAU,IAAI;AACpD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM,qBAAqB;AAAA,QAC3B,SAAS,uBAAuB,OAAO,MAAM,OAAO;AAAA,QACpD,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACvC;;;AC9NA,gBAAe;AAmKR,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACjD,YAAY,SAAiB;AAC3B,UAAM,+BAA+B,OAAO,EAAE;AAC9C,SAAK,OAAO;AAAA,EACd;AACF;AAUO,IAAM,iBAAiB;AAKvB,IAAM,mBAAqC;AAQ3C,IAAM,wBACX,OAAO,OAAO;AAAA,EACZ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO;AACT,CAAC;AAKI,IAAM,wBACX,OAAO;AAAA,EACL,OAAO;AAAA,IACL,OAAO,QAAQ,qBAAqB,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAAA,EAC9D;AACF;AAQF,IAAM,2BACJ;AAAA,EACE;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,OAAO,OAAO,OAAO,QAAQ,UAAU;AAAA,EACnD;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,OAAO;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,MAAM;AAAA,EAClB;AACF;AAMF,IAAM,wBAAwE;AAAA,EAC5E;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,OAAO,OAAO,OAAO,QAAQ,UAAU;AAAA,EACnD;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS,KAAK;AAAA,EAClC;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,OAAO;AAAA,EAC3B;AACF;AAQA,IAAM,sBAAsE;AAAA,EAC1E;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,OAAO,OAAO,OAAO,QAAQ,UAAU;AAAA,EACnD;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS,KAAK;AAAA,EAClC;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,OAAO;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,OAAO;AAAA,EAC3B;AACF;AAaO,SAAS,YAAY,UAA0B;AACpD,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GAAG;AACzD,UAAM,IAAI;AAAA,MACR,mDAAmD,KAAK,UAAU,QAAQ,CAAC;AAAA,IAC7E;AAAA,EACF;AAGA,QAAM,aAAU,UAAAC;AAAA,IACd;AAAA,EACF;AACA,MAAI,OAAO,WAAW,YAAY,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG;AACzE,UAAM,IAAI;AAAA,MACR,4BAA4B,KAAK,UAAU,QAAQ,CAAC;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AACT;AAYO,SAAS,uBACd,SACA,SACU;AACV,SAAO,QAAQ,IAAI,CAAC,MAAM;AACxB,QAAI,EAAE,SAAS,GAAG,GAAG;AAEnB,aAAO;AAAA,IACT;AACA,WAAO,GAAG,OAAO,IAAI,CAAC;AAAA,EACxB,CAAC;AACH;AAUO,SAAS,YACd,QACA,MACA,YACQ;AACR,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AACA,MAAI,WAAW,IAAI;AACjB,WAAO;AAAA,EACT;AACA,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,WAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EACzB;AACA,SAAO,GAAG,MAAM,IAAI,IAAI;AAC1B;AAWA,eAAsB,aAAa,KAAgC;AACjE,QAAM,UAAqC,WAAwC;AACnF,MAAI,OAAO,YAAY,YAAY;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,MAAM,MAAM,QAAQ,GAAG;AAC7B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI;AAAA,MACR,iCAAiC,GAAG,UAAU,IAAI,MAAM;AAAA,IAC1D;AAAA,EACF;AACA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,SAAO,iBAAiB,IAAI;AAC9B;AAMO,SAAS,iBAAiB,OAA0B;AACzD,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,IAAI,wBAAwB,4BAA4B;AAAA,EAChE;AACA,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,OAAO,YAAY,EAAE,GAAG,WAAW,GAAG;AACjD,UAAM,IAAI,wBAAwB,wDAAwD;AAAA,EAC5F;AACA,MAAI,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,WAAW,GAAG;AACrD,UAAM,IAAI,wBAAwB,0DAA0D;AAAA,EAC9F;AACA,MAAI,EAAE,WAAW,QAAW;AAE1B,gBAAY,EAAE,MAAM;AAAA,EACtB;AACA,MAAI,EAAE,gBAAgB,QAAW;AAC/B,QAAI,CAAC,MAAM,QAAQ,EAAE,WAAW,GAAG;AACjC,YAAM,IAAI,wBAAwB,uCAAuC;AAAA,IAC3E;AACA,MAAE,YAAY;AAAA,MAAQ,CAAC,GAAG,MACxB,wBAAwB,GAAG,eAAe,CAAC,GAAG;AAAA,IAChD;AAAA,EACF;AACA,MAAI,EAAE,gBAAgB,QAAW;AAC/B,QAAI,CAAC,MAAM,QAAQ,EAAE,WAAW,GAAG;AACjC,YAAM,IAAI,wBAAwB,uCAAuC;AAAA,IAC3E;AACA,MAAE,YAAY,QAAQ,CAAC,GAAG,MAAM;AAC9B,UAAI,OAAO,GAAG,OAAO,YAAY,EAAE,GAAG,WAAW,GAAG;AAClD,cAAM,IAAI;AAAA,UACR,eAAe,CAAC;AAAA,QAClB;AAAA,MACF;AACA,UAAI,EAAE,WAAW,QAAW;AAC1B,oBAAY,EAAE,MAAM;AAAA,MACtB;AACA,UAAI,CAAC,MAAM,QAAQ,EAAE,WAAW,GAAG;AACjC,cAAM,IAAI;AAAA,UACR,eAAe,CAAC;AAAA,QAClB;AAAA,MACF;AACA,QAAE,YAAY;AAAA,QAAQ,CAAC,GAAG,MACxB,wBAAwB,GAAG,eAAe,CAAC,iBAAiB,CAAC,GAAG;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,GAAY,MAAoB;AAC/D,MAAI,MAAM,QAAQ,OAAO,MAAM,UAAU;AACvC,UAAM,IAAI,wBAAwB,GAAG,IAAI,oBAAoB;AAAA,EAC/D;AACA,QAAM,QAAQ;AACd,MAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,WAAW,GAAG;AACnE,UAAM,IAAI,wBAAwB,GAAG,IAAI,sBAAsB;AAAA,EACjE;AACA,MAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAW,GAAG;AAC/D,UAAM,IAAI,wBAAwB,GAAG,IAAI,oBAAoB;AAAA,EAC/D;AACA,MAAI,OAAO,MAAM,SAAS,UAAU;AAClC,UAAM,IAAI;AAAA,MACR,GAAG,IAAI;AAAA,IACT;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,WAAW,GAAG;AAC/D,UAAM,IAAI;AAAA,MACR,GAAG,IAAI;AAAA,IACT;AAAA,EACF;AACA,MAAI,MAAM,WAAW,QAAW;AAC9B,gBAAY,MAAM,MAAM;AAAA,EAC1B;AACF;AAOO,SAAS,kBACd,OACkB;AAClB,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAE7B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,MAAI,eAAe,WAAW,eAAe,OAAO;AAClD,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAMA,SAAS,sBACP,MACmB;AACnB,MAAI,SAAS,OAAO;AAClB,WAAO,CAAC;AAAA,EACV;AACA,QAAM,SACJ,SAAS,UACL,wBACA,SAAS,QACP,sBACA;AACR,SAAO,OAAO,IAAI,CAAC,OAAO;AAAA,IACxB,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,IACT,MAAM,EAAE;AAAA,IACR,SAAS,CAAC,GAAG,EAAE,OAAO;AAAA,EACxB,EAAE;AACJ;AAcO,SAAS,gBACd,OACsB;AACtB,QAAM,WAAW,iBAAiB,KAAK;AAEvC,QAAM,SAAS,SAAS,WAAW,SAAY,SAAS,SAAS,SAAS;AAC1E,QAAM,WAAW,YAAY,SAAS,UAAU,cAAc;AAC9D,QAAM,qBAAqB,SAAS,sBAAsB;AAC1D,QAAM,OAAO,kBAAkB,SAAS,QAAQ;AAEhD,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,kBAAkB,SAAS,eAAe,CAAC;AAIjD,QAAM,aAAgC,CAAC,GAAG,gBAAgB,GAAG,eAAe;AAE5E,QAAM,YAAkC,WAAW;AAAA,IAAI,CAAC,UACtD,aAAa,OAAO,QAAQ,QAAQ;AAAA,EACtC;AAEA,QAAM,uBACJ,SAAS,eAAe,CAAC,GACzB,IAAI,CAAC,OAAO;AAAA,IACZ,KAAK,EAAE;AAAA,IACP,MAAM,EAAE;AAAA,IACR,UAAU,YAAY,EAAE,UAAU,SAAS,UAAU,cAAc;AAAA,IACnE,aAAa,EAAE,YAAY;AAAA,MAAI,CAAC,UAC9B;AAAA,QACE;AAAA,QACA;AAAA,QACA,YAAY,EAAE,UAAU,SAAS,UAAU,cAAc;AAAA,MAC3D;AAAA,IACF;AAAA,EACF,EAAE;AAEF,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,aACP,OACA,QACA,oBACoB;AACpB,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,MAAM;AAAA,IACN,MAAM,eAAe;AAAA,EACvB;AACA,QAAM,kBAAkB,uBAAuB,MAAM,SAAS,MAAM,OAAO;AAC3E,QAAM,gBACJ,MAAM,WAAW,SAAY,YAAY,MAAM,MAAM,IAAI;AAC3D,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,MAAM;AAAA,IACN,SAAS;AAAA;AAAA;AAAA;AAAA,IAIT,GAAI,kBAAkB,SAAY,EAAE,UAAU,cAAc,IAAI,CAAC;AAAA,EACnE;AACF;AA0CO,SAAS,mCACd,WACc;AACd,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,WAAW;AACzB,UAAM,eAAe,sBAAsB,EAAE,OAAO;AACpD,QAAI,iBAAiB,QAAW;AAC9B,YAAM,IAAI;AAAA,QACR,oBAAoB,EAAE,OAAO,mDAA8C,OAAO,KAAK,qBAAqB,EAAE,KAAK,IAAI,CAAC;AAAA,MAC1H;AAAA,IACF;AACA,QAAI,IAAI,YAAY,MAAM,QAAW;AACnC,UAAI,YAAY,IAAI,CAAC;AAAA,IACvB;AACA,UAAM,WAAW,IAAI,YAAY;AACjC,UAAM,WAAW,SAAS,EAAE,IAAI;AAChC,QAAI,aAAa,QAAW;AAE1B,eAAS,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO;AAAA,IAClC,OAAO;AAEL,YAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,iBAAW,UAAU,EAAE,SAAS;AAC9B,YAAI,CAAC,KAAK,IAAI,MAAM,GAAG;AACrB,mBAAS,KAAK,MAAM;AACpB,eAAK,IAAI,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAsBO,SAAS,uBACd,UACc;AACd,QAAM,MAA4B,CAAC,GAAG,SAAS,SAAS;AACxD,aAAW,YAAY,SAAS,qBAAqB;AACnD,eAAW,QAAQ,SAAS,aAAa;AACvC,UAAI,KAAK,IAAI;AAAA,IACf;AAAA,EACF;AACA,SAAO,mCAAmC,GAAG;AAC/C;;;ACnqBA,SAAS,gCACP,SACoB;AACpB,MAAI;AACJ,aAAW,UAAU,SAAS;AAC5B,UAAM,QAAQ,OAAO,QAAQ,GAAG;AAChC,QAAI,UAAU,GAAI,QAAO;AACzB,UAAM,cAAc,OAAO,MAAM,GAAG,KAAK;AACzC,UAAM,YAAY,sBAAsB,WAAW;AACnD,QAAI,cAAc,OAAW,QAAO;AACpC,QAAI,UAAU,QAAW;AACvB,cAAQ;AAAA,IACV,WAAW,UAAU,WAAW;AAC9B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AASA,IAAM,uBAAuB,CAAC,oBAAoB,uBAAuB;AAKzE,IAAM,oBAAoB,KAAK,KAAK,KAAK;AAKzC,IAAM,gBAAgB;AAStB,SAASC,aACP,MACA,SACA,OACA,MACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,gBAAgB,MAAsB;AAE7C,MAAI;AACJ,MAAI,OAAO,SAAS,aAAa;AAC/B,aAAS,KAAK,SAAS,mBAAmB,IAAI,CAAC,CAAC;AAAA,EAClD,WAAW,OAAO,WAAW,aAAa;AACxC,aAAS,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAAA,EACvD,OAAO;AACL,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAEA,SAAO,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACzE;AAKA,SAAS,gBAAgB,SAAyB;AAEhD,MAAI,SAAS,QAAQ,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAEzD,SAAO,OAAO,SAAS,GAAG;AACxB,cAAU;AAAA,EACZ;AAEA,MAAI,OAAO,SAAS,aAAa;AAC/B,WAAO,mBAAmB,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,EAChD,WAAW,OAAO,WAAW,aAAa;AACxC,WAAO,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,OAAO;AAAA,EACvD,OAAO;AACL,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACF;AAgOO,IAAM,iBAAN,MAAgD;AAAA;AAAA;AAAA;AAAA,EAmBrD,YAAY,QAA8B;AACxC,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO;AACtB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,SAAS,WAAW,MAAM,KAAK,UAAU;AAC/D,SAAK,cAAc,OAAO;AAC1B,SAAK,WAAW,OAAO;AACvB,SAAK,oBAAoB,OAAO;AAChC,SAAK,kBAAkB,OAAO;AAC9B,SAAK,WAAW,OAAO,WAAW,IAAI,QAAQ,OAAO,EAAE;AACvD,SAAK,qBAAqB,OAAO;AACjC,SAAK,yBAAyB,OAAO;AACrC,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,gBAAgB,OAAO;AAC5B,SAAK,yBAAyB,OAAO;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,OAAe;AACzB,WAAO,KAAK,MAAM,CAAC;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKO,cAAc,SAA+B;AAClD,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,aAAa,QAA+K;AACjM,QAAI,OAAO,YAAY,QAAW;AAChC,WAAK,UAAU,OAAO;AAAA,IACxB;AACA,QAAI,OAAO,sBAAsB,QAAW;AAC1C,WAAK,oBAAoB,OAAO;AAAA,IAClC;AACA,QAAI,OAAO,qBAAqB,QAAW;AACzC,WAAK,qBAAqB,OAAO;AAAA,IACnC;AACA,QAAI,OAAO,yBAAyB,QAAW;AAC7C,WAAK,yBAAyB,OAAO;AAAA,IACvC;AACA,QAAI,OAAO,kBAAkB,QAAW;AACtC,WAAK,gBAAgB,OAAO;AAAA,IAC9B;AACA,QAAI,OAAO,2BAA2B,QAAW;AAC/C,WAAK,yBAAyB,OAAO;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,SAAS,QAA0E;AAEvF,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,0BAA0B,CAAC,KAAK,sBAAsB,CAAC,KAAK,mBAAmB;AACvF,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,OAAO,MAAM;AAChB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,OAAO,WAAW;AAClC,UAAM,kBAAkB,OAAO,UAAU,IAAI,KAAK,KAAK,IAAI,IAAI,iBAAiB;AAChF,QAAI,SAAS;AAEb,UAAM,SAAsB,OAAO,UAAU;AAI7C,UAAM,WAAW,KAAK,aAClB,GAAG,KAAK,UAAU,IAAI,OAAO,IAAI,GAAG,QAAQ,QAAQ,GAAG,IACvD,OAAO;AAGX,QAAI,WAAW,UAAU;AACvB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB,WAAW,MAAM;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAIA,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI;AACF,YAAM,eAAe,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC;AACvF,cAAQ,MAAM,KAAK,YAAY,iBAAiB,YAAY;AAC5D,eAAS,MAAM,KAAK,YAAY,OAAO,KAAK;AAC5C,eAAS,KAAK,YAAY,OAAO,KAAK;AAGtC,UAAI,CAAC,OAAO,GAAG;AACb,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAOA;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAASC,MAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOD;AAAA,UACL,qBAAqB;AAAA,UACrB,6CAA6CC,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG,CAAC;AAAA,UAC7FA,gBAAe,QAAQA,OAAM;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAIA,QAAI;AAGJ,UAAM,WAAW,OAAO,MAAM,GAAG,EAAE,CAAC;AAGpC,UAAM,yBAAyB,CAC7B,WACuD;AACvD,UAAI,UAAU,OAAO,WAAW,YAAY,QAAQ,QAAQ;AAC1D,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAOA,UAAM,yBAAyB,KAAK;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,wBAAwB;AAE1B,YAAM,mBAAmB,MAAM,KAAK,wBAAwB,UAAU,UAAU,SAAS,MAAM;AAC/F,YAAM,SAAS,uBAAuB,gBAAgB;AACtD,UAAI,QAAQ,UAAU,OAAO,OAAO,OAAO;AACzC,eAAO;AAAA,MACT;AACA,mBAAa;AAAA,IACf,WAAW,KAAK,wBAAwB;AAEtC,UAAI;AACF,cAAM,iBAAiB,MAAM,KAAK,uBAAuB;AAAA,UACvD,aAAa;AAAA,UACb,SAAS,KAAK,QAAQ;AAAA,UACtB,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACF,CAAC;AAED,YAAI,gBAAgB;AAClB,uBAAa;AACb,mBAAS;AAAA,QACX,OAAO;AAEL,gBAAM,iBAAiB,MAAM,KAAK,+BAA+B,eAAe;AAChF,mBAAS,eAAe;AACxB,gBAAM,mBAAmB,MAAM,KAAK,wBAAwB,UAAU,UAAU,SAAS,MAAM;AAC/F,gBAAM,SAAS,uBAAuB,gBAAgB;AACtD,cAAI,QAAQ,UAAU,OAAO,OAAO,OAAO;AACzC,mBAAO;AAAA,UACT;AACA,uBAAa;AAAA,QACf;AAAA,MACF,SAASA,MAAK;AAEZ,cAAM,iBAAiB,MAAM,KAAK,+BAA+B,eAAe;AAChF,iBAAS,eAAe;AACxB,cAAM,mBAAmB,MAAM,KAAK,wBAAwB,UAAU,UAAU,SAAS,MAAM;AAC/F,cAAM,SAAS,uBAAuB,gBAAgB;AACtD,YAAI,QAAQ,UAAU,OAAO,OAAO,OAAO;AACzC,iBAAO;AAAA,QACT;AACA,qBAAa;AAAA,MACf;AAAA,IACF,OAAO;AAEL,YAAM,iBAAiB,MAAM,KAAK,+BAA+B,eAAe;AAChF,eAAS,eAAe;AACxB,YAAM,mBAAmB,MAAM,KAAK,wBAAwB,UAAU,UAAU,SAAS,MAAM;AAC/F,YAAM,SAAS,uBAAuB,gBAAgB;AACtD,UAAI,QAAQ,UAAU,OAAO,OAAO,OAAO;AACzC,eAAO;AAAA,MACT;AACA,mBAAa;AAAA,IACf;AAGA,UAAM,YAA8B;AAAA,MAClC,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,SAAS,KAAK,QAAQ;AAAA,MACtB,SAAS;AAAA,IACX;AAGA,UAAM,cAAc,KAAK,WAAW,WAAW,MAAM;AAGrD,UAAM,UAAU,OAAO,WAAW,KAAK;AACvC,UAAM,MAAM,UAAU,GAAG,OAAO,UAAU,WAAW,KAAK;AAE1D,UAAM,YAAuB;AAAA,MAC3B,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa,OAAO;AAAA,IACtB;AAEA,WAAO,EAAE,IAAI,MAAM,MAAM,UAAU;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,6BACN,MACA,SACA,iBACS;AAET,QAAI,KAAK,iBAAiB,mBAAmB,KAAK,eAAe;AAC/D,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,KAAK,SAAS,WAAW;AACzC,eAAW,OAAO,SAAS;AACzB,YAAM,cAAc,KAAK,SAAS,qBAAqB,IAAI,EAAE;AAC7D,iBAAW,cAAc,aAAa;AAEpC,YAAI,CAAC,KAAK,SAAS,kBAAkB,UAAU,GAAG;AAChD;AAAA,QACF;AAGA,YAAI,WAAW,SAAS,iBAAiB;AACvC;AAAA,QACF;AAGA,YAAI,WAAW,uBAAuB,OAAO;AAC3C;AAAA,QACF;AAGA,cAAM,iBAAiB,WAAW,QAAQ;AAC1C,YAAI,CAAC,KAAK,YAAY,gBAAgB,IAAI,GAAG;AAC3C;AAAA,QACF;AAGA,cAAM,oBAAoB,WAAW,WAAW,CAAC;AACjD,cAAM,gBAAgB,QAAQ;AAAA,UAAM,YAClC,kBAAkB,SAAS,MAAM,KAAK,kBAAkB,SAAS,GAAG;AAAA,QACtE;AACA,YAAI,CAAC,eAAe;AAClB;AAAA,QACF;AAGA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,YAAY,gBAAwB,eAAgC;AAE1E,QAAI,mBAAmB,MAAM,mBAAmB,KAAK;AACnD,aAAO;AAAA,IACT;AAGA,QAAI,mBAAmB,eAAe;AACpC,aAAO;AAAA,IACT;AAGA,UAAM,uBAAuB,eAAe,QAAQ,OAAO,EAAE;AAC7D,UAAM,oBAAoB,cAAc,QAAQ,OAAO,EAAE;AAEzD,QAAI,kBAAkB,WAAW,uBAAuB,GAAG,GAAG;AAC5D,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,+BAA+B,iBAAkD;AAE7F,WAAO,EAAE,QAAQ,KAAK,iBAAiB,gBAAgB;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,wBACZ,aACA,MACA,SACA,QACsD;AACtD,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOD;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,wBAAwB;AAc/B,UAAI;AACF,YAAI,QAAQ,WAAW,GAAG;AACxB,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAOA;AAAA,cACL,qBAAqB;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,eAAe,gCAAgC,OAAO;AAC5D,YAAI,iBAAiB,QAAW;AAC9B,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAOA;AAAA,cACL,qBAAqB;AAAA,cACrB,uDAAuD,KAAK,UAAU,OAAO,CAAC;AAAA,YAChF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,aAAa,KAAK,uBAAuB;AAAA,UAC7C,SAAS,KAAK;AAAA,UACd;AAAA,UACA,SAAS,KAAK,QAAQ;AAAA,UACtB,WAAW;AAAA,YACT,CAAC,YAAY,GAAG;AAAA,cACd,CAAC,IAAI,GAAG,CAAC,GAAG,OAAO;AAAA,YACrB;AAAA,UACF;AAAA,UACA,gBAAgB,KAAK,MAAM,OAAO,QAAQ,IAAI,GAAI;AAAA,QACpD,CAAC;AAGD,cAAM,cAAc,MAAM,KAAK,QAAQ,GAAG,KAAK,IAAI,aAAa;AAAA,UAC9D,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,eAAe,WAAW;AAAA,UAC5B;AAAA,QACF,CAAC;AAED,YAAI,CAAC,YAAY,IAAI;AACnB,gBAAM,YAAY,MAAM,YAAY,KAAK;AACzC,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAOA;AAAA,cACL,qBAAqB;AAAA,cACrB,8CAA8C,YAAY,MAAM,IAAI,SAAS;AAAA,YAC/E;AAAA,UACF;AAAA,QACF;AAOA,YAAI,WAAW,UAAU,WAAW,GAAG;AACrC,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,OAAOA;AAAA,cACL,qBAAqB;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,UAAU,WAAW,UAAU,CAAC;AACtC,eAAO;AAAA,UACL,KAAK,WAAW;AAAA,UAChB,aAAa,WAAW;AAAA,UACxB,SAAS,KAAK,QAAQ;AAAA,UACtB,MAAM,QAAQ;AAAA,UACd,SAAS,QAAQ;AAAA,UACjB,QAAQ,WAAW;AAAA,UACnB,WAAW;AAAA,UACX,YAAY,WAAW;AAAA,UACvB,oBAAoB;AAAA,UACpB,WAAW,oBAAI,KAAK;AAAA,QACtB;AAAA,MACF,SAASC,MAAK;AACZ,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAOD;AAAA,YACL,qBAAqB;AAAA,YACrB,yCAAyCC,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG,CAAC;AAAA,YACzFA,gBAAe,QAAQA,OAAM;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,mBAA2C;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,sBAAsB;AAAA,MACxB;AAEA,YAAM,mBAAmB,KAAK,qBAC1B,MAAM,KAAK,mBAAmB,gBAAgB,IAC9C,MAAM,KAAK,kBAAmB,OAAO,gBAAgB;AAEzD,UAAI,CAAC,iBAAiB,IAAI;AACxB,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAOD;AAAA,YACL,qBAAqB;AAAA,YACrB,0CAA0C,iBAAiB,MAAM,OAAO;AAAA,YACxE,iBAAiB,MAAM;AAAA,YACvB,iBAAiB,MAAM;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAEA,aAAO,iBAAiB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QACJ,MACA,UAA0B,CAAC,GACoB;AAC/C,UAAM;AAAA,MACJ,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB;AAAA,IACF,IAAI;AAGJ,UAAM,eAAe,KAAK,yBAAyB,IAAI;AACvD,QAAI,CAAC,aAAa,IAAI;AACpB,aAAO;AAAA,IACT;AACA,UAAM,YAAY,aAAa;AAM/B,UAAM,mBAAmB,IAAI,KAAK,UAAU,WAAW,MAAM;AAC7D,QAAI,mBAAmB,oBAAI,KAAK,GAAG;AACjC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,UAAU,WAAW,WAAW;AAClC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAmB;AAAA,MACvB,IAAI,YAAY,UAAU,MAAM;AAAA,MAChC,KAAK,UAAU;AAAA,MACf,MAAM;AAAA,MACN,KAAK,UAAU;AAAA,MACf,UAAU;AAAA;AAAA,IACZ;AAEA,SAAK,SAAS,UAAU,SAAS,UAAU,YAAY,aAAa;AAGpE,QAAI,mBAAmB,UAAU;AACjC,QAAI,YAAY;AAGhB,QAAI,mBAAmB,iBAAiB,KAAK,SAAS;AACpD,UAAI;AAAA,MAYJ,SAASC,MAAK;AAEZ,gBAAQ,KAAK,2DAA2DA,IAAG;AAAA,MAC7E;AAAA,IACF;AAKA,UAAM,aAAa,UAAU,WAAW,cAAc,UAAU,UAAU,WAAW,GAAG;AACxF,UAAM,eAA+B;AAAA,MACnC,kBAAkB,EAAE,eAAe,WAAW;AAAA,MAC9C,eAAe,UAAU,WAAW;AAAA,MACpC,SAAS,UAAU;AAAA,MACnB,oBAAoB,UAAU;AAAA,MAC9B,KAAK,UAAU;AAAA,IACjB;AAEA,UAAM,YAAY,KAAK,gBAAgB;AAAA,MACrC,OAAO,CAAC,UAAU,IAAI;AAAA,MACtB,SAAS;AAAA,MACT,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,YAAY,UAAU;AAAA,IACxB,CAAC;AAED,UAAM,cAA2B;AAAA,MAC/B,YAAY;AAAA,MACZ,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,SAAS,UAAU;AAAA,MACnB,MAAM,UAAU;AAAA,IAClB;AAEA,WAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,MAAwB,SAAsB,UAAkB;AACzE,QAAI,WAAW,UAAU;AACvB,YAAM,IAAI,MAAM,WAAW,MAAM,gDAAgD;AAAA,IACnF;AAEA,UAAM,aAAa,KAAK,UAAU,IAAI;AACtC,UAAM,UAAU,gBAAgB,UAAU;AAC1C,WAAO,GAAG,aAAa,GAAG,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,MAAgC;AACzC,UAAM,SAAS,KAAK,yBAAyB,IAAI;AACjD,QAAI,CAAC,OAAO,IAAI;AACd,YAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAAA,IACtC;AACA,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,yBAAyB,MAAyD;AAExF,QAAI,UAAU;AAGd,QAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,YAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,gBAAU,MAAM,MAAM,SAAS,CAAC;AAAA,IAClC;AAGA,QAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,UAAI;AACF,cAAM,MAAM,IAAI,IAAI,IAAI;AACxB,kBAAU,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,MAC7C,QAAQ;AACN,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAOD;AAAA,YACL,qBAAqB;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,WAAW,aAAa,GAAG;AACtC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOA;AAAA,UACL,qBAAqB;AAAA,UACrB,iDAAiD,aAAa;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,QAAQ,MAAM,cAAc,MAAM;AAErD,QAAI;AACJ,QAAI;AACF,mBAAa,gBAAgB,UAAU;AAAA,IACzC,SAASC,MAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOD;AAAA,UACL,qBAAqB;AAAA,UACrB,iCAAiCC,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG,CAAC;AAAA,UACjFA,gBAAe,QAAQA,OAAM;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,UAAU;AAAA,IAChC,SAASA,MAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOD;AAAA,UACL,qBAAqB;AAAA,UACrB,oCAAoCC,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG,CAAC;AAAA,UACpFA,gBAAe,QAAQA,OAAM;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAIA,QACE,UACA,OAAO,WAAW,YAClB,gBAAgB,UAChB,OAAO,cACP,OAAO,OAAO,eAAe,YAC7B,YAAY,OAAO,cACnB,OAAO,OAAO,WAAW,WAAW,UACpC;AACA,MAAC,OAAO,WAAgC,SAAS,IAAI,KAAK,OAAO,WAAW,MAAM;AAAA,IACpF;AAGA,UAAM,mBAAmB,yBAAyB,MAAM;AACxD,QAAI,CAAC,iBAAiB,IAAI;AACxB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAOD;AAAA,UACL,qBAAqB;AAAA,UACrB,iBAAiB,MAAM;AAAA,UACvB;AAAA,UACA,iBAAiB,MAAM;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,IAAI,MAAM,MAAM,iBAAiB,KAAK;AAAA,EACjD;AACF;AAKO,SAAS,qBAAqB,QAA+C;AAClF,SAAO,IAAI,eAAe,MAAM;AAClC;;;ACvpCA,IAAAE,uBAAsC;AAYtC,IAAMC,gBAAe;AASd,IAAM,kCAAkC;AAAA;AAAA,EAE7C,eAAe;AAAA;AAAA,EAEf,gBAAgB;AAAA;AAAA,EAEhB,oBAAoB;AAAA;AAAA,EAEpB,oBAAoB;AAAA;AAAA,EAEpB,oBAAoB;AAAA;AAAA,EAEpB,YAAY;AACd;AAkLO,IAAM,wBAAN,MAA8D;AAAA,EAA9D;AAIL;AAAA;AAAA;AAAA,SAAQ,OAA6B,oBAAI,IAAI;AAK7C;AAAA;AAAA;AAAA,SAAQ,QAAyB;AAAA,MAC/B,OAAO,oBAAI,IAAI;AAAA,MACf,OAAO,oBAAI,IAAI;AAAA,MACf,cAAc,oBAAI,IAAI;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,KAAc,aAAiC;AAEzD,SAAK,KAAK,IAAI,IAAI,IAAI,GAAG;AAGzB,QAAI,CAAC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,GAAG;AACjC,WAAK,MAAM,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC;AAAA,IACjC;AAGA,eAAW,cAAc,aAAa;AACpC,WAAK,cAAc,KAAK,UAAU;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,OAAqB;AAE7B,UAAM,cAAc,KAAK,MAAM,MAAM,IAAI,KAAK,KAAK,CAAC;AAGpD,eAAW,cAAc,aAAa;AACpC,WAAK,MAAM,MAAM,OAAO,WAAW,GAAG;AAAA,IACxC;AAGA,eAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,MAAM,cAAc;AACvD,YAAM,WAAW,QAAQ;AAAA,QACvB,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,MAAe,EAAE,OAAO,KAAK;AAAA,MAC5D;AACA,UAAI,SAAS,WAAW,GAAG;AACzB,aAAK,MAAM,aAAa,OAAO,MAAM;AAAA,MACvC,OAAO;AAEL,mBAAW,SAAS,UAAU;AAC5B,gBAAM,OAAO,MAAM,KAAK,OAAO,CAAC,MAAe,EAAE,OAAO,KAAK;AAAA,QAC/D;AACA,aAAK,MAAM,aAAa,IAAI,QAAQ,SAAS,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC;AAAA,MAC/E;AAAA,IACF;AAGA,SAAK,MAAM,MAAM,OAAO,KAAK;AAG7B,SAAK,KAAK,OAAO,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,oBAAoB,UAAkB,QAAgC;AAEpE,UAAM,kBAAkB,KAAK,oBAAoB,UAAU,MAAM;AAEjE,QAAI,gBAAgB,WAAW,GAAG;AAChC,aAAO;AAAA,IACT;AAGA,UAAM,YAAuB,CAAC;AAE9B,eAAW,SAAS,iBAAiB;AAEnC,UAAI,CAAC,KAAK,kBAAkB,MAAM,UAAU,GAAG;AAC7C;AAAA,MACF;AAGA,iBAAW,OAAO,MAAM,MAAM;AAC5B,YAAI,CAAC,UAAU,KAAK,CAAC,MAAe,EAAE,OAAO,IAAI,EAAE,GAAG;AACpD,oBAAU,KAAK,GAAG;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO;AAAA,IACT;AAGA,cAAU,KAAK,CAAC,GAAY,MAAe,EAAE,WAAW,EAAE,QAAQ;AAElE,WAAO,UAAU,CAAC;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,qBAAwC;AACtC,UAAM,MAAyB,CAAC;AAChC,eAAW,WAAW,KAAK,MAAM,aAAa,OAAO,GAAG;AACtD,UAAI,KAAK,GAAG,OAAO;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,qBAAqB,OAA6B;AAChD,WAAO,KAAK,MAAM,MAAM,IAAI,KAAK,KAAK,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,UACE,KACA,YACA,SACM;AAEN,UAAM,aAAsB,SAAS,aAAa,SAC9C,EAAE,GAAG,KAAK,UAAU,QAAQ,SAAS,IACrC;AAGJ,SAAK,KAAK,IAAI,WAAW,IAAI,UAAU;AAGvC,QAAI,CAAC,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,GAAG;AACxC,WAAK,MAAM,MAAM,IAAI,WAAW,IAAI,CAAC,CAAC;AAAA,IACxC;AAGA,SAAK,cAAc,YAAY,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,kBAAkB,YAAiC;AAEjD,QAAI,WAAW,WAAW;AACxB,aAAO;AAAA,IACT;AAGA,UAAM,MAAM,oBAAI,KAAK;AACrB,QAAI,WAAW,UAAU,WAAW,SAAS,KAAK;AAChD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,OAAoC;AACzC,WAAO,KAAK,KAAK,IAAI,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAwB;AACtB,WAAO,MAAM,KAAK,KAAK,KAAK,OAAO,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAc;AACZ,SAAK,KAAK,MAAM;AAChB,SAAK,MAAM,MAAM,MAAM;AACvB,SAAK,MAAM,MAAM,MAAM;AACvB,SAAK,MAAM,aAAa,MAAM;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,iBAAiB,KAAyC;AACxD,UAAM,SAAS,KAAK,MAAM,MAAM,IAAI,GAAG;AAEvC,QAAI,CAAC,QAAQ;AACX,iBAAO;AAAA,YACL;AAAA,UACE,gCAAgC;AAAA,UAChC,yBAAyB,GAAG;AAAA,UAC5BA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,WAAO,WAAW,YAAY;AAG9B,UAAM,iBAAiB,KAAK,MAAM,MAAM,IAAI,OAAO,KAAK;AACxD,QAAI,gBAAgB;AAClB,YAAM,aAAa,eAAe,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAC3D,UAAI,YAAY;AACd,mBAAW,YAAY;AAAA,MACzB;AAAA,IACF;AAGA,eAAW,WAAW,KAAK,MAAM,aAAa,OAAO,GAAG;AACtD,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,WAAW,QAAQ,KAAK;AAChC,gBAAM,WAAW,YAAY;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,eAAO,yBAAG,MAAS;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,iBACE,iBACA,QACmB;AACnB,UAAM,UAA6B,CAAC;AAEpC,eAAW,WAAW,KAAK,MAAM,aAAa,OAAO,GAAG;AACtD,iBAAW,SAAS,SAAS;AAE3B,YAAI,UAAU,MAAM,WAAW,QAAQ;AACrC;AAAA,QACF;AAGA,YAAI,KAAK,uBAAuB,MAAM,UAAU,eAAe,GAAG;AAChE,kBAAQ,KAAK,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,cAAc,KAAc,YAA8B;AAEhE,UAAM,iBAAiB,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,KAAK,CAAC;AACxD,QAAI,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW,GAAG,GAAG;AACzD,qBAAe,KAAK,UAAU;AAC9B,WAAK,MAAM,MAAM,IAAI,IAAI,IAAI,cAAc;AAAA,IAC7C;AAGA,QAAI,CAAC,KAAK,MAAM,MAAM,IAAI,WAAW,GAAG,GAAG;AACzC,WAAK,MAAM,MAAM,IAAI,WAAW,KAAK;AAAA,QACnC;AAAA,QACA,WAAW,WAAW;AAAA,QACtB,OAAO,IAAI;AAAA,QACX,UAAU,oBAAI,KAAK;AAAA,MACrB,CAAC;AAAA,IACH;AAGA,eAAW,UAAU,WAAW,SAAS;AACvC,YAAM,SAAS,KAAK,kBAAkB,WAAW,MAAM,MAAM;AAC7D,YAAM,UAAU,KAAK,MAAM,aAAa,IAAI,MAAM,KAAK,CAAC;AAGxD,YAAM,gBAAgB,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,WAAW,GAAG;AAE7E,UAAI,eAAe;AAEjB,YAAI,CAAC,cAAc,KAAK,KAAK,CAAC,MAAe,EAAE,OAAO,IAAI,EAAE,GAAG;AAC7D,wBAAc,KAAK,KAAK,GAAG;AAE3B,wBAAc,KAAK,KAAK,CAAC,GAAY,MAAe,EAAE,WAAW,EAAE,QAAQ;AAAA,QAC7E;AAAA,MACF,OAAO;AAEL,cAAM,QAAyB;AAAA,UAC7B,UAAU,WAAW;AAAA,UACrB;AAAA,UACA,MAAM,CAAC,GAAG;AAAA,UACV;AAAA,UACA,WAAW,WAAW;AAAA,QACxB;AACA,gBAAQ,KAAK,KAAK;AAClB,aAAK,MAAM,aAAa,IAAI,QAAQ,OAAO;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAkB,UAAkB,QAAwB;AAClE,WAAO,GAAG,QAAQ,IAAI,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,oBACN,UACA,QACmB;AACnB,UAAM,UAA6B,CAAC;AAGpC,UAAM,WAAW,KAAK,kBAAkB,UAAU,MAAM;AACxD,UAAM,eAAe,KAAK,MAAM,aAAa,IAAI,QAAQ;AACzD,QAAI,cAAc;AAChB,cAAQ,KAAK,GAAG,YAAY;AAAA,IAC9B;AAGA,eAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,MAAM,cAAc;AACvD,UAAI,WAAW,SAAU;AAEzB,iBAAW,SAAS,SAAS;AAE3B,YAAI,CAAC,KAAK,cAAc,MAAM,QAAQ,MAAM,GAAG;AAC7C;AAAA,QACF;AAGA,YAAI,KAAK,uBAAuB,UAAU,MAAM,QAAQ,GAAG;AACzD,cAAI,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,MAAM,WAAW,GAAG,GAAG;AACnE,oBAAQ,KAAK,KAAK;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cAAc,SAAiB,QAAyB;AAE9D,QAAI,YAAY,QAAQ;AACtB,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,aAAO,OAAO,WAAW,SAAS,GAAG,KAAK,WAAW;AAAA,IACvD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,uBAAuB,UAAkB,SAA0B;AAEzE,QAAI,YAAY,UAAU;AACxB,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,SAAS,KAAK,GAAG;AAC3B,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,aAAO,SAAS,WAAW,MAAM;AAAA,IACnC;AAGA,QAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,UAAI,CAAC,SAAS,WAAW,MAAM,GAAG;AAChC,eAAO;AAAA,MACT;AACA,YAAM,YAAY,SAAS,MAAM,OAAO,MAAM;AAE9C,aAAO,CAAC,UAAU,SAAS,GAAG,KAAK,cAAc;AAAA,IACnD;AAGA,QAAI,QAAQ,SAAS,GAAG,KAAK,SAAS,WAAW,OAAO,GAAG;AACzD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBACN,eACA,eACS;AAET,WAAO,KAAK,uBAAuB,eAAe,aAAa,KACxD,KAAK,uBAAuB,eAAe,aAAa;AAAA,EACjE;AACF;AAOO,SAAS,8BAAsD;AACpE,SAAO,IAAI,sBAAsB;AACnC;;;ACrmBO,IAAM,sBAAoC,EAAE,MAAM,YAAY;;;ACvD9D,IAAM,kCAAN,MAAuE;AAAA;AAAA;AAAA;AAAA,EAI5E,MAAM,uBAAyC;AAC7C,WAAO;AAAA,EACT;AACF;AAKO,IAAM,8BACX,IAAI,gCAAgC;;;ACjG/B,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAE/C,YACkB,aACA,cACA,aACA,MAChB;AACA;AAAA,MACE,wBAAwB,WAAW,+CAA+C,YAAY,WAAW,WAAW,QAAQ,IAAI,QAC7H,cAAc,eACX,4BACA;AAAA,IACR;AAVgB;AACA;AACA;AACA;AALlB,gBAAO;AAAA,EAaP;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAE3C,YACkB,MACA,OAChB;AACA;AAAA,MACE,gCAAgC,IAAI;AAAA,IACtC;AALgB;AACA;AAHlB,gBAAO;AAAA,EAQP;AACF;AAEO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EAEjD,YACkB,SACA,MACA,mBAChB;AACA;AAAA,MACE,YAAY,OAAO,qCAAqC,IAAI,yBACnC,kBAAkB,KAAK,IAAI,KAAK,MAAM;AAAA,IACjE;AAPgB;AACA;AACA;AAJlB,gBAAO;AAAA,EAUP;AACF;AAOA,eAAsB,cACpB,MACA,aACA,UAAmC,WAAW,MAAM,KAAK,UAAU,GAChD;AACnB,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,QAAQ,GAAG,IAAI,SAAS;AAAA,MACvC,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AAAA,EACH,SAASC,MAAK;AACZ,UAAM,IAAI,kBAAkB,MAAMA,IAAY;AAAA,EAChD;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,kBAAkB,IAAI;AAAA,EAClC;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAOlC,MAAI,gBAAgB,KAAK,UAAU;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,KAAK,YAAY,CAAC;AAAA,IAC5B,UAAU,KAAK;AAAA,EACjB;AACF;;;AC7DO,IAAM,+BAAN,cAA2C,MAAM;AAAA,EAItD,YAAY,SAA4B,SAA4B;AAClE;AAAA,MACE,0DAA0D,QAAQ,MAAM;AAAA,IAC1E;AACA,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,EACjB;AACF;AAMO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAG7C,YAAY,WAAiB;AAC3B,UAAM,sBAAsB,UAAU,YAAY,CAAC,EAAE;AACrD,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AACF;AA0BO,SAAS,eAAe,OAAuB;AACpD,MAAI,CAAC,MAAM,WAAW,YAAY,GAAG;AACnC,WAAO;AAAA,EACT;AACA,QAAM,YAAY,MAAM,YAAY,GAAG;AACvC,MAAI,cAAc,MAAM,cAAc,MAAM,SAAS,GAAG;AACtD,WAAO;AAAA,EACT;AACA,SAAO,MAAM,MAAM,YAAY,CAAC;AAClC;AAiCO,SAAS,mBACd,WACA,SACmB;AACnB,QAAM,UAA6B,CAAC;AAEpC,aAAW,OAAO,WAAW;AAC3B,UAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,yBAAyB,KAAK,CAAC,CAAC;AAClE,QAAI,UAAU,QAAW;AACvB,cAAQ,KAAK,WAAW,GAAG,CAAC;AAC5B;AAAA,IACF;AAAA,EAEF;AAEA,SAAO,EAAE,QAAQ,QAAQ,WAAW,GAAG,QAAQ;AACjD;AAMA,SAAS,yBACP,WACA,SACS;AACT,MAAI,UAAU,YAAY,QAAQ,SAAS;AACzC,WAAO;AAAA,EACT;AAIA,MAAI,eAAe,UAAU,KAAK,MAAM,eAAe,QAAQ,KAAK,GAAG;AACrE,WAAO;AAAA,EACT;AACA,MAAI,CAAC,aAAa,QAAQ,MAAM,UAAU,IAAI,GAAG;AAC/C,WAAO;AAAA,EACT;AAIA,QAAM,aAAa,IAAI;AAAA,IACrB,uBAAuB,UAAU,SAAS,UAAU,OAAO;AAAA,EAC7D;AACA,QAAM,iBAAiB,IAAI;AAAA,IACzB,uBAAuB,QAAQ,SAAS,QAAQ,OAAO;AAAA,EACzD;AACA,aAAW,KAAK,YAAY;AAC1B,QAAI,CAAC,eAAe,IAAI,CAAC,GAAG;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAWA,SAAS,aAAa,aAAqB,eAAgC;AACzE,MAAI,gBAAgB,MAAM,gBAAgB,KAAK;AAC7C,WAAO;AAAA,EACT;AACA,MAAI,YAAY,SAAS,GAAG,GAAG;AAC7B,WAAO,cAAc,WAAW,WAAW;AAAA,EAC7C;AACA,SAAO,kBAAkB;AAC3B;AAEA,SAAS,WAAW,OAAyC;AAC3D,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ,SAAS,CAAC,GAAG,MAAM,OAAO;AAAA,IAC1B,GAAI,MAAM,eAAe,SAAY,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,IACzE,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,EAC/D;AACF;AA8CO,SAAS,uBACd,WACA,MACmB;AACnB,QAAM,MAAM,UAAU,IAAI;AAC1B,MAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,aAAgC,IAAI,IAAI,CAAC,UAAU;AACvD,UAAM,cACJ,sBAAsB,MAAM,OAAO;AAAA;AAAA;AAAA,KAIlC,MAAM,QAAQ,WAAW,YAAY,IAClC,MAAM,UACN,aAAa,MAAM,OAAO;AAChC,WAAO;AAAA,MACL,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,OAAO,eAAe,MAAM,KAAK;AAAA,MACjC,MAAM,MAAM;AAAA,MACZ,SAAS,CAAC,GAAG,MAAM,OAAO;AAAA,IAC5B;AAAA,EACF,CAAC;AAID,aAAW,KAAK,CAAC,GAAG,MAAM;AACxB,QAAI,EAAE,UAAU,EAAE,MAAO,QAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK;AACzD,QAAI,EAAE,YAAY,EAAE,QAAS,QAAO,EAAE,UAAU,EAAE,UAAU,KAAK;AACjE,QAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,KAAK;AACrD,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AACT;","names":["import_zod","EnsDataSchema","import_sdk_services","import_zod","import_zod","errorText","import_sdk_services","import_zod","ms","createError","err","import_sdk_services","SERVICE_NAME","err"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client-types.ts","../src/notifications.ts","../src/storage.schema.ts","../src/TinyCloud.ts","../src/spaces/SpaceService.ts","../src/spaces/Space.ts","../src/spaces/spaces.schema.ts","../src/delegations/types.schema.ts","../src/space.ts","../src/delegations/DelegationManager.ts","../src/delegations/SharingService.schema.ts","../src/manifest.ts","../src/delegations/SharingService.ts","../src/authorization/CapabilityKeyRegistry.ts","../src/authorization/strategies.ts","../src/authorization/spaceCreation.ts","../src/version.ts","../src/capabilities.ts"],"sourcesContent":["/**\n * @tinycloud/sdk-core\n *\n * Core TinyCloud SDK package providing shared interfaces and the TinyCloud class.\n *\n * This package defines the platform-agnostic interfaces that both web-sdk and node-sdk\n * implement. The main TinyCloud class accepts an IUserAuthorization implementation,\n * allowing it to work in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\n// Platform-agnostic client types (canonical definitions)\nexport {\n ClientSession,\n EnsData,\n SiweConfig,\n ServerHost,\n ClientSessionSchema,\n EnsDataSchema,\n SiweConfigSchema,\n validateClientSession,\n SiweMessage,\n} from \"./client-types\";\n\n// Notification handler\nexport {\n INotificationHandler,\n SilentNotificationHandler,\n} from \"./notifications\";\n\n// ENS resolver\nexport { IENSResolver } from \"./ens\";\n\n// WASM bindings abstraction\nexport { IWasmBindings, ISessionManager } from \"./wasm\";\n\n// Signer interface\nexport { ISigner, Bytes } from \"./signer\";\n\n// Session storage interface and types\nexport {\n // Interface\n ISessionStorage,\n // Types (derived from Zod schemas)\n PersistedSessionData,\n PersistedTinyCloudSession,\n TinyCloudSession,\n ValidationError,\n // Validation\n validatePersistedSessionData,\n} from \"./storage\";\n\n// User authorization interface and types\nexport {\n IUserAuthorization,\n Extension,\n PartialSiweMessage,\n UserAuthorizationConfig,\n} from \"./userAuthorization\";\nexport type { SignInOptions } from \"./userAuthorization\";\n\n// Main TinyCloud class\nexport { TinyCloud, TinyCloudConfig } from \"./TinyCloud\";\n\n// Re-export service types from sdk-services for convenience\nexport {\n // Context\n ServiceContext,\n type ServiceContextConfig,\n type IServiceContext,\n // Service types\n type IService,\n // KV Service\n KVService,\n PrefixedKVService,\n type IKVService,\n type IPrefixedKVService,\n type KVServiceConfig,\n type KVGetOptions,\n type KVPutOptions,\n type KVListOptions,\n type KVDeleteOptions,\n type KVHeadOptions,\n type KVResponse,\n type KVListResponse,\n type KVResponseHeaders,\n // Result pattern\n type Result,\n ok,\n err,\n serviceError,\n ErrorCodes,\n type ErrorCode,\n type ServiceError,\n // Session\n type ServiceSession,\n // Platform dependencies\n type InvokeFunction,\n type InvokeAnyFunction,\n type InvokeAnyEntry,\n type FetchFunction,\n // Retry\n type RetryPolicy,\n defaultRetryPolicy,\n // SQL Service\n SQLService,\n DatabaseHandle,\n SQLAction,\n type ISQLService,\n type IDatabaseHandle,\n type SQLServiceConfig,\n type SqlValue,\n type SqlStatement,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SQLActionType,\n // DuckDB Service\n DuckDbService,\n DuckDbDatabaseHandle,\n DuckDbAction,\n type IDuckDbService,\n type IDuckDbDatabaseHandle,\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type DuckDbQueryResponse,\n type DuckDbExecuteResponse,\n type DuckDbBatchResponse,\n type DuckDbActionType,\n type SchemaInfo,\n type TableInfo,\n type ColumnInfo,\n type ViewInfo,\n // Hooks Service\n HooksService,\n type IHooksService,\n type HookServiceName,\n type HookSubscription,\n type HookEvent,\n type HookStreamEvent,\n type HookWebhookScope,\n type HookWebhookRegistration,\n type HookWebhookRecord,\n type HookWebhookListOptions,\n type HookWebhookUnregisterOptions,\n type SubscribeOptions,\n type HooksServiceConfig,\n // Vault Service\n DataVaultService,\n VaultHeaders,\n VaultPublicSpaceKVActions,\n createVaultCrypto,\n type IDataVaultService,\n type VaultCrypto,\n type WasmVaultFunctions,\n type DataVaultConfig,\n type VaultPutOptions,\n type VaultGetOptions,\n type VaultListOptions,\n type VaultGrantOptions,\n type VaultEntry,\n type VaultError,\n} from \"@tinycloud/sdk-services\";\n\n// Space utilities\nexport {\n SpaceHostResult,\n fetchPeerId,\n submitHostDelegation,\n activateSessionWithHost,\n} from \"./space\";\n\n// Delegations\nexport {\n // Result pattern (aliased to avoid conflict with sdk-services Result)\n Result as DelegationResult,\n DelegationError,\n DelegationErrorCodes,\n DelegationErrorCode,\n // Delegation types\n Delegation,\n CreateDelegationParams,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n DelegatedResource,\n DelegationChain,\n DelegationApiResponse,\n // Configuration types\n DelegationManagerConfig,\n KeyProvider,\n // Classes\n DelegationManager,\n // v2 SharingService\n SharingService,\n createSharingService,\n ISharingService,\n SharingServiceConfig,\n EncodedShareData,\n ReceiveOptions,\n ShareAccess,\n // v2 types\n JWK,\n KeyType,\n KeyInfo,\n CapabilityEntry,\n DelegationRecord,\n DelegationChainV2,\n DelegationDirection,\n DelegationFilters,\n SpaceOwnership,\n SpaceInfo,\n ShareSchema,\n ShareLink,\n ShareLinkData,\n IngestOptions,\n GenerateShareParams,\n} from \"./delegations\";\n\n// Authorization (v2 spec)\nexport {\n // Class\n CapabilityKeyRegistry,\n // Interface\n ICapabilityKeyRegistry,\n // Factory\n createCapabilityKeyRegistry,\n // Types\n StoredDelegationChain,\n // Error codes\n CapabilityKeyRegistryErrorCodes,\n CapabilityKeyRegistryErrorCode,\n // SignStrategy types\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n EventEmitterStrategy,\n SignStrategy,\n defaultSignStrategy,\n // Space creation handler types\n SpaceCreationContext,\n ISpaceCreationHandler,\n AutoApproveSpaceCreationHandler,\n defaultSpaceCreationHandler,\n} from \"./authorization\";\n\n// Spaces (v2 spec)\nexport {\n // Space object\n Space,\n ISpace,\n SpaceConfig,\n ISpaceScopedDelegations,\n ISpaceScopedSharing,\n // SpaceService\n SpaceService,\n ISpaceService,\n SpaceServiceConfig,\n SpaceErrorCodes,\n SpaceErrorCode,\n createSpaceService,\n // URI utilities\n parseSpaceUri,\n buildSpaceUri,\n // Public space utility\n makePublicSpaceId,\n // Delegation creation types\n SpaceDelegationParams,\n CreateDelegationFunction,\n} from \"./spaces\";\n\n// Protocol version checking\nexport {\n ProtocolMismatchError,\n VersionCheckError,\n UnsupportedFeatureError,\n checkNodeInfo,\n} from \"./version\";\nexport type { NodeInfo } from \"./version\";\n\n// Manifest types and resolution (capability chain delegation)\nexport {\n // Types\n type Manifest,\n type ManifestDefaults,\n type ManifestDelegation,\n type PermissionEntry,\n type ResolvedCapabilities,\n type ResolvedDelegate,\n type ResourceCapability,\n // Errors\n ManifestValidationError,\n // Constants\n DEFAULT_DEFAULTS,\n DEFAULT_EXPIRY,\n SERVICE_LONG_TO_SHORT,\n SERVICE_SHORT_TO_LONG,\n // Types\n type AbilitiesMap,\n // Functions\n applyPrefix,\n expandActionShortNames,\n loadManifest,\n manifestAbilitiesUnion,\n normalizeDefaults,\n parseExpiry,\n resolveManifest,\n resourceCapabilitiesToAbilitiesMap,\n validateManifest,\n} from \"./manifest\";\n\n// Capability subset checking and recap parsing\nexport {\n // Errors\n PermissionNotInManifestError,\n SessionExpiredError,\n // Functions\n isCapabilitySubset,\n parseRecapCapabilities,\n // Types\n type ParseRecapFromSiwe,\n type SubsetCheckResult,\n type WasmRecapEntry,\n} from \"./capabilities\";\n","/**\n * Platform-agnostic client types for TinyCloud SDK.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport { SiweMessage } from \"siwe\";\n\nexport { SiweMessage };\n\n/** ENS data associated with a user session. */\nexport interface EnsData {\n domain?: string | null;\n avatarUrl?: string | null;\n}\n\nexport const EnsDataSchema = z.object({\n domain: z.string().nullable().optional(),\n avatarUrl: z.string().nullable().optional(),\n});\n\n/** SIWE configuration. All fields optional — callers provide only what they need to override. */\nexport interface SiweConfig {\n domain?: string;\n uri?: string;\n chainId?: number;\n statement?: string;\n nonce?: string;\n expirationTime?: string;\n notBefore?: string;\n requestId?: string;\n resources?: string[];\n}\n\nexport const SiweConfigSchema = z\n .object({\n domain: z.string().optional(),\n uri: z.string().optional(),\n chainId: z.number().optional(),\n statement: z.string().optional(),\n nonce: z.string().optional(),\n expirationTime: z.string().optional(),\n notBefore: z.string().optional(),\n requestId: z.string().optional(),\n resources: z.array(z.string()).optional(),\n })\n .passthrough();\n\n/** Representation of an active client session. */\nexport interface ClientSession {\n /** User address (may be delegated) */\n address: string;\n /** User address without delegation */\n walletAddress: string;\n /** EIP-155 chain ID */\n chainId: number;\n /** Key to identify the session */\n sessionKey: string;\n /** The SIWE message text (from SiweMessage.prepareMessage()) */\n siwe: string;\n /** The signature of the SIWE message */\n signature: string;\n /** ENS data supported by TinyCloud */\n ens?: EnsData;\n}\n\nexport const ClientSessionSchema = z.object({\n address: z.string(),\n walletAddress: z.string(),\n chainId: z.number(),\n sessionKey: z.string(),\n siwe: z.string(),\n signature: z.string(),\n ens: EnsDataSchema.optional(),\n});\n\n/** The URL of a server running tinycloud-node. */\nexport type ServerHost = string;\n\n/** Validate unknown data as a ClientSession. Returns the parsed session or null. */\nexport function validateClientSession(data: unknown): ClientSession | null {\n const result = ClientSessionSchema.safeParse(data);\n return result.success ? result.data : null;\n}\n","/**\n * Notification handler interface for TinyCloud SDK.\n *\n * Abstracts UI notifications so that web-sdk can show toasts\n * while node-sdk uses a silent no-op handler.\n *\n * @packageDocumentation\n */\n\n/**\n * Platform-agnostic notification handler.\n *\n * Implementations can provide different UX patterns:\n * - Browser: toast notifications via antd or similar\n * - Node.js: silent (default) or logging\n * - CLI: console output\n */\nexport interface INotificationHandler {\n /** Called on successful operations (e.g., \"Successfully signed in\") */\n success(message: string, description?: string): void;\n /** Called on warnings */\n warning(message: string, description?: string): void;\n /** Called on errors */\n error(category: string, message: string, description?: string): void;\n /** Optional cleanup (e.g., dismiss all active notifications) */\n cleanup?(): void;\n}\n\n/** No-op handler for environments without UI (node-sdk default). */\nexport class SilentNotificationHandler implements INotificationHandler {\n success(): void {}\n warning(): void {}\n error(): void {}\n}\n","/**\n * Zod schemas for session persistence types.\n *\n * This is the source of truth for session-related types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\n\n// =============================================================================\n// Shared Patterns\n// =============================================================================\n\n/**\n * Ethereum address pattern (checksummed or lowercase).\n */\nconst ethereumAddressPattern = /^0x[a-fA-F0-9]{40}$/;\n\n// =============================================================================\n// ENS Data Schema\n// =============================================================================\n\n/**\n * Schema for ENS data associated with a session.\n */\nexport const EnsDataSchema = z.object({\n /** ENS name/domain. */\n domain: z.string().nullable().optional(),\n /** ENS avatar URL. */\n avatarUrl: z.string().nullable().optional(),\n});\n\nexport type EnsData = z.infer<typeof EnsDataSchema>;\n\n// =============================================================================\n// Persisted TinyCloud Session Schema\n// =============================================================================\n\n/**\n * Schema for TinyCloud-specific session data that's persisted.\n */\nexport const PersistedTinyCloudSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** Additional spaces included in this session's capabilities. Key is logical name, value is full spaceId URI */\n spaces: z.record(z.string(), z.string()).optional(),\n /** The verification method DID */\n verificationMethod: z.string(),\n});\n\nexport type PersistedTinyCloudSession = z.infer<\n typeof PersistedTinyCloudSessionSchema\n>;\n\n// =============================================================================\n// Persisted Session Data Schema\n// =============================================================================\n\n/**\n * Schema for full persisted session data.\n *\n * Contains all data needed to restore a session without re-authentication.\n */\nexport const PersistedSessionDataSchema = z.object({\n /** User's Ethereum address */\n address: z\n .string()\n .regex(ethereumAddressPattern, \"Invalid Ethereum address\"),\n /** EIP-155 Chain ID */\n chainId: z.number().int().positive(),\n /** Session key in JWK format (stringified) */\n sessionKey: z.string(),\n /** The signed SIWE message */\n siwe: z.string(),\n /** User's signature of the SIWE message */\n signature: z.string(),\n /** TinyCloud delegation data if available */\n tinycloudSession: PersistedTinyCloudSessionSchema.optional(),\n /** Session expiration timestamp (ISO 8601 with timezone offset) */\n expiresAt: z.string().datetime({ offset: true }),\n /** Session creation timestamp (ISO 8601 with timezone offset) */\n createdAt: z.string().datetime({ offset: true }),\n /** Schema version for migrations */\n version: z.string(),\n /** Optional ENS data */\n ens: EnsDataSchema.optional(),\n});\n\nexport type PersistedSessionData = z.infer<typeof PersistedSessionDataSchema>;\n\n// =============================================================================\n// TinyCloud Session Schema (Runtime)\n// =============================================================================\n\n/**\n * Schema for full TinyCloud session with delegation data.\n *\n * This is the runtime session type used for making invocations and delegations.\n */\nexport const TinyCloudSessionSchema = z.object({\n /** User's Ethereum address */\n address: z.string().regex(ethereumAddressPattern, \"Invalid Ethereum address\"),\n /** EIP-155 Chain ID */\n chainId: z.number().int().positive(),\n /** Session key ID */\n sessionKey: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** Additional spaces included in this session's capabilities. Key is logical name, value is full spaceId URI */\n spaces: z.record(z.string(), z.string()).optional(),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The delegation header for API calls */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke operations) */\n jwk: z.object({}).passthrough(),\n /** The signed SIWE message */\n siwe: z.string(),\n /** User's signature of the SIWE message */\n signature: z.string(),\n});\n\nexport type TinyCloudSession = z.infer<typeof TinyCloudSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError extends ServiceError {\n code: \"VALIDATION_ERROR\";\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n/**\n * Validate persisted session data against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validatePersistedSessionData(JSON.parse(rawData));\n * if (result.ok) {\n * // result.data is typed as PersistedSessionData\n * console.log(result.data.address);\n * } else {\n * console.error(result.error.message);\n * }\n * ```\n */\nexport function validatePersistedSessionData(\n data: unknown\n): Result<PersistedSessionData, ValidationError> {\n const result = PersistedSessionDataSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate TinyCloud session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateTinyCloudSession(\n data: unknown\n): Result<TinyCloudSession, ValidationError> {\n const result = TinyCloudSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate persisted TinyCloud session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validatePersistedTinyCloudSession(\n data: unknown\n): Result<PersistedTinyCloudSession, ValidationError> {\n const result = PersistedTinyCloudSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","import {\n IUserAuthorization,\n ClientSession,\n Extension,\n SignInOptions,\n} from \"./userAuthorization\";\nimport {\n ServiceContext,\n IService,\n IServiceContext,\n IKVService,\n KVService,\n ISQLService,\n SQLService,\n IDuckDbService,\n DuckDbService,\n IDataVaultService,\n IHooksService,\n HooksService,\n ServiceSession,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n RetryPolicy,\n defaultRetryPolicy,\n ServiceConstructor,\n Result,\n ok,\n err,\n serviceError,\n ServiceError,\n ErrorCodes,\n} from \"@tinycloud/sdk-services\";\nimport { makePublicSpaceId } from \"./spaces/SpaceService\";\n\n/**\n * Configuration for the TinyCloud SDK.\n */\nexport interface TinyCloudConfig {\n /** Whether to automatically resolve ENS names */\n resolveEns?: boolean;\n\n // === Service Configuration ===\n\n /**\n * TinyCloud host URLs.\n * Required when using services.\n */\n hosts?: string[];\n\n /**\n * Platform-specific invoke function from WASM binding.\n * Required when using services.\n */\n invoke?: InvokeFunction;\n\n /**\n * Optional multi-resource invoke function for aggregated capability requests.\n */\n invokeAny?: InvokeAnyFunction;\n\n /**\n * Custom fetch implementation.\n * Defaults to globalThis.fetch.\n */\n fetch?: FetchFunction;\n\n /**\n * Service constructors to register.\n * Built-in services (like KVService) are registered by default unless overridden.\n *\n * @example\n * ```typescript\n * services: {\n * kv: KVService, // default\n * files: MyFileService, // custom\n * }\n * ```\n */\n services?: Record<string, ServiceConstructor>;\n\n /**\n * Per-service configuration.\n *\n * @example\n * ```typescript\n * serviceConfigs: {\n * kv: { prefix: 'myapp' },\n * files: { maxSize: 10_000_000 },\n * }\n * ```\n */\n serviceConfigs?: Record<string, Record<string, unknown>>;\n\n /**\n * Retry policy for service operations.\n */\n retryPolicy?: Partial<RetryPolicy>;\n}\n\n/**\n * TinyCloud SDK - Unified entry point for web and node.\n *\n * This class provides the main SDK interface. Platform-specific behavior\n * is injected through the IUserAuthorization implementation:\n * - WebUserAuthorization for browser environments\n * - NodeUserAuthorization for Node.js environments\n *\n * @example\n * ```typescript\n * // Web usage\n * import { TinyCloud } from '@tinycloud/sdk-core';\n * import { WebUserAuthorization } from '@tinycloud/web-sdk';\n *\n * const auth = new WebUserAuthorization({ ... });\n * const tc = new TinyCloud(auth);\n * await tc.signIn();\n * const result = await tc.kv.put('key', 'value');\n *\n * // Node usage\n * import { TinyCloud } from '@tinycloud/sdk-core';\n * import { NodeUserAuthorization, PrivateKeySigner } from '@tinycloud/node-sdk';\n *\n * const signer = new PrivateKeySigner(process.env.PRIVATE_KEY);\n * const auth = new NodeUserAuthorization({\n * signStrategy: { type: 'auto-sign' },\n * signer,\n * domain: 'api.myapp.com'\n * });\n * const tc = new TinyCloud(auth);\n * await tc.signIn();\n * ```\n */\nexport class TinyCloud {\n /**\n * User authorization handler.\n * Provides authentication and signing capabilities.\n */\n public readonly userAuthorization: IUserAuthorization;\n\n /**\n * SDK configuration.\n */\n private config: TinyCloudConfig;\n\n /**\n * Registered extensions.\n */\n private extensions: Extension[] = [];\n\n // === Service Infrastructure ===\n\n /**\n * Service context providing platform dependencies to services.\n */\n private _serviceContext?: ServiceContext;\n\n /**\n * Registered services by name.\n */\n private _services: Map<string, IService> = new Map();\n\n /**\n * Whether services have been initialized.\n */\n private _servicesInitialized: boolean = false;\n\n /**\n * Create a new TinyCloud SDK instance.\n *\n * @param userAuthorization - Platform-specific authorization implementation\n * @param config - Optional SDK configuration\n */\n constructor(userAuthorization: IUserAuthorization, config?: TinyCloudConfig) {\n this.userAuthorization = userAuthorization;\n this.config = config || {};\n }\n\n // === Service Management ===\n\n /**\n * Initialize services with platform dependencies.\n * Must be called before using services.\n *\n * @param invoke - Platform-specific invoke function from WASM binding\n * @param hosts - TinyCloud host URLs (optional, uses config.hosts)\n * @param fetchFn - Custom fetch implementation (optional)\n */\n public initializeServices(\n invoke?: InvokeFunction,\n hosts?: string[],\n fetchFn?: FetchFunction,\n ): void {\n const effectiveInvoke = invoke ?? this.config.invoke;\n const effectiveHosts = hosts ?? this.config.hosts;\n\n if (!effectiveInvoke) {\n throw new Error(\n \"invoke function is required to initialize services. \" +\n \"Provide it via config.invoke or initializeServices().\",\n );\n }\n\n if (!effectiveHosts || effectiveHosts.length === 0) {\n throw new Error(\n \"hosts are required to initialize services. \" +\n \"Provide them via config.hosts or initializeServices().\",\n );\n }\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: effectiveInvoke,\n invokeAny: this.config.invokeAny,\n fetch: fetchFn ?? this.config.fetch ?? globalThis.fetch.bind(globalThis),\n hosts: effectiveHosts,\n retryPolicy: this.config.retryPolicy,\n });\n\n // Register default services (can be overridden via config.services)\n const serviceConstructors: Record<string, ServiceConstructor> = {\n kv: KVService,\n sql: SQLService,\n duckdb: DuckDbService,\n hooks: HooksService,\n ...this.config.services,\n };\n\n // Create and register services\n for (const [name, ServiceClass] of Object.entries(serviceConstructors)) {\n const serviceConfig = this.config.serviceConfigs?.[name] ?? {};\n const service = new ServiceClass(serviceConfig);\n service.initialize(this._serviceContext);\n this._serviceContext.registerService(name, service);\n this._services.set(name, service);\n }\n\n this._servicesInitialized = true;\n }\n\n /**\n * Get the service context.\n * @throws Error if services are not initialized\n */\n public get serviceContext(): IServiceContext {\n if (!this._serviceContext) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first.\",\n );\n }\n return this._serviceContext;\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name (e.g., 'kv')\n * @returns The service instance or undefined\n */\n public getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n /**\n * Get the KV service.\n * @throws Error if services are not initialized\n */\n public get kv(): IKVService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"kv\") as IKVService | undefined;\n if (!service) {\n throw new Error(\"KV service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the SQL service.\n * @throws Error if services are not initialized\n */\n public get sql(): ISQLService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"sql\") as ISQLService | undefined;\n if (!service) {\n throw new Error(\"SQL service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the DuckDB service.\n * @throws Error if services are not initialized\n */\n public get duckdb(): IDuckDbService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"duckdb\") as IDuckDbService | undefined;\n if (!service) {\n throw new Error(\"DuckDB service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the Hooks service.\n * @throws Error if services are not initialized\n */\n public get hooks(): IHooksService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"hooks\") as IHooksService | undefined;\n if (!service) {\n throw new Error(\"Hooks service is not registered.\");\n }\n return service;\n }\n\n /**\n * Get the Data Vault service.\n * @throws Error if services are not initialized or vault service is not registered\n */\n public get vault(): IDataVaultService {\n if (!this._servicesInitialized) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n const service = this._services.get(\"vault\") as\n | IDataVaultService\n | undefined;\n if (!service) {\n throw new Error(\"Vault service is not registered.\");\n }\n return service;\n }\n\n /**\n * Notify services of session change.\n * Called internally after sign-in and sign-out.\n *\n * @param session - The new session, or null if signed out\n */\n private notifyServicesOfSessionChange(session: ServiceSession | null): void {\n if (this._serviceContext) {\n this._serviceContext.setSession(session);\n }\n }\n\n /**\n * Abort all pending service operations.\n * Called internally before sign-out.\n */\n private abortServiceOperations(): void {\n if (this._serviceContext) {\n this._serviceContext.abort();\n }\n }\n\n /**\n * Convert ClientSession to ServiceSession.\n * Returns null if session lacks required fields.\n */\n private toServiceSession(\n clientSession: ClientSession | undefined,\n ): ServiceSession | null {\n if (!clientSession) return null;\n\n // TinyCloudSession contains the required fields\n const tcSession = (clientSession as any).tinycloudSession;\n if (!tcSession) return null;\n\n return {\n delegationHeader: tcSession.delegationHeader,\n delegationCid: tcSession.delegationCid,\n spaceId: tcSession.spaceId,\n verificationMethod: tcSession.verificationMethod,\n jwk: tcSession.jwk,\n };\n }\n\n /**\n * Add an extension to the SDK.\n * Extensions can add capabilities and lifecycle hooks.\n */\n public extend(extension: Extension): void {\n this.extensions.push(extension);\n this.userAuthorization.extend(extension);\n }\n\n /**\n * Check if an extension is enabled.\n * @param namespace - The extension namespace to check\n */\n public isExtensionEnabled(namespace: string): boolean {\n return this.extensions.some((ext) => ext.namespace === namespace);\n }\n\n // === Authentication Methods (delegate to userAuthorization) ===\n\n /**\n * Get the current session, if signed in.\n */\n public get session(): ClientSession | undefined {\n return this.userAuthorization.session;\n }\n\n /**\n * Check if the user is signed in.\n */\n public get isSignedIn(): boolean {\n return !!this.userAuthorization.session;\n }\n\n /**\n * Sign in and create a new session.\n * Notifies services of the new session after successful sign-in.\n * @param options - Optional per-call SIWE overrides for this sign-in only\n * @returns The new session\n */\n public async signIn(options?: SignInOptions): Promise<ClientSession> {\n const session = await this.userAuthorization.signIn(options);\n\n // Notify services of the new session\n const serviceSession = this.toServiceSession(session);\n this.notifyServicesOfSessionChange(serviceSession);\n\n return session;\n }\n\n /**\n * Sign out and clear the current session.\n * Aborts pending service operations and notifies services.\n */\n public async signOut(): Promise<void> {\n // Abort all pending operations before sign-out\n this.abortServiceOperations();\n\n await this.userAuthorization.signOut();\n\n // Clear cached public KV service\n this._publicKV = undefined;\n\n // Clear session from services\n this.notifyServicesOfSessionChange(null);\n }\n\n /**\n * Get the current wallet address.\n */\n public address(): string | undefined {\n return this.userAuthorization.address();\n }\n\n /**\n * Get the current chain ID.\n */\n public chainId(): number | undefined {\n return this.userAuthorization.chainId();\n }\n\n /**\n * Sign a message with the connected wallet.\n * @param message - Message to sign\n */\n public async signMessage(message: string): Promise<string> {\n return this.userAuthorization.signMessage(message);\n }\n\n // === Public Space Methods ===\n\n /**\n * Cached public KV service instance.\n */\n private _publicKV?: IKVService;\n\n /**\n * Construct the deterministic public space ID for a given address and chain ID.\n *\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @returns The public space ID\n */\n static makePublicSpaceId(address: string, chainId: number): string {\n return makePublicSpaceId(address, chainId);\n }\n\n /**\n * Ensure the user's public space exists.\n * Creates it via spaces.create('public') if it doesn't.\n * Called automatically by modules that need to publish data.\n *\n * Requires the user to be signed in and services to be initialized.\n */\n public async ensurePublicSpace(): Promise<Result<void, ServiceError>> {\n const address = this.address();\n const chainId = this.chainId();\n if (!address || !chainId) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"Must be signed in to ensure public space\",\n \"public-space\",\n ),\n );\n }\n\n if (!this._serviceContext) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"Services not initialized. Call initializeServices() or signIn() first.\",\n \"public-space\",\n ),\n );\n }\n\n const spaceId = makePublicSpaceId(address, chainId);\n\n // Check if it already exists via invoke\n try {\n const session = this._serviceContext.session;\n if (!session) {\n return err(\n serviceError(\n ErrorCodes.AUTH_REQUIRED,\n \"No active session\",\n \"public-space\",\n ),\n );\n }\n\n const headers = this._serviceContext.invoke(\n session,\n \"space\",\n spaceId,\n \"tinycloud.space/info\",\n );\n\n const response = await this._serviceContext.fetch(\n `${this._serviceContext.hosts[0]}/invoke`,\n { method: \"POST\", headers, body: JSON.stringify({ spaceId }) },\n );\n\n if (response.ok) {\n return ok(undefined);\n }\n\n if (response.status === 404) {\n // Space doesn't exist — create it\n const createHeaders = this._serviceContext.invoke(\n session,\n \"space\",\n \"public\",\n \"tinycloud.space/create\",\n );\n\n const createResponse = await this._serviceContext.fetch(\n `${this._serviceContext.hosts[0]}/invoke`,\n {\n method: \"POST\",\n headers: createHeaders,\n body: JSON.stringify({ name: \"public\" }),\n },\n );\n\n if (!createResponse.ok) {\n // 409 means it already exists — that's fine\n if (createResponse.status === 409) {\n return ok(undefined);\n }\n const errorText = await createResponse.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to create public space: ${createResponse.status} - ${errorText}`,\n \"public-space\",\n ),\n );\n }\n\n return ok(undefined);\n }\n\n // Other error from info check\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to check public space: ${response.status} - ${errorText}`,\n \"public-space\",\n ),\n );\n } catch (error) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Network error ensuring public space: ${String(error)}`,\n \"public-space\",\n { cause: error instanceof Error ? error : undefined },\n ),\n );\n }\n }\n\n /**\n * Get a KVService scoped to the user's own public space.\n * Writes require authentication (owner/delegate).\n *\n * @throws Error if not signed in or services not initialized\n */\n public get publicKV(): IKVService {\n if (!this._servicesInitialized || !this._serviceContext) {\n throw new Error(\n \"Services not initialized. Call initializeServices() first, \" +\n \"or use TinyCloudWeb/TinyCloudNode which handles this automatically.\",\n );\n }\n\n const address = this.address();\n const chainId = this.chainId();\n if (!address || !chainId) {\n throw new Error(\"Must be signed in to access publicKV.\");\n }\n\n // Return cached instance if available\n if (this._publicKV) {\n return this._publicKV;\n }\n\n const publicSpaceId = makePublicSpaceId(address, chainId);\n const session = this._serviceContext.session;\n if (!session) {\n throw new Error(\"No active session. Sign in first.\");\n }\n\n // Create a KV service with a context that targets the public space\n const publicKV = new KVService({ prefix: \"\" });\n const publicContext = new ServiceContext({\n invoke: this._serviceContext.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n retryPolicy: this.config.retryPolicy,\n });\n publicContext.setSession({\n ...session,\n spaceId: publicSpaceId,\n });\n publicKV.initialize(publicContext);\n\n this._publicKV = publicKV;\n return this._publicKV;\n }\n\n /**\n * Read from any user's public space (unauthenticated).\n * Uses the public REST endpoint — no session needed.\n *\n * @param host - TinyCloud server URL (e.g., \"https://node.tinycloud.xyz\")\n * @param spaceId - Full public space ID\n * @param key - Key to read\n * @param fetchFn - Optional custom fetch function\n * @returns The data at the key\n */\n static async readPublicSpace<T = unknown>(\n host: string,\n spaceId: string,\n key: string,\n fetchFn?: FetchFunction,\n ): Promise<Result<T, ServiceError>> {\n const doFetch = fetchFn ?? globalThis.fetch.bind(globalThis);\n const encodedKey = key.split(\"/\").map(encodeURIComponent).join(\"/\");\n const url = `${host}/public/${encodeURIComponent(spaceId)}/kv/${encodedKey}`;\n\n try {\n const response = await doFetch(url, { method: \"GET\" });\n\n if (!response.ok) {\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.NOT_FOUND,\n `Key not found: ${key} in space ${spaceId}`,\n \"public-space\",\n ),\n );\n }\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to read public space: ${response.status} - ${errorText}`,\n \"public-space\",\n { meta: { status: response.status } },\n ),\n );\n }\n\n const contentType = response.headers.get(\"content-type\");\n let data: T;\n if (contentType?.includes(\"application/json\")) {\n data = (await response.json()) as T;\n } else {\n const text = await response.text();\n // Try parsing as JSON, fall back to raw text\n try {\n data = JSON.parse(text) as T;\n } catch {\n data = text as unknown as T;\n }\n }\n\n return ok(data);\n } catch (error) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Network error reading public space: ${String(error)}`,\n \"public-space\",\n { cause: error instanceof Error ? error : undefined },\n ),\n );\n }\n }\n\n /**\n * Read from any user's public space by address (unauthenticated).\n * Convenience method that constructs the space ID from address and chain ID.\n *\n * @param host - TinyCloud server URL\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @param key - Key to read\n * @param fetchFn - Optional custom fetch function\n * @returns The data at the key\n */\n static async readPublicKey<T = unknown>(\n host: string,\n address: string,\n chainId: number,\n key: string,\n fetchFn?: FetchFunction,\n ): Promise<Result<T, ServiceError>> {\n const spaceId = makePublicSpaceId(address, chainId);\n return TinyCloud.readPublicSpace<T>(host, spaceId, key, fetchFn);\n }\n}\n","/**\n * SpaceService - Global singleton for managing spaces (owned and delegated).\n *\n * SpaceService provides a unified interface for discovering, creating,\n * and accessing spaces. It handles both owned spaces (created by the user)\n * and delegated spaces (shared by other users).\n *\n * @packageDocumentation\n */\n\nimport type {\n IKVService,\n Result,\n ServiceError,\n ServiceSession,\n FetchFunction,\n InvokeFunction,\n} from \"@tinycloud/sdk-services\";\nimport { ok, err, serviceError } from \"@tinycloud/sdk-services\";\nimport type {\n SpaceInfo,\n SpaceOwnership,\n Delegation,\n CreateDelegationParams,\n ShareLink,\n GenerateShareParams,\n} from \"../delegations/types\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry\";\nimport type { ISharingService } from \"../delegations/SharingService\";\nimport {\n Space,\n type ISpace,\n type ISpaceScopedDelegations,\n type ISpaceScopedSharing,\n type SpaceConfig,\n} from \"./Space\";\nimport {\n validateServerDelegationsResponse,\n validateServerOwnedSpacesResponse,\n validateServerCreateSpaceResponse,\n validateServerSpaceInfoResponse,\n type ServerDelegationsResponse,\n} from \"./spaces.schema.js\";\n\n// =============================================================================\n// Service Name and Error Codes\n// =============================================================================\n\nconst SERVICE_NAME = \"space\";\n\n/**\n * Error codes for SpaceService operations.\n */\nexport const SpaceErrorCodes = {\n /** Space not found */\n NOT_FOUND: \"SPACE_NOT_FOUND\",\n /** Space already exists */\n ALREADY_EXISTS: \"SPACE_ALREADY_EXISTS\",\n /** Creation failed */\n CREATION_FAILED: \"SPACE_CREATION_FAILED\",\n /** Authentication required */\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n /** Invalid space name or URI */\n INVALID_NAME: \"INVALID_SPACE_NAME\",\n /** Network error */\n NETWORK_ERROR: \"NETWORK_ERROR\",\n /** Not initialized */\n NOT_INITIALIZED: \"NOT_INITIALIZED\",\n} as const;\n\nexport type SpaceErrorCode = (typeof SpaceErrorCodes)[keyof typeof SpaceErrorCodes];\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Parameters for creating a space-scoped delegation.\n * Extends CreateDelegationParams with the spaceId.\n */\nexport interface SpaceDelegationParams extends Omit<CreateDelegationParams, \"spaceId\"> {\n /** The space ID to create the delegation for */\n spaceId: string;\n}\n\n/**\n * Function type for creating delegations.\n * Platform SDKs provide this to handle SIWE-based delegation creation.\n */\nexport type CreateDelegationFunction = (\n params: SpaceDelegationParams\n) => Promise<Result<Delegation, ServiceError>>;\n\n/**\n * Configuration for SpaceService.\n */\nexport interface SpaceServiceConfig {\n /** TinyCloud host URLs */\n hosts: string[];\n /** Active session for authentication */\n session: ServiceSession;\n /** Platform-specific invoke function */\n invoke: InvokeFunction;\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n /** Optional capability key registry for delegated space discovery */\n capabilityRegistry?: ICapabilityKeyRegistry;\n /** Factory function to create a space-scoped KV service */\n createKVService?: (spaceId: string) => IKVService;\n /** User's PKH DID (derived from address or provided explicitly) */\n userDid?: string;\n /** Optional SharingService for v2 sharing links (client-side) */\n sharingService?: ISharingService;\n /**\n * Factory function to create delegations using SIWE-based flow.\n * Platform SDKs (web-sdk, node-sdk) provide this using their WASM bindings.\n * Required for space.delegations.create() to work.\n */\n createDelegation?: CreateDelegationFunction;\n}\n\n/**\n * Interface for SpaceService.\n */\nexport interface ISpaceService {\n /**\n * List all spaces the user has access to (owned + delegated).\n */\n list(): Promise<Result<SpaceInfo[], ServiceError>>;\n\n /**\n * Create a new space.\n *\n * @param name - The name for the new space\n */\n create(name: string): Promise<Result<SpaceInfo, ServiceError>>;\n\n /**\n * Get a Space object by name or full URI.\n *\n * For owned spaces, use the short name: `sdk.space('default')`\n * For delegated spaces, use the full URI: `sdk.space('tinycloud:pkh:eip155:1:0x...:photos')`\n *\n * @param nameOrUri - Short name or full URI\n */\n get(nameOrUri: string): ISpace;\n\n /**\n * Check if a space exists and the user has access.\n *\n * @param nameOrUri - Short name or full URI\n */\n exists(nameOrUri: string): Promise<Result<boolean, ServiceError>>;\n\n /**\n * Get the current user's primary space ID.\n */\n getCurrentSpaceId(): string | undefined;\n\n /**\n * Update the service configuration.\n */\n updateConfig(config: Partial<SpaceServiceConfig>): void;\n}\n\n// =============================================================================\n// Public Space Utilities\n// =============================================================================\n\n/**\n * Construct the deterministic public space ID for a given address and chain ID.\n *\n * Public space IDs follow the format:\n * `tinycloud:pkh:eip155:{chainId}:{address}:public`\n *\n * Given an address and chain ID, any client can construct this ID\n * to discover and read a user's public data without prior interaction.\n *\n * @param address - Ethereum address (0x-prefixed)\n * @param chainId - Chain ID (e.g., 1 for mainnet)\n * @returns The full public space ID URI\n *\n * @example\n * ```typescript\n * const spaceId = makePublicSpaceId('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 1);\n * // => \"tinycloud:pkh:eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045:public\"\n * ```\n */\nexport function makePublicSpaceId(address: string, chainId: number): string {\n return `tinycloud:pkh:eip155:${chainId}:${address}:public`;\n}\n\n// =============================================================================\n// Space URI Utilities\n// =============================================================================\n\n/**\n * Parse a space URI to extract components.\n *\n * Full URI format: `tinycloud:pkh:eip155:{chainId}:{address}:{name}`\n * Short name format: `{name}`\n *\n * @param uri - The space URI or short name\n * @returns Parsed components or null if invalid\n */\nexport function parseSpaceUri(\n uri: string\n): { owner: string; name: string; chainId?: string; address?: string } | null {\n // Full URI format: tinycloud:pkh:eip155:{chainId}:{address}:{name}\n const fullUriMatch = uri.match(\n /^tinycloud:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40}):(.+)$/\n );\n if (fullUriMatch) {\n const [, chainId, address, name] = fullUriMatch;\n return {\n owner: `did:pkh:eip155:${chainId}:${address}`,\n name,\n chainId,\n address,\n };\n }\n\n // Short name format - just return the name, owner will be inferred\n if (/^[a-zA-Z0-9_-]+$/.test(uri)) {\n return {\n owner: \"\", // Will be filled in from session\n name: uri,\n };\n }\n\n return null;\n}\n\n/**\n * Build a full space URI from components.\n *\n * @param owner - Owner DID (did:pkh:eip155:{chainId}:{address})\n * @param name - Space name\n * @returns Full space URI\n */\nexport function buildSpaceUri(owner: string, name: string): string {\n // Extract chain ID and address from PKH DID\n const pkhMatch = owner.match(/^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/);\n if (pkhMatch) {\n const [, chainId, address] = pkhMatch;\n return `tinycloud:pkh:eip155:${chainId}:${address}:${name}`;\n }\n // Fallback - shouldn't happen with valid PKH DIDs\n return `tinycloud:${owner}:${name}`;\n}\n\n// =============================================================================\n// Server Response Transformation\n// =============================================================================\n\n/**\n * Transform validated server delegation response to SDK's Delegation[] format.\n *\n * Server returns { [cid: string]: DelegationInfo } where:\n * - Key is the delegation CID\n * - Value is DelegationInfo with delegator, delegate, capabilities, etc.\n *\n * SDK expects Delegation[] with cid field included.\n *\n * @param validatedData - Pre-validated server response from validateServerDelegationsResponse()\n * @param defaultSpaceId - Default space ID to use if not extractable from resource\n */\nfunction transformServerDelegations(\n validatedData: ServerDelegationsResponse,\n defaultSpaceId: string\n): Delegation[] {\n const result: Delegation[] = [];\n\n for (const [cid, info] of Object.entries(validatedData)) {\n // Extract path from capabilities (use first capability's resource path)\n const capabilities = info.capabilities;\n let path = \"\";\n let spaceId = defaultSpaceId;\n const actions: string[] = [];\n\n for (const cap of capabilities) {\n actions.push(cap.ability);\n // Parse resource to extract space and path\n // Resource format: tinycloud:pkh:eip155:{chainId}:{address}:{spaceName}/{service}/{path}\n const resourceMatch = cap.resource.match(\n /^(tinycloud:pkh:eip155:\\d+:0x[a-fA-F0-9]+:[^/]+)\\/[^/]+\\/(.*)$/\n );\n if (resourceMatch) {\n spaceId = resourceMatch[1];\n path = resourceMatch[2] || \"\";\n }\n }\n\n // Extract first string parent CID (server may return byte arrays for some CIDs)\n const firstStringParent = info.parents?.find((p): p is string => typeof p === 'string');\n\n result.push({\n cid,\n delegateDID: info.delegate,\n delegatorDID: info.delegator,\n spaceId,\n path,\n actions,\n expiry: info.expiry ? new Date(info.expiry) : new Date(Date.now() + 24 * 60 * 60 * 1000),\n isRevoked: false,\n createdAt: info.issued_at ? new Date(info.issued_at) : undefined,\n parentCid: firstStringParent,\n });\n }\n\n return result;\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * SpaceService - Global singleton for managing spaces.\n *\n * @example\n * ```typescript\n * const spaceService = new SpaceService({\n * hosts: ['https://node.tinycloud.xyz'],\n * session,\n * invoke,\n * });\n *\n * // List all accessible spaces\n * const result = await spaceService.list();\n * if (result.ok) {\n * for (const space of result.data) {\n * console.log(`${space.name} (${space.type})`);\n * }\n * }\n *\n * // Create a new space\n * const createResult = await spaceService.create('photos');\n *\n * // Get a space object for operations\n * const space = spaceService.get('photos');\n * await space.kv.put('album/vacation', { photos: [...] });\n * ```\n */\nexport class SpaceService implements ISpaceService {\n private hosts: string[];\n private session: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n private capabilityRegistry?: ICapabilityKeyRegistry;\n private createKVServiceFn?: (spaceId: string) => IKVService;\n private _userDid?: string;\n private sharingService?: ISharingService;\n private createDelegationFn?: CreateDelegationFunction;\n\n /** Cache of created Space objects */\n private spaceCache: Map<string, ISpace> = new Map();\n\n /** Cache of space info */\n private infoCache: Map<string, { info: SpaceInfo; cachedAt: number }> = new Map();\n\n /** Cache TTL in milliseconds (5 minutes) */\n private readonly cacheTTL = 5 * 60 * 1000;\n\n /**\n * Create a new SpaceService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: SpaceServiceConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.capabilityRegistry = config.capabilityRegistry;\n this.createKVServiceFn = config.createKVService;\n this._userDid = config.userDid;\n this.sharingService = config.sharingService;\n this.createDelegationFn = config.createDelegation;\n }\n\n /**\n * Update the service configuration.\n */\n updateConfig(config: Partial<SpaceServiceConfig>): void {\n if (config.hosts) this.hosts = config.hosts;\n if (config.session) this.session = config.session;\n if (config.invoke) this.invoke = config.invoke;\n if (config.fetch) this.fetchFn = config.fetch;\n if (config.capabilityRegistry) this.capabilityRegistry = config.capabilityRegistry;\n if (config.createKVService) this.createKVServiceFn = config.createKVService;\n if (config.userDid !== undefined) this._userDid = config.userDid;\n if (config.sharingService) this.sharingService = config.sharingService;\n if (config.createDelegation) this.createDelegationFn = config.createDelegation;\n\n // Clear caches when config changes\n this.spaceCache.clear();\n this.infoCache.clear();\n }\n\n /**\n * Get the current user's primary space ID.\n */\n getCurrentSpaceId(): string | undefined {\n return this.session?.spaceId;\n }\n\n /**\n * Get the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Get the current user's PKH DID.\n */\n private get userDid(): string | undefined {\n // Return explicitly set user DID, or try to derive from verificationMethod\n if (this._userDid) {\n return this._userDid;\n }\n // verificationMethod might be did:key format - cannot derive PKH from it\n // The caller should provide userDid explicitly for full functionality\n return undefined;\n }\n\n // ===========================================================================\n // List Spaces\n // ===========================================================================\n\n /**\n * List all spaces the user has access to.\n *\n * Combines owned spaces (from the server) with delegated spaces\n * (from the capability registry).\n */\n async list(): Promise<Result<SpaceInfo[], ServiceError>> {\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n try {\n const spaces: SpaceInfo[] = [];\n\n // 1. Get owned spaces from the server\n const ownedResult = await this.listOwnedSpaces();\n if (ownedResult.ok) {\n spaces.push(...ownedResult.data);\n }\n\n // 2. Get delegated spaces from capability registry\n if (this.capabilityRegistry) {\n const delegatedSpaces = this.discoverDelegatedSpaces();\n spaces.push(...delegatedSpaces);\n }\n\n // Remove duplicates (prefer owned over delegated)\n const uniqueSpaces = this.deduplicateSpaces(spaces);\n\n return ok(uniqueSpaces);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list spaces: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n /**\n * List owned spaces from the server.\n */\n private async listOwnedSpaces(): Promise<Result<SpaceInfo[], ServiceError>> {\n try {\n const headers = this.invoke(this.session, \"space\", \"\", \"tinycloud.space/list\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list owned spaces: ${response.status} - ${errorText}`,\n SERVICE_NAME,\n { meta: { status: response.status } }\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerOwnedSpacesResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const spaces: SpaceInfo[] = validationResult.data.map((item) => ({\n id: item.id,\n name: item.name ?? this.extractNameFromId(item.id),\n owner: item.owner,\n type: \"owned\" as SpaceOwnership,\n permissions: [\"*\"], // Full permissions for owned spaces\n }));\n\n return ok(spaces);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing owned spaces: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n /**\n * Discover delegated spaces from the capability registry.\n */\n private discoverDelegatedSpaces(): SpaceInfo[] {\n if (!this.capabilityRegistry) {\n return [];\n }\n\n const spaces: Map<string, SpaceInfo> = new Map();\n\n // Get all capabilities and extract unique space IDs\n const capabilities = this.capabilityRegistry.getAllCapabilities();\n\n for (const capability of capabilities) {\n const spaceId = capability.delegation.spaceId;\n\n // Skip if we already have this space\n if (spaces.has(spaceId)) {\n const existing = spaces.get(spaceId)!;\n // Merge permissions\n if (existing.permissions) {\n const actions = capability.delegation.actions;\n for (const action of actions) {\n if (!existing.permissions.includes(action)) {\n existing.permissions.push(action);\n }\n }\n }\n continue;\n }\n\n // Skip if this is the user's own space\n if (spaceId === this.session?.spaceId) {\n continue;\n }\n\n const parsed = parseSpaceUri(spaceId);\n\n spaces.set(spaceId, {\n id: spaceId,\n name: parsed?.name ?? this.extractNameFromId(spaceId),\n owner: capability.delegation.delegatorDID ?? parsed?.owner ?? \"\",\n type: \"delegated\",\n permissions: [...capability.delegation.actions],\n expiresAt: capability.expiresAt,\n });\n }\n\n return Array.from(spaces.values());\n }\n\n /**\n * Extract space name from a full space ID.\n */\n private extractNameFromId(id: string): string {\n const parsed = parseSpaceUri(id);\n if (parsed) {\n return parsed.name;\n }\n // Fallback: take last segment\n const parts = id.split(\":\");\n return parts[parts.length - 1] || id;\n }\n\n /**\n * Deduplicate spaces, preferring owned over delegated.\n */\n private deduplicateSpaces(spaces: SpaceInfo[]): SpaceInfo[] {\n const seen = new Map<string, SpaceInfo>();\n\n for (const space of spaces) {\n const existing = seen.get(space.id);\n if (!existing || (existing.type === \"delegated\" && space.type === \"owned\")) {\n seen.set(space.id, space);\n }\n }\n\n return Array.from(seen.values());\n }\n\n // ===========================================================================\n // Create Space\n // ===========================================================================\n\n /**\n * Create a new space.\n *\n * @param name - The name for the new space\n */\n async create(name: string): Promise<Result<SpaceInfo, ServiceError>> {\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n // Validate name\n if (!name || !/^[a-zA-Z0-9_-]+$/.test(name)) {\n return err(\n serviceError(\n SpaceErrorCodes.INVALID_NAME,\n \"Space name must contain only alphanumeric characters, underscores, and hyphens\",\n SERVICE_NAME\n )\n );\n }\n\n try {\n const headers = this.invoke(this.session, \"space\", name, \"tinycloud.space/create\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ name }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 409) {\n return err(\n serviceError(\n SpaceErrorCodes.ALREADY_EXISTS,\n `Space \"${name}\" already exists`,\n SERVICE_NAME\n )\n );\n }\n\n return err(\n serviceError(\n SpaceErrorCodes.CREATION_FAILED,\n `Failed to create space: ${response.status} - ${errorText}`,\n SERVICE_NAME,\n { meta: { status: response.status } }\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerCreateSpaceResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.CREATION_FAILED,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const spaceInfo: SpaceInfo = {\n id: validationResult.data.id,\n name: validationResult.data.name || name,\n owner: validationResult.data.owner || this.userDid || \"\",\n type: \"owned\",\n permissions: [\"*\"],\n };\n\n // Cache the info\n this.infoCache.set(spaceInfo.id, { info: spaceInfo, cachedAt: Date.now() });\n\n return ok(spaceInfo);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error creating space: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n // ===========================================================================\n // Get Space\n // ===========================================================================\n\n /**\n * Get a Space object by name or full URI.\n *\n * @param nameOrUri - Short name or full URI\n */\n get(nameOrUri: string): ISpace {\n // Resolve the full space ID\n const spaceId = this.resolveSpaceId(nameOrUri);\n\n // Check cache\n const cached = this.spaceCache.get(spaceId);\n if (cached) {\n return cached;\n }\n\n // Create new Space object\n const parsed = parseSpaceUri(spaceId);\n const name = parsed?.name ?? this.extractNameFromId(spaceId);\n\n const config: SpaceConfig = {\n id: spaceId,\n name,\n createKV: this.createSpaceScopedKV.bind(this),\n createDelegations: this.createSpaceScopedDelegations.bind(this),\n createSharing: this.createSpaceScopedSharing.bind(this),\n getInfo: this.getSpaceInfo.bind(this),\n };\n\n const space = new Space(config);\n this.spaceCache.set(spaceId, space);\n\n return space;\n }\n\n /**\n * Resolve a name or URI to a full space ID.\n */\n private resolveSpaceId(nameOrUri: string): string {\n const parsed = parseSpaceUri(nameOrUri);\n\n if (!parsed) {\n // Invalid format, return as-is\n return nameOrUri;\n }\n\n if (parsed.owner) {\n // Full URI - return as-is\n return nameOrUri;\n }\n\n // Short name - build full URI from user's DID\n if (this.userDid) {\n return buildSpaceUri(this.userDid, parsed.name);\n }\n\n // No user DID available, return as-is\n return nameOrUri;\n }\n\n // ===========================================================================\n // Exists Check\n // ===========================================================================\n\n /**\n * Check if a space exists and the user has access.\n */\n async exists(nameOrUri: string): Promise<Result<boolean, ServiceError>> {\n const spaceId = this.resolveSpaceId(nameOrUri);\n\n // Check info cache first\n const cached = this.infoCache.get(spaceId);\n if (cached && Date.now() - cached.cachedAt < this.cacheTTL) {\n return ok(true);\n }\n\n // Query the server\n const infoResult = await this.getSpaceInfo(spaceId);\n return ok(infoResult.ok);\n }\n\n // ===========================================================================\n // Space Info\n // ===========================================================================\n\n /**\n * Get space info from server or cache.\n */\n private async getSpaceInfo(spaceId: string): Promise<Result<SpaceInfo, ServiceError>> {\n // Check cache\n const cached = this.infoCache.get(spaceId);\n if (cached && Date.now() - cached.cachedAt < this.cacheTTL) {\n return ok(cached.info);\n }\n\n if (!this.session) {\n return err(\n serviceError(SpaceErrorCodes.AUTH_REQUIRED, \"Authentication required\", SERVICE_NAME)\n );\n }\n\n try {\n const headers = this.invoke(this.session, \"space\", spaceId, \"tinycloud.space/info\");\n\n const response = await this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ spaceId }),\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return err(\n serviceError(SpaceErrorCodes.NOT_FOUND, `Space not found: ${spaceId}`, SERVICE_NAME)\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to get space info: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerSpaceInfoResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const data = validationResult.data;\n const spaceInfo: SpaceInfo = {\n id: data.id,\n name: data.name ?? this.extractNameFromId(data.id),\n owner: data.owner,\n type: data.type ?? (data.owner === this.userDid ? \"owned\" : \"delegated\"),\n permissions: data.permissions,\n expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined,\n };\n\n // Cache the info\n this.infoCache.set(spaceId, { info: spaceInfo, cachedAt: Date.now() });\n\n return ok(spaceInfo);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error getting space info: ${String(error)}`,\n SERVICE_NAME,\n { cause: error instanceof Error ? error : undefined }\n )\n );\n }\n }\n\n // ===========================================================================\n // Space-Scoped Service Factories\n // ===========================================================================\n\n /**\n * Create a space-scoped KV service.\n */\n private createSpaceScopedKV(spaceId: string): IKVService {\n if (this.createKVServiceFn) {\n return this.createKVServiceFn(spaceId);\n }\n\n // Return a proxy that throws a helpful error\n return new Proxy({} as IKVService, {\n get: () => {\n throw new Error(\n \"KV service factory not configured. Provide createKVService in SpaceServiceConfig.\"\n );\n },\n });\n }\n\n /**\n * Create space-scoped delegation operations.\n */\n private createSpaceScopedDelegations(spaceId: string): ISpaceScopedDelegations {\n const self = this;\n\n return {\n async list(): Promise<Result<Delegation[], ServiceError>> {\n // List outgoing delegations (created by user) using tinycloud.capabilities/read\n try {\n // Facts contain the query params for the capabilities/read capability\n const facts = [\n {\n capabilitiesReadParams: {\n type: \"list\",\n filters: { direction: \"created\" },\n },\n },\n ];\n\n // The capabilities/read endpoint requires path=\"all\" to match server routing\n const headers = self.invoke(\n self.session,\n \"capabilities\",\n \"all\",\n \"tinycloud.capabilities/read\",\n facts\n );\n\n const response = await self.fetchFn(`${self.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list delegations: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n // Server returns { [cid: string]: DelegationInfo } - validate and transform to Delegation[]\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerDelegationsResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const delegations = transformServerDelegations(validationResult.data, spaceId);\n return ok(delegations);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing delegations: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n\n async listReceived(): Promise<Result<Delegation[], ServiceError>> {\n // List incoming delegations (received by user) using tinycloud.capabilities/read\n try {\n // Facts contain the query params for the capabilities/read capability\n const facts = [\n {\n capabilitiesReadParams: {\n type: \"list\",\n filters: { direction: \"received\" },\n },\n },\n ];\n\n // The capabilities/read endpoint requires path=\"all\" to match server routing\n const headers = self.invoke(\n self.session,\n \"capabilities\",\n \"all\",\n \"tinycloud.capabilities/read\",\n facts\n );\n\n const response = await self.fetchFn(`${self.host}/invoke`, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to list received delegations: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n // Server returns { [cid: string]: DelegationInfo } - validate and transform to Delegation[]\n const rawData = await response.json();\n\n // Validate server response\n const validationResult = validateServerDelegationsResponse(rawData);\n if (!validationResult.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n validationResult.error.message,\n SERVICE_NAME,\n { meta: validationResult.error.meta }\n )\n );\n }\n\n const delegations = transformServerDelegations(validationResult.data, spaceId);\n return ok(delegations);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error listing received delegations: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n\n async create(\n params: Omit<CreateDelegationParams, \"spaceId\">\n ): Promise<Result<Delegation, ServiceError>> {\n // Use the platform-provided createDelegation function (SIWE-based flow)\n if (self.createDelegationFn) {\n return self.createDelegationFn({ ...params, spaceId });\n }\n\n // Fallback: return error if no createDelegation function provided\n // The old invoke-based approach doesn't work because /delegate expects\n // SIWE delegation headers, not invocation headers\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Delegation creation requires a createDelegation function. \" +\n \"This should be provided by the platform SDK (web-sdk or node-sdk).\",\n SERVICE_NAME\n )\n );\n },\n\n async revoke(cid: string): Promise<Result<void, ServiceError>> {\n try {\n const headers = self.invoke(\n self.session,\n \"delegation\",\n cid,\n \"tinycloud.delegation/revoke\"\n );\n\n const response = await self.fetchFn(`${self.host}/revoke`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ cid, spaceId }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Failed to revoke delegation: ${response.status} - ${errorText}`,\n SERVICE_NAME\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n `Network error revoking delegation: ${String(error)}`,\n SERVICE_NAME\n )\n );\n }\n },\n };\n }\n\n /**\n * Create space-scoped sharing operations.\n *\n * When a SharingService is configured, delegates to client-side v2 sharing.\n * V2 sharing links are self-contained with embedded private keys - no server tracking.\n */\n private createSpaceScopedSharing(spaceId: string): ISpaceScopedSharing {\n const self = this;\n\n return {\n async generate(\n params: Omit<GenerateShareParams, \"spaceId\">\n ): Promise<Result<ShareLink, ServiceError>> {\n // Use v2 SharingService when available (client-side sharing links)\n if (self.sharingService) {\n // Note: SharingService uses session.spaceId for the space.\n // For space-scoped sharing on delegated spaces, ensure the session\n // is configured for the correct space before calling generate().\n const result = await self.sharingService.generate(params);\n if (!result.ok) {\n return err(\n serviceError(\n SpaceErrorCodes.NETWORK_ERROR,\n result.error.message || \"Failed to generate share link\",\n SERVICE_NAME\n )\n );\n }\n return ok(result.data);\n }\n\n // Fallback: return error since server endpoint doesn't exist\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"SharingService not configured. V2 sharing requires a SharingService instance.\",\n SERVICE_NAME\n )\n );\n },\n\n async list(): Promise<Result<ShareLink[], ServiceError>> {\n // V2 sharing links are self-contained (not server-tracked)\n // This operation is not supported in the v2 spec\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Listing share links is not supported in v2. Share links are self-contained tokens that are not tracked on the server.\",\n SERVICE_NAME\n )\n );\n },\n\n async revoke(token: string): Promise<Result<void, ServiceError>> {\n // V2 sharing links are revoked by revoking the underlying delegation\n // This requires the delegation CID, not the share token\n return err(\n serviceError(\n SpaceErrorCodes.NOT_INITIALIZED,\n \"Revoking share links by token is not supported in v2. To revoke access, revoke the underlying delegation using space.delegations.revoke(cid).\",\n SERVICE_NAME\n )\n );\n },\n };\n }\n}\n\n/**\n * Create a new SpaceService instance.\n *\n * @param config - Service configuration\n * @returns A new SpaceService instance\n */\nexport function createSpaceService(config: SpaceServiceConfig): ISpaceService {\n return new SpaceService(config);\n}\n","/**\n * Space - Represents a scoped access point to a TinyCloud space.\n *\n * The Space object provides scoped access to services within a specific space,\n * whether owned by the user or delegated from another user.\n *\n * @packageDocumentation\n */\n\nimport type { IKVService, Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport type { SpaceInfo } from \"../delegations/types\";\n\n/**\n * Interface for space-scoped delegation operations.\n *\n * Provides delegation management scoped to a specific space.\n */\nexport interface ISpaceScopedDelegations {\n /**\n * List delegations created by the user in this space (outgoing).\n */\n list(): Promise<Result<import(\"../delegations/types\").Delegation[], ServiceError>>;\n\n /**\n * List delegations received by the user for this space (incoming).\n */\n listReceived(): Promise<Result<import(\"../delegations/types\").Delegation[], ServiceError>>;\n\n /**\n * Create a delegation within this space.\n */\n create(\n params: Omit<import(\"../delegations/types\").CreateDelegationParams, \"spaceId\">\n ): Promise<Result<import(\"../delegations/types\").Delegation, ServiceError>>;\n\n /**\n * Revoke a delegation within this space.\n */\n revoke(cid: string): Promise<Result<void, ServiceError>>;\n}\n\n/**\n * Interface for space-scoped sharing operations.\n *\n * Provides sharing link management scoped to a specific space.\n */\nexport interface ISpaceScopedSharing {\n /**\n * Generate a sharing link for a resource in this space.\n */\n generate(\n params: Omit<import(\"../delegations/types\").GenerateShareParams, \"spaceId\">\n ): Promise<Result<import(\"../delegations/types\").ShareLink, ServiceError>>;\n\n /**\n * List active sharing links in this space.\n */\n list(): Promise<Result<import(\"../delegations/types\").ShareLink[], ServiceError>>;\n\n /**\n * Revoke a sharing link.\n */\n revoke(token: string): Promise<Result<void, ServiceError>>;\n}\n\n/**\n * Interface for a Space object.\n *\n * Provides scoped access to services within a specific space.\n */\nexport interface ISpace {\n /**\n * The space identifier.\n */\n readonly id: string;\n\n /**\n * The short name of the space.\n */\n readonly name: string;\n\n /**\n * KV operations scoped to this space.\n */\n readonly kv: IKVService;\n\n /**\n * Delegation operations scoped to this space.\n */\n readonly delegations: ISpaceScopedDelegations;\n\n /**\n * Sharing operations scoped to this space.\n */\n readonly sharing: ISpaceScopedSharing;\n\n /**\n * Get space metadata.\n */\n info(): Promise<Result<SpaceInfo, ServiceError>>;\n}\n\n/**\n * Configuration for creating a Space object.\n */\nexport interface SpaceConfig {\n /**\n * The space identifier (full URI).\n */\n id: string;\n\n /**\n * The short name of the space.\n */\n name: string;\n\n /**\n * Factory function to create a space-scoped KV service.\n */\n createKV: (spaceId: string) => IKVService;\n\n /**\n * Factory function to create space-scoped delegations.\n */\n createDelegations: (spaceId: string) => ISpaceScopedDelegations;\n\n /**\n * Factory function to create space-scoped sharing.\n */\n createSharing: (spaceId: string) => ISpaceScopedSharing;\n\n /**\n * Function to get space info.\n */\n getInfo: (spaceId: string) => Promise<Result<SpaceInfo, ServiceError>>;\n}\n\n/**\n * Space - Provides scoped access to services within a specific space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // KV operations scoped to this space\n * await space.kv.put('key', 'value');\n * const result = await space.kv.get('key');\n *\n * // Delegation operations scoped to this space\n * await space.delegations.create({\n * delegateDID: 'did:pkh:eip155:1:0x...',\n * path: '/shared/',\n * actions: ['tinycloud.kv/get']\n * });\n *\n * // Get space metadata\n * const info = await space.info();\n * ```\n */\nexport class Space implements ISpace {\n private readonly _id: string;\n private readonly _name: string;\n private readonly _kv: IKVService;\n private readonly _delegations: ISpaceScopedDelegations;\n private readonly _sharing: ISpaceScopedSharing;\n private readonly _getInfo: (spaceId: string) => Promise<Result<SpaceInfo, ServiceError>>;\n\n /**\n * Create a new Space instance.\n *\n * @param config - Space configuration\n */\n constructor(config: SpaceConfig) {\n this._id = config.id;\n this._name = config.name;\n this._kv = config.createKV(config.id);\n this._delegations = config.createDelegations(config.id);\n this._sharing = config.createSharing(config.id);\n this._getInfo = config.getInfo;\n }\n\n /**\n * The space identifier (full URI).\n */\n get id(): string {\n return this._id;\n }\n\n /**\n * The short name of the space.\n */\n get name(): string {\n return this._name;\n }\n\n /**\n * KV operations scoped to this space.\n */\n get kv(): IKVService {\n return this._kv;\n }\n\n /**\n * Delegation operations scoped to this space.\n */\n get delegations(): ISpaceScopedDelegations {\n return this._delegations;\n }\n\n /**\n * Sharing operations scoped to this space.\n */\n get sharing(): ISpaceScopedSharing {\n return this._sharing;\n }\n\n /**\n * Get space metadata.\n *\n * @returns Result containing space information\n */\n async info(): Promise<Result<SpaceInfo, ServiceError>> {\n return this._getInfo(this._id);\n }\n}\n","/**\n * Zod schemas for Space and SpaceService configuration types.\n *\n * These schemas provide runtime validation for space management types.\n * Types are derived from schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport { CreateDelegationParamsSchema } from \"../delegations/types.schema.js\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError extends ServiceError {\n code: \"VALIDATION_ERROR\";\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// SpaceConfig Schema\n// =============================================================================\n\n/**\n * Configuration for creating a Space object.\n *\n * Contains the space identifier, name, and factory functions for creating\n * space-scoped services.\n */\nexport const SpaceConfigSchema = z.object({\n /** The space identifier (full URI) */\n id: z.string(),\n /** The short name of the space */\n name: z.string(),\n /** Factory function to create a space-scoped KV service */\n createKV: z.function(),\n /** Factory function to create space-scoped delegations */\n createDelegations: z.function(),\n /** Factory function to create space-scoped sharing */\n createSharing: z.function(),\n /** Function to get space info */\n getInfo: z.function(),\n});\n\nexport type SpaceConfig = z.infer<typeof SpaceConfigSchema>;\n\n// =============================================================================\n// SpaceServiceConfig Schema\n// =============================================================================\n\n/**\n * Configuration for SpaceService.\n *\n * Contains all the dependencies needed for the SpaceService to manage\n * spaces, including hosts, session, and factory functions.\n */\nexport const SpaceServiceConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string()),\n /** Active session for authentication */\n session: z.unknown(),\n /** Platform-specific invoke function */\n invoke: z.function(),\n /** Optional custom fetch implementation */\n fetch: z.function().optional(),\n /** Optional capability key registry for delegated space discovery */\n capabilityRegistry: z.unknown().optional(),\n /** Factory function to create a space-scoped KV service */\n createKVService: z.function().optional(),\n /** User's PKH DID (derived from address or provided explicitly) */\n userDid: z.string().optional(),\n /** Optional SharingService for v2 sharing links (client-side) */\n sharingService: z.unknown().optional(),\n /** Factory function to create delegations using SIWE-based flow */\n createDelegation: z.function().optional(),\n});\n\nexport type SpaceServiceConfig = z.infer<typeof SpaceServiceConfigSchema>;\n\n// =============================================================================\n// SpaceDelegationParams Schema\n// =============================================================================\n\n/**\n * Parameters for creating a space-scoped delegation.\n *\n * Extends CreateDelegationParams with the spaceId field.\n */\nexport const SpaceDelegationParamsSchema = CreateDelegationParamsSchema.extend({\n /** The space ID to create the delegation for */\n spaceId: z.string(),\n});\n\nexport type SpaceDelegationParams = z.infer<typeof SpaceDelegationParamsSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate a SpaceConfig object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceConfig(config);\n * if (result.ok) {\n * const space = new Space(result.data);\n * } else {\n * console.error(\"Invalid config:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceConfig(\n data: unknown\n): Result<SpaceConfig, ValidationError> {\n const result = SpaceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate a SpaceServiceConfig object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceServiceConfig(config);\n * if (result.ok) {\n * const service = new SpaceService(result.data);\n * } else {\n * console.error(\"Invalid config:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceServiceConfig(\n data: unknown\n): Result<SpaceServiceConfig, ValidationError> {\n const result = SpaceServiceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate a SpaceDelegationParams object against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const result = validateSpaceDelegationParams(params);\n * if (result.ok) {\n * await createDelegation(result.data);\n * } else {\n * console.error(\"Invalid params:\", result.error.message);\n * }\n * ```\n */\nexport function validateSpaceDelegationParams(\n data: unknown\n): Result<SpaceDelegationParams, ValidationError> {\n const result = SpaceDelegationParamsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n// =============================================================================\n// Server Response Schemas\n// =============================================================================\n\n/**\n * Server's DelegationInfo structure (from capabilities/read response).\n * This schema validates the shape of delegation data received from the server.\n */\nexport const ServerDelegationInfoSchema = z.object({\n /** DID of the delegator */\n delegator: z.string(),\n /** DID of the delegate */\n delegate: z.string(),\n /** Parent delegation CIDs - accepts string or byte array format from server */\n parents: z.array(z.union([z.string(), z.array(z.number())])),\n /** Expiration time (ISO8601 string) */\n expiry: z.string().optional(),\n /** Not-before time (ISO8601 string) */\n not_before: z.string().optional(),\n /** Issued-at time (ISO8601 string) */\n issued_at: z.string().optional(),\n /** Capabilities granted by this delegation */\n capabilities: z.array(\n z.object({\n resource: z.string(),\n ability: z.string(),\n })\n ),\n});\n\nexport type ServerDelegationInfo = z.infer<typeof ServerDelegationInfoSchema>;\n\n/**\n * Server response for capabilities/read endpoint.\n * Returns a record mapping CID -> DelegationInfo.\n */\nexport const ServerDelegationsResponseSchema = z.record(\n z.string(),\n ServerDelegationInfoSchema\n);\n\nexport type ServerDelegationsResponse = z.infer<typeof ServerDelegationsResponseSchema>;\n\n/**\n * Server response for space/list endpoint.\n * Returns an array of owned space info.\n */\nexport const ServerOwnedSpaceSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name (optional, can be derived from id) */\n name: z.string().optional(),\n /** Owner DID */\n owner: z.string(),\n /** Creation timestamp */\n createdAt: z.string().optional(),\n});\n\nexport type ServerOwnedSpace = z.infer<typeof ServerOwnedSpaceSchema>;\n\nexport const ServerOwnedSpacesResponseSchema = z.array(ServerOwnedSpaceSchema);\n\nexport type ServerOwnedSpacesResponse = z.infer<typeof ServerOwnedSpacesResponseSchema>;\n\n/**\n * Server response for space/create endpoint.\n */\nexport const ServerCreateSpaceResponseSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name */\n name: z.string(),\n /** Owner DID */\n owner: z.string(),\n /** Creation timestamp */\n createdAt: z.string().optional(),\n});\n\nexport type ServerCreateSpaceResponse = z.infer<typeof ServerCreateSpaceResponseSchema>;\n\n/**\n * Server response for space/info endpoint.\n */\nexport const ServerSpaceInfoResponseSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Space name (optional) */\n name: z.string().optional(),\n /** Owner DID */\n owner: z.string(),\n /** Ownership type */\n type: z.enum([\"owned\", \"delegated\"]).optional(),\n /** Permissions the user has in this space */\n permissions: z.array(z.string()).optional(),\n /** Expiration for delegated access */\n expiresAt: z.string().optional(),\n});\n\nexport type ServerSpaceInfoResponse = z.infer<typeof ServerSpaceInfoResponseSchema>;\n\n// =============================================================================\n// Server Response Validation Helpers\n// =============================================================================\n\n/**\n * Validate server delegations response (capabilities/read).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerDelegationsResponse(\n data: unknown\n): Result<ServerDelegationsResponse, ValidationError> {\n // Handle null/undefined as empty response\n if (data === null || data === undefined) {\n return { ok: true, data: {} };\n }\n\n // Handle array format (legacy compatibility) - return as-is, validation happens elsewhere\n if (Array.isArray(data)) {\n return { ok: true, data: {} };\n }\n\n const result = ServerDelegationsResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server delegations response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server owned spaces response (space/list).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerOwnedSpacesResponse(\n data: unknown\n): Result<ServerOwnedSpacesResponse, ValidationError> {\n const result = ServerOwnedSpacesResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server owned spaces response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server create space response (space/create).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerCreateSpaceResponse(\n data: unknown\n): Result<ServerCreateSpaceResponse, ValidationError> {\n const result = ServerCreateSpaceResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server create space response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate server space info response (space/info).\n *\n * @param data - Unknown data from server\n * @returns Result with validated data or validation error\n */\nexport function validateServerSpaceInfoResponse(\n data: unknown\n): Result<ServerSpaceInfoResponse, ValidationError> {\n const result = ServerSpaceInfoResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: `Invalid server space info response: ${result.error.message}`,\n service: \"space\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * Zod schemas for delegation management types.\n *\n * These schemas provide runtime validation for delegation, capability key management,\n * and sharing link functionality. Types are derived from schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type {\n FetchFunction,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\n\n// =============================================================================\n// Result Type (Generic)\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type and error type.\n * Result types provide explicit error handling instead of throwing.\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({ ok: z.literal(true), data: dataSchema }),\n z.object({ ok: z.literal(false), error: errorSchema }),\n ]);\n}\n\n/**\n * Result type pattern for delegation operations.\n */\nexport type Result<T, E = DelegationError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n// =============================================================================\n// JWK Type (JSON Web Key)\n// =============================================================================\n\n/**\n * JSON Web Key representation for cryptographic keys.\n * Follows the JWK specification (RFC 7517).\n */\nexport const JWKSchema = z.object({\n /** Key type (e.g., \"EC\", \"RSA\", \"OKP\") */\n kty: z.string(),\n /** Curve for EC/OKP keys (e.g., \"P-256\", \"Ed25519\") */\n crv: z.string().optional(),\n /** X coordinate for EC keys, public key for OKP */\n x: z.string().optional(),\n /** Y coordinate for EC keys */\n y: z.string().optional(),\n /** Private key value (d parameter) */\n d: z.string().optional(),\n /** Public exponent for RSA keys */\n e: z.string().optional(),\n /** Modulus for RSA keys */\n n: z.string().optional(),\n /** Key ID */\n kid: z.string().optional(),\n /** Algorithm */\n alg: z.string().optional(),\n /** Key use (e.g., \"sig\", \"enc\") */\n use: z.string().optional(),\n /** Key operations (e.g., [\"sign\", \"verify\"]) */\n key_ops: z.array(z.string()).optional(),\n});\n\nexport type JWK = z.infer<typeof JWKSchema>;\n\n// =============================================================================\n// Key Management Types\n// =============================================================================\n\n/**\n * Type of key in the capability registry.\n */\nexport const KeyTypeSchema = z.enum([\"main\", \"session\", \"ingested\"]);\nexport type KeyType = z.infer<typeof KeyTypeSchema>;\n\n/**\n * Information about a cryptographic key used for delegations.\n */\nexport const KeyInfoSchema = z.object({\n /** Unique identifier for this key */\n id: z.string(),\n /** DID associated with this key */\n did: z.string(),\n /** Type of key determining its authority level */\n type: KeyTypeSchema,\n /** Private key in JWK format */\n jwk: JWKSchema.optional(),\n /** Priority for key selection (lower = higher priority) */\n priority: z.number(),\n});\n\nexport type KeyInfo = z.infer<typeof KeyInfoSchema>;\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Error type for delegation operations.\n */\nexport const DelegationErrorSchema = z.object({\n /** Error code for programmatic handling */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** The service that produced the error */\n service: z.literal(\"delegation\"),\n /** Original error if wrapping another error */\n cause: z.instanceof(Error).optional(),\n /** Additional metadata about the error */\n meta: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type DelegationError = z.infer<typeof DelegationErrorSchema>;\n\n/**\n * Error codes for delegation operations.\n */\nexport const DelegationErrorCodes = {\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n NOT_INITIALIZED: \"NOT_INITIALIZED\",\n NOT_FOUND: \"NOT_FOUND\",\n REVOKED: \"REVOKED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n CREATION_FAILED: \"CREATION_FAILED\",\n REVOCATION_FAILED: \"REVOCATION_FAILED\",\n INVALID_TOKEN: \"INVALID_TOKEN\",\n KV_SERVICE_UNAVAILABLE: \"KV_SERVICE_UNAVAILABLE\",\n DATA_FETCH_FAILED: \"DATA_FETCH_FAILED\",\n VALIDATION_ERROR: \"VALIDATION_ERROR\",\n} as const;\n\nexport type DelegationErrorCode =\n (typeof DelegationErrorCodes)[keyof typeof DelegationErrorCodes];\n\n// =============================================================================\n// Delegation Types\n// =============================================================================\n\n/**\n * Represents a delegation from one DID to another.\n */\nexport const DelegationSchema = z.object({\n /** Content identifier (CID) of the delegation */\n cid: z.string(),\n /** DID of the delegate (the party receiving the delegation) */\n delegateDID: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /** Resource path this delegation grants access to */\n path: z.string(),\n /** Actions this delegation authorizes */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string from JSON) */\n expiry: z.coerce.date(),\n /** Whether this delegation has been revoked */\n isRevoked: z.boolean(),\n /** DID of the delegator (the party granting the delegation) */\n delegatorDID: z.string().optional(),\n /** When this delegation was created (accepts Date or ISO string from JSON) */\n createdAt: z.coerce.date().optional(),\n /** Parent delegation CID if this is a sub-delegation */\n parentCid: z.string().optional(),\n /** Whether sub-delegation is allowed */\n allowSubDelegation: z.boolean().optional(),\n /** Authorization header (UCAN bearer token) */\n authHeader: z.string().optional(),\n});\n\nexport type Delegation = z.infer<typeof DelegationSchema>;\n\n/**\n * Entry in the capability registry mapping a capability to available keys.\n */\nexport const CapabilityEntrySchema = z.object({\n /** Resource URI this capability applies to */\n resource: z.string(),\n /** Action this capability authorizes */\n action: z.string(),\n /** Keys that can exercise this capability, ordered by priority */\n keys: z.array(KeyInfoSchema),\n /** The delegation that grants this capability */\n delegation: DelegationSchema,\n /** When this capability expires (accepts Date or ISO string from JSON) */\n expiresAt: z.coerce.date().optional(),\n});\n\nexport type CapabilityEntry = z.infer<typeof CapabilityEntrySchema>;\n\n/**\n * Persistent record of a delegation stored in the system.\n */\nexport const DelegationRecordSchema = z.object({\n /** Content identifier (CID) of the delegation */\n cid: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /** DID of the delegator (grantor) */\n delegator: z.string(),\n /** DID of the delegatee (recipient) */\n delegatee: z.string(),\n /** Key ID used to sign/exercise this delegation */\n keyId: z.string().optional(),\n /** Resource path pattern this delegation grants access to */\n path: z.string(),\n /** Actions this delegation authorizes */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string from JSON) */\n expiry: z.coerce.date().optional(),\n /** When this delegation becomes valid (not before) (accepts Date or ISO string) */\n notBefore: z.coerce.date().optional(),\n /** Whether this delegation has been revoked */\n isRevoked: z.boolean(),\n /** When this delegation was created (accepts Date or ISO string from JSON) */\n createdAt: z.coerce.date(),\n /** Parent delegation CID if this is a sub-delegation */\n parentCid: z.string().optional(),\n});\n\nexport type DelegationRecord = z.infer<typeof DelegationRecordSchema>;\n\n/**\n * Parameters for creating a new delegation.\n */\nexport const CreateDelegationParamsSchema = z.object({\n /** DID of the delegate (the party receiving the delegation) */\n delegateDID: z.string(),\n /** Resource path this delegation grants access to */\n path: z.string(),\n /** Actions to authorize */\n actions: z.array(z.string()),\n /** When this delegation expires (accepts Date or ISO string) */\n expiry: z.coerce.date().optional(),\n /** Whether to disable sub-delegation */\n disableSubDelegation: z.boolean().optional(),\n /** Optional statement for the SIWE message */\n statement: z.string().optional(),\n});\n\nexport type CreateDelegationParams = z.infer<typeof CreateDelegationParamsSchema>;\n\n/**\n * A chain of delegations from root to leaf (array format).\n */\nexport const DelegationChainSchema = z.array(DelegationSchema);\nexport type DelegationChain = z.infer<typeof DelegationChainSchema>;\n\n/**\n * Structured delegation chain (v2 spec).\n */\nexport const DelegationChainV2Schema = z.object({\n /** The root delegation from the original authority */\n root: DelegationSchema,\n /** Intermediate delegations in the chain (may be empty) */\n chain: z.array(DelegationSchema),\n /** The final delegation to the current user */\n leaf: DelegationSchema,\n});\n\nexport type DelegationChainV2 = z.infer<typeof DelegationChainV2Schema>;\n\n// =============================================================================\n// Filtering and Query Types\n// =============================================================================\n\n/**\n * Direction of delegation to filter by.\n */\nexport const DelegationDirectionSchema = z.enum([\"granted\", \"received\", \"all\"]);\nexport type DelegationDirection = z.infer<typeof DelegationDirectionSchema>;\n\n/**\n * Filters for listing delegations.\n */\nexport const DelegationFiltersSchema = z.object({\n /** Filter by delegation direction */\n direction: DelegationDirectionSchema.optional(),\n /** Filter by resource path pattern */\n path: z.string().optional(),\n /** Filter by required actions */\n actions: z.array(z.string()).optional(),\n /** Include revoked delegations */\n includeRevoked: z.boolean().optional(),\n /** Filter by delegator DID */\n delegator: z.string().optional(),\n /** Filter by delegatee DID */\n delegatee: z.string().optional(),\n /** Only include delegations valid at this time */\n validAt: z.coerce.date().optional(),\n /** Maximum number of results to return */\n limit: z.number().optional(),\n /** Cursor for pagination */\n cursor: z.string().optional(),\n});\n\nexport type DelegationFilters = z.infer<typeof DelegationFiltersSchema>;\n\n// =============================================================================\n// Space Types\n// =============================================================================\n\n/**\n * Type of space ownership.\n */\nexport const SpaceOwnershipSchema = z.enum([\"owned\", \"delegated\"]);\nexport type SpaceOwnership = z.infer<typeof SpaceOwnershipSchema>;\n\n/**\n * Information about a space the user has access to.\n */\nexport const SpaceInfoSchema = z.object({\n /** Space identifier */\n id: z.string(),\n /** Human-readable name for the space */\n name: z.string().optional(),\n /** DID of the space owner */\n owner: z.string(),\n /** Whether user owns or has delegated access */\n type: SpaceOwnershipSchema,\n /** Permissions the user has in this space */\n permissions: z.array(z.string()).optional(),\n /** When the access expires (for delegated spaces) */\n expiresAt: z.coerce.date().optional(),\n});\n\nexport type SpaceInfo = z.infer<typeof SpaceInfoSchema>;\n\n// =============================================================================\n// Share Link Types\n// =============================================================================\n\n/**\n * Schema for encoding share link data.\n */\nexport const ShareSchemaSchema = z.enum([\"base64\", \"compact\", \"ipfs\"]);\nexport type ShareSchema = z.infer<typeof ShareSchemaSchema>;\n\n/**\n * A shareable link containing delegation credentials.\n */\nexport const ShareLinkSchema = z.object({\n /** Unique token identifying this share link */\n token: z.string(),\n /** Full URL for sharing */\n url: z.string(),\n /** The delegation this link grants access to */\n delegation: DelegationSchema,\n /** Encoding schema used for the link */\n schema: ShareSchemaSchema,\n /** When this share link expires */\n expiresAt: z.coerce.date().optional(),\n /** Human-readable description of what is being shared */\n description: z.string().optional(),\n});\n\nexport type ShareLink = z.infer<typeof ShareLinkSchema>;\n\n/**\n * Data retrieved from a share link.\n */\nexport function createShareLinkDataSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The retrieved data */\n data: dataSchema,\n /** The delegation that authorized this access */\n delegation: DelegationSchema,\n /** The space the data belongs to */\n spaceId: z.string(),\n /** The resource path that was accessed */\n path: z.string(),\n });\n}\n\nexport const ShareLinkDataSchema = createShareLinkDataSchema(z.unknown());\nexport type ShareLinkData<T = unknown> = {\n data: T;\n delegation: Delegation;\n spaceId: string;\n path: string;\n};\n\n// =============================================================================\n// Ingestion Types\n// =============================================================================\n\n/**\n * Options for ingesting an external delegation.\n */\nexport const IngestOptionsSchema = z.object({\n /** Whether to persist the delegation to storage */\n persist: z.boolean().optional(),\n /** Whether to validate the full delegation chain */\n validateChain: z.boolean().optional(),\n /** Name for the ingested key */\n keyName: z.string().optional(),\n /** Whether to create a session key for this delegation */\n createSessionKey: z.boolean().optional(),\n /** Override the priority for the ingested key */\n priority: z.number().optional(),\n});\n\nexport type IngestOptions = z.infer<typeof IngestOptionsSchema>;\n\n// =============================================================================\n// Parameter Types\n// =============================================================================\n\n/**\n * Parameters for generating a share link.\n */\nexport const GenerateShareParamsSchema = z.object({\n /** Resource path to share */\n path: z.string(),\n /** Actions to authorize */\n actions: z.array(z.string()).optional(),\n /** When the share link expires */\n expiry: z.coerce.date().optional(),\n /** Encoding schema for the link */\n schema: ShareSchemaSchema.optional(),\n /** Human-readable description */\n description: z.string().optional(),\n /** Base URL for the share link */\n baseUrl: z.string().optional(),\n});\n\nexport type GenerateShareParams = z.infer<typeof GenerateShareParamsSchema>;\n\n// =============================================================================\n// Configuration Types\n// =============================================================================\n\n// Note: These types include functions and external types which cannot be fully validated at runtime.\n// We use z.unknown().refine() for runtime type checking while preserving TypeScript types.\n\n/**\n * Configuration for DelegationManager.\n * Note: ServiceSession, InvokeFunction, and FetchFunction are external types.\n */\nexport const DelegationManagerConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string()),\n /** Active session for authentication */\n session: z.unknown().refine(\n (val): val is ServiceSession => val !== null && typeof val === \"object\",\n { message: \"Expected a ServiceSession object\" }\n ),\n /** Platform-specific invoke function */\n invoke: z.unknown().refine(\n (val): val is InvokeFunction => typeof val === \"function\",\n { message: \"Expected an invoke function\" }\n ),\n /** Optional custom fetch implementation */\n fetch: z.unknown().refine(\n (val): val is FetchFunction => val === undefined || typeof val === \"function\",\n { message: \"Expected a fetch function or undefined\" }\n ).optional(),\n});\n\nexport type DelegationManagerConfig = z.infer<typeof DelegationManagerConfigSchema>;\n\n/**\n * Provider interface for cryptographic key operations.\n */\nexport const KeyProviderSchema = z.object({\n /** Generate a new session key, returns key ID */\n createSessionKey: z.unknown().refine(\n (val): val is (name: string) => Promise<string> => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n /** Get JWK for a key */\n getJWK: z.unknown().refine(\n (val): val is (keyId: string) => object => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n /** Get DID for a key */\n getDID: z.unknown().refine(\n (val): val is (keyId: string) => Promise<string> => typeof val === \"function\",\n { message: \"Expected a function\" }\n ),\n});\n\nexport type KeyProvider = z.infer<typeof KeyProviderSchema>;\n\n// =============================================================================\n// API Response Types\n// =============================================================================\n\n/**\n * Response from the delegation API.\n */\nexport const DelegationApiResponseSchema = z.object({\n /** SIWE message content */\n siwe: z.string(),\n /** Signature of the SIWE message */\n signature: z.string(),\n /** Delegation version */\n version: z.number(),\n /** CID of the created delegation */\n cid: z.string().optional(),\n});\n\nexport type DelegationApiResponse = z.infer<typeof DelegationApiResponseSchema>;\n\n// =============================================================================\n// WASM Delegation Types\n// =============================================================================\n\n/**\n * A single (service, space, path, actions) entry inside a\n * createDelegation WASM result.\n *\n * Mirrors the Rust `DelegatedResource` struct in\n * `tinycloud-sdk-wasm/src/session.rs`. Field names match the manifest\n * {@link PermissionEntry} shape so callers can reconstruct what they sent\n * without having to re-parse the UCAN.\n *\n * `service` is the short form (e.g. `\"kv\"`, `\"sql\"`) as returned by the\n * Rust layer. The SDK layer translates to the long form\n * (`\"tinycloud.kv\"`) when comparing against manifests.\n */\nexport const DelegatedResourceSchema = z.object({\n /** Short-form service name, e.g. \"kv\", \"sql\", \"duckdb\", \"capabilities\", \"hooks\". */\n service: z.string(),\n /** Full space id string, e.g. \"tinycloud:pkh:eip155:1:0x....:default\". */\n space: z.string(),\n /** Resource path; empty string when the resource URI had no path segment. */\n path: z.string(),\n /** Full-URN ability strings, e.g. [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]. */\n actions: z.array(z.string()),\n});\n\nexport type DelegatedResource = z.infer<typeof DelegatedResourceSchema>;\n\n/**\n * Input parameters for the createDelegation WASM function.\n *\n * A single call may encode multiple `(service, path, actions)` entries\n * via the `abilities` map — the underlying UCAN will contain one\n * attenuation entry per `(service, path)` pair, all signed by the same\n * session key in one blob.\n *\n * The `abilities` shape is identical to what `prepareSession` accepts\n * (`Record<shortService, Record<path, actionURNs[]>>`), so manifest\n * resolution can feed both sides from one data structure.\n */\nexport const CreateDelegationWasmParamsSchema = z.object({\n /** The session containing delegation credentials */\n session: z.unknown().refine(\n (val): val is ServiceSession => val !== null && typeof val === \"object\",\n { message: \"Expected a ServiceSession object\" }\n ),\n /** DID of the delegate */\n delegateDID: z.string(),\n /** Space ID this delegation applies to */\n spaceId: z.string(),\n /**\n * Multi-resource abilities map: short-service → path → full-URN actions.\n * Matches the shape accepted by `prepareSession`.\n *\n * Example:\n * ```\n * {\n * kv: {\n * \"com.listen.app/\": [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]\n * },\n * sql: {\n * \"com.listen.app/data.sqlite\": [\"tinycloud.sql/read\"]\n * }\n * }\n * ```\n */\n abilities: z.record(z.string(), z.record(z.string(), z.array(z.string()))),\n /** Expiration time in seconds since Unix epoch */\n expirationSecs: z.number(),\n /** Optional not-before time in seconds since Unix epoch */\n notBeforeSecs: z.number().optional(),\n});\n\nexport type CreateDelegationWasmParams = z.infer<typeof CreateDelegationWasmParamsSchema>;\n\n/**\n * Result from the createDelegation WASM function.\n *\n * A single UCAN may cover multiple resources. The `resources` array\n * describes every `(service, space, path, actions)` entry granted, in\n * deterministic (service, path) lexicographic order (the Rust side sorts\n * the HashMap entries before signing).\n */\nexport const CreateDelegationWasmResultSchema = z.object({\n /** Base64url-encoded UCAN delegation */\n delegation: z.string(),\n /** CID of the delegation */\n cid: z.string(),\n /** DID of the delegate */\n delegateDID: z.string(),\n /** Expiration time */\n expiry: z.coerce.date(),\n /**\n * All (service, space, path, actions) entries granted by this delegation.\n * Always non-empty on success.\n */\n resources: z.array(DelegatedResourceSchema),\n});\n\nexport type CreateDelegationWasmResult = z.infer<typeof CreateDelegationWasmResultSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validates a Delegation object and returns a Result.\n */\nexport function validateDelegation(data: unknown): Result<Delegation, DelegationError> {\n const result = DelegationSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a CreateDelegationParams object and returns a Result.\n */\nexport function validateCreateDelegationParams(\n data: unknown\n): Result<CreateDelegationParams, DelegationError> {\n const result = CreateDelegationParamsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a DelegationFilters object and returns a Result.\n */\nexport function validateDelegationFilters(\n data: unknown\n): Result<DelegationFilters, DelegationError> {\n const result = DelegationFiltersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates a ShareLink object and returns a Result.\n */\nexport function validateShareLink(data: unknown): Result<ShareLink, DelegationError> {\n const result = ShareLinkSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Generic validation function factory.\n */\nexport function createValidator<T>(\n schema: z.ZodType<T>\n): (data: unknown) => Result<T, DelegationError> {\n return (data: unknown): Result<T, DelegationError> => {\n const result = schema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: result.error.message,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n };\n}\n","/**\n * Shared space utilities for TinyCloud.\n *\n * These functions are platform-agnostic and can be used by both\n * web-sdk and node-sdk for space hosting and session activation.\n */\n\n/**\n * Result of a space hosting or session activation attempt.\n */\nexport interface SpaceHostResult {\n /** Whether the operation succeeded (2xx status) */\n success: boolean;\n /** HTTP status code */\n status: number;\n /** Error message if failed */\n error?: string;\n /** Space IDs that were successfully activated */\n activated?: string[];\n /** Space IDs that were skipped (e.g., space doesn't exist yet) */\n skipped?: string[];\n}\n\n/**\n * Fetch the peer ID from TinyCloud server for space hosting.\n *\n * The peer ID identifies the TinyCloud server instance that will host the space.\n *\n * @param host - TinyCloud server URL (e.g., \"https://node.tinycloud.xyz\")\n * @param spaceId - The space ID to host\n * @returns The peer ID string\n * @throws Error if the request fails\n */\nexport async function fetchPeerId(\n host: string,\n spaceId: string\n): Promise<string> {\n const res = await fetch(\n `${host}/peer/generate/${encodeURIComponent(spaceId)}`\n );\n\n if (!res.ok) {\n const error = await res.text().catch(() => res.statusText);\n throw new Error(`Failed to get peer ID: ${res.status} - ${error}`);\n }\n\n return res.text();\n}\n\n/**\n * Submit a space hosting delegation to TinyCloud server.\n *\n * This registers a new space with the server, allowing the user\n * to store data in it.\n *\n * @param host - TinyCloud server URL\n * @param headers - Delegation headers (from siweToDelegationHeaders)\n * @returns Result indicating success/failure\n */\nexport async function submitHostDelegation(\n host: string,\n headers: Record<string, string>\n): Promise<SpaceHostResult> {\n const res = await fetch(`${host}/delegate`, {\n method: \"POST\",\n headers,\n });\n\n return {\n success: res.ok,\n status: res.status,\n error: res.ok ? undefined : await res.text().catch(() => res.statusText),\n };\n}\n\n/**\n * Activate a session with TinyCloud server.\n *\n * This submits the session delegation to the server, enabling the session\n * key to perform operations on behalf of the user.\n *\n * @param host - TinyCloud server URL\n * @param delegationHeader - Session delegation header (from session.delegationHeader)\n * @returns Result indicating success/failure (404 means space doesn't exist)\n */\nexport async function activateSessionWithHost(\n host: string,\n delegationHeader: { Authorization: string }\n): Promise<SpaceHostResult> {\n const res = await fetch(`${host}/delegate`, {\n method: \"POST\",\n headers: delegationHeader,\n });\n\n if (res.ok) {\n try {\n const body = await res.json() as { activated?: string[]; skipped?: string[] };\n return {\n success: true,\n status: res.status,\n activated: body.activated ?? [],\n skipped: body.skipped ?? [],\n };\n } catch {\n // Fallback for older servers that return plain text CID\n return {\n success: true,\n status: res.status,\n activated: [],\n skipped: [],\n };\n }\n }\n\n return {\n success: false,\n status: res.status,\n error: await res.text().catch(() => res.statusText),\n };\n}\n","/**\n * DelegationManager - Handles delegation CRUD operations.\n *\n * This class manages the creation, revocation, listing, and querying\n * of delegations within TinyCloud. It extracts and improves upon the\n * delegation functionality previously in ITinyCloudStorage.\n *\n * @packageDocumentation\n */\n\nimport type {\n FetchFunction,\n FetchResponse,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\nimport {\n Result,\n DelegationError,\n DelegationErrorCodes,\n Delegation,\n CreateDelegationParams,\n DelegationChain,\n DelegationManagerConfig,\n DelegationApiResponse,\n} from \"./types\";\n\n/**\n * Delegation action constants.\n */\nconst DelegationAction = {\n CREATE: \"tinycloud.delegation/create\",\n REVOKE: \"tinycloud.delegation/revoke\",\n LIST: \"tinycloud.delegation/list\",\n GET: \"tinycloud.delegation/get\",\n CHECK: \"tinycloud.delegation/check\",\n} as const;\n\n/**\n * Creates a DelegationError with the given parameters.\n */\nfunction createError(\n code: string,\n message: string,\n cause?: Error,\n meta?: Record<string, unknown>\n): DelegationError {\n return {\n code,\n message,\n service: \"delegation\",\n cause,\n meta,\n };\n}\n\n/**\n * DelegationManager handles all delegation-related operations.\n *\n * @example\n * ```typescript\n * import { DelegationManager } from \"@tinycloud/sdk-core/delegations\";\n *\n * const delegations = new DelegationManager({\n * hosts: [\"https://node.tinycloud.xyz\"],\n * session,\n * invoke,\n * });\n *\n * // Create a delegation\n * const result = await delegations.create({\n * delegateDID: \"did:pkh:eip155:1:0x...\",\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/list\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours\n * });\n *\n * if (result.ok) {\n * console.log(\"Created delegation:\", result.data.cid);\n * }\n * ```\n */\nexport class DelegationManager {\n private hosts: string[];\n private session: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n\n /**\n * Creates a new DelegationManager instance.\n *\n * @param config - Configuration including hosts, session, and invoke function\n */\n constructor(config: DelegationManagerConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Updates the session (e.g., after re-authentication).\n *\n * @param session - New session to use for operations\n */\n public updateSession(session: ServiceSession): void {\n this.session = session;\n }\n\n /**\n * Gets the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Executes an invoke operation against the delegation API.\n */\n private async invokeOperation(\n path: string,\n action: string,\n body?: string\n ): Promise<FetchResponse> {\n const headers = this.invoke(this.session, \"delegation\", path, action);\n\n return this.fetchFn(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n });\n }\n\n /**\n * Creates a new delegation.\n *\n * Delegates specific permissions to another DID for a given path.\n * The delegatee can then use these permissions to access resources\n * within the specified scope.\n *\n * @param params - Parameters for the delegation\n * @returns Result containing the created Delegation or an error\n *\n * @example\n * ```typescript\n * const result = await manager.create({\n * delegateDID: bob.did,\n * path: \"documents/shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days\n * });\n * ```\n */\n async create(params: CreateDelegationParams): Promise<Result<Delegation>> {\n // Validate inputs\n if (!params.delegateDID) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"delegateDID is required\"\n ),\n };\n }\n\n if (!params.path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n if (!params.actions || params.actions.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"at least one action is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({\n delegateDID: params.delegateDID,\n path: params.path,\n actions: params.actions,\n expiry: params.expiry?.toISOString(),\n disableSubDelegation: params.disableSubDelegation ?? false,\n statement: params.statement,\n });\n\n const response = await this.invokeOperation(\n params.path,\n DelegationAction.CREATE,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, path: params.path }\n ),\n };\n }\n\n const apiResponse = (await response.json()) as DelegationApiResponse;\n\n const delegation: Delegation = {\n cid: apiResponse.cid ?? \"\",\n delegateDID: params.delegateDID,\n spaceId: this.session.spaceId,\n path: params.path,\n actions: params.actions,\n expiry: params.expiry ?? new Date(Date.now() + 24 * 60 * 60 * 1000),\n isRevoked: false,\n allowSubDelegation: !(params.disableSubDelegation ?? false),\n createdAt: new Date(),\n };\n\n return { ok: true, data: delegation };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation creation: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Revokes an existing delegation.\n *\n * Once revoked, the delegation can no longer be used to access resources.\n * This also invalidates any sub-delegations derived from this delegation.\n *\n * @param cid - The CID of the delegation to revoke\n * @returns Result indicating success or an error\n *\n * @example\n * ```typescript\n * const result = await manager.revoke(\"bafy...\");\n * if (result.ok) {\n * console.log(\"Delegation revoked successfully\");\n * }\n * ```\n */\n async revoke(cid: string): Promise<Result<void>> {\n if (!cid) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"cid is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ cid });\n\n const response = await this.invokeOperation(\n cid,\n DelegationAction.REVOKE,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 404) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_FOUND,\n `Delegation not found: ${cid}`\n ),\n };\n }\n\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.REVOCATION_FAILED,\n `Failed to revoke delegation: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, cid }\n ),\n };\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation revocation: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Lists all delegations for the current session's space.\n *\n * Returns both delegations created by the current user (as delegator)\n * and delegations granted to the current user (as delegatee).\n *\n * @returns Result containing an array of Delegations or an error\n *\n * @example\n * ```typescript\n * const result = await manager.list();\n * if (result.ok) {\n * for (const delegation of result.data) {\n * console.log(`${delegation.cid}: ${delegation.path} -> ${delegation.delegateDID}`);\n * }\n * }\n * ```\n */\n async list(): Promise<Result<Delegation[]>> {\n try {\n const response = await this.invokeOperation(\"\", DelegationAction.LIST);\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to list delegations: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status }\n ),\n };\n }\n\n const data = (await response.json()) as Array<{\n cid: string;\n delegateDID: string;\n delegatorDID?: string;\n spaceId: string;\n path: string;\n actions: string[];\n expiry: string;\n isRevoked: boolean;\n createdAt?: string;\n parentCid?: string;\n allowSubDelegation?: boolean;\n }>;\n\n const delegations: Delegation[] = data.map((item) => ({\n cid: item.cid,\n delegateDID: item.delegateDID,\n delegatorDID: item.delegatorDID,\n spaceId: item.spaceId,\n path: item.path,\n actions: item.actions,\n expiry: new Date(item.expiry),\n isRevoked: item.isRevoked,\n createdAt: item.createdAt ? new Date(item.createdAt) : undefined,\n parentCid: item.parentCid,\n allowSubDelegation: item.allowSubDelegation,\n }));\n\n return { ok: true, data: delegations };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during delegation list: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Gets the full delegation chain for a given delegation.\n *\n * Returns the chain of delegations from the root (original delegator)\n * to the specified delegation, including all intermediate sub-delegations.\n *\n * @param cid - The CID of the delegation to get the chain for\n * @returns Result containing the DelegationChain or an error\n *\n * @example\n * ```typescript\n * const result = await manager.getChain(\"bafy...\");\n * if (result.ok) {\n * console.log(\"Chain length:\", result.data.length);\n * for (const delegation of result.data) {\n * console.log(`- ${delegation.delegatorDID} -> ${delegation.delegateDID}`);\n * }\n * }\n * ```\n */\n async getChain(cid: string): Promise<Result<DelegationChain>> {\n if (!cid) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"cid is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ cid, includeChain: true });\n\n const response = await this.invokeOperation(\n cid,\n DelegationAction.GET,\n body\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 404) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_FOUND,\n `Delegation not found: ${cid}`\n ),\n };\n }\n\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to get delegation chain: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, cid }\n ),\n };\n }\n\n const data = (await response.json()) as {\n chain: Array<{\n cid: string;\n delegateDID: string;\n delegatorDID?: string;\n spaceId: string;\n path: string;\n actions: string[];\n expiry: string;\n isRevoked: boolean;\n createdAt?: string;\n parentCid?: string;\n allowSubDelegation?: boolean;\n }>;\n };\n\n const chain: DelegationChain = data.chain.map((item) => ({\n cid: item.cid,\n delegateDID: item.delegateDID,\n delegatorDID: item.delegatorDID,\n spaceId: item.spaceId,\n path: item.path,\n actions: item.actions,\n expiry: new Date(item.expiry),\n isRevoked: item.isRevoked,\n createdAt: item.createdAt ? new Date(item.createdAt) : undefined,\n parentCid: item.parentCid,\n allowSubDelegation: item.allowSubDelegation,\n }));\n\n return { ok: true, data: chain };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during chain retrieval: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n\n /**\n * Checks if the current session has permission for a given path and action.\n *\n * This can be used to verify permissions before attempting an operation,\n * or to implement custom access control logic.\n *\n * @param path - The resource path to check\n * @param action - The action to check (e.g., \"tinycloud.kv/get\")\n * @returns Result containing a boolean indicating permission or an error\n *\n * @example\n * ```typescript\n * const result = await manager.checkPermission(\"documents/private/\", \"tinycloud.kv/put\");\n * if (result.ok && result.data) {\n * console.log(\"Permission granted\");\n * } else {\n * console.log(\"Permission denied\");\n * }\n * ```\n */\n async checkPermission(path: string, action: string): Promise<Result<boolean>> {\n if (!path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n if (!action) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"action is required\"\n ),\n };\n }\n\n try {\n const body = JSON.stringify({ path, action });\n\n const response = await this.invokeOperation(\n path,\n DelegationAction.CHECK,\n body\n );\n\n if (!response.ok) {\n // 403 means permission denied, which is a valid result\n if (response.status === 403) {\n return { ok: true, data: false };\n }\n\n const errorText = await response.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Failed to check permission: ${response.status} - ${errorText}`,\n undefined,\n { status: response.status, path, action }\n ),\n };\n }\n\n const data = (await response.json()) as { allowed: boolean };\n return { ok: true, data: data.allowed };\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.ABORTED,\n \"Request aborted\",\n error\n ),\n };\n }\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NETWORK_ERROR,\n `Network error during permission check: ${String(error)}`,\n error instanceof Error ? error : undefined\n ),\n };\n }\n }\n}\n","/**\n * Zod schemas for SharingService types.\n *\n * These schemas provide runtime validation for sharing link data,\n * receive options, and service configuration.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type {\n FetchFunction,\n IKVService,\n InvokeFunction,\n ServiceSession,\n} from \"@tinycloud/sdk-services\";\nimport {\n JWKSchema,\n DelegationSchema,\n KeyProviderSchema,\n IngestOptionsSchema,\n type Result,\n type DelegationError,\n DelegationErrorCodes,\n} from \"./types.schema.js\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry.js\";\nimport type { DelegationManager } from \"./DelegationManager.js\";\n\n// =============================================================================\n// EncodedShareData Schema\n// =============================================================================\n\n/**\n * Schema for data encoded in a sharing link.\n *\n * This is the primary validation point for external share link data.\n * The link is base64-decoded and JSON-parsed, then validated against this schema.\n */\nexport const EncodedShareDataSchema = z.object({\n /** Private key in JWK format (must include d parameter) */\n key: JWKSchema.refine(\n (jwk) => typeof jwk.d === \"string\" && jwk.d.length > 0,\n { message: \"JWK must include private key (d parameter)\" }\n ),\n /** DID of the key */\n keyDid: z.string().min(1, \"keyDid is required\"),\n /** The delegation granting access */\n delegation: DelegationSchema,\n /** Resource path this link grants access to */\n path: z.string().min(1, \"path is required\"),\n /** TinyCloud host URL */\n host: z.string().url(\"host must be a valid URL\"),\n /** Space ID */\n spaceId: z.string().min(1, \"spaceId is required\"),\n /** Schema version (must be 1) */\n version: z.literal(1),\n});\n\nexport type EncodedShareData = z.infer<typeof EncodedShareDataSchema>;\n\n// =============================================================================\n// ReceiveOptions Schema\n// =============================================================================\n\n/**\n * Schema for options when receiving a sharing link.\n */\nexport const ReceiveOptionsSchema = z.object({\n /**\n * Whether to automatically create a sub-delegation to the current session key.\n * Default: true\n */\n autoSubdelegate: z.boolean().optional(),\n /**\n * Whether to use the current session key for operations (requires autoSubdelegate).\n * Default: true\n */\n useSessionKey: z.boolean().optional(),\n /**\n * Ingestion options passed to CapabilityKeyRegistry.\n */\n ingestOptions: IngestOptionsSchema.optional(),\n});\n\nexport type ReceiveOptions = z.infer<typeof ReceiveOptionsSchema>;\n\n// =============================================================================\n// SharingServiceConfig Schema\n// =============================================================================\n\n/**\n * Schema for SharingService configuration.\n *\n * Note: Function fields use z.function() for shape validation only.\n * External types (ServiceSession, DelegationManager, ICapabilityKeyRegistry)\n * use z.unknown() with runtime type refinement.\n */\nexport const SharingServiceConfigSchema = z.object({\n /** TinyCloud host URLs */\n hosts: z.array(z.string().url()).min(1, \"At least one host URL is required\"),\n /**\n * Active session for authentication.\n * Required for generate(), optional for receive().\n */\n session: z\n .unknown()\n .refine(\n (val): val is ServiceSession =>\n val === undefined || (val !== null && typeof val === \"object\"),\n { message: \"Expected a ServiceSession object or undefined\" }\n )\n .optional(),\n /** Platform-specific invoke function */\n invoke: z\n .unknown()\n .refine((val): val is InvokeFunction => typeof val === \"function\", {\n message: \"Expected an invoke function\",\n }),\n /** Optional custom fetch implementation */\n fetch: z\n .unknown()\n .refine(\n (val): val is FetchFunction =>\n val === undefined || typeof val === \"function\",\n { message: \"Expected a fetch function or undefined\" }\n )\n .optional(),\n /** Key provider for cryptographic operations */\n keyProvider: KeyProviderSchema,\n /** Capability key registry for key/delegation management */\n registry: z\n .unknown()\n .refine(\n (val): val is ICapabilityKeyRegistry =>\n val !== null && typeof val === \"object\",\n { message: \"Expected an ICapabilityKeyRegistry object\" }\n ),\n /**\n * Delegation manager for creating delegations.\n * Required for generate(), optional for receive().\n */\n delegationManager: z\n .unknown()\n .refine(\n (val): val is DelegationManager =>\n val === undefined || (val !== null && typeof val === \"object\"),\n { message: \"Expected a DelegationManager object or undefined\" }\n )\n .optional(),\n /** Factory for creating KV service instances */\n createKVService: z.unknown().refine(\n (val): val is (config: {\n hosts: string[];\n session: ServiceSession;\n invoke: InvokeFunction;\n fetch?: FetchFunction;\n pathPrefix?: string;\n }) => IKVService => typeof val === \"function\",\n { message: \"Expected a createKVService factory function\" }\n ),\n /** Base URL for sharing links (e.g., \"https://share.myapp.com\") */\n baseUrl: z.string().optional(),\n /**\n * Custom delegation creation function.\n */\n createDelegation: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected a createDelegation function or undefined\",\n })\n .optional(),\n /**\n * WASM function for client-side delegation creation.\n */\n createDelegationWasm: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected a createDelegationWasm function or undefined\",\n })\n .optional(),\n /**\n * Path prefix for KV operations.\n */\n pathPrefix: z.string().optional(),\n /**\n * Session expiry time.\n */\n sessionExpiry: z.date().optional(),\n /**\n * Callback to create a DIRECT delegation from wallet to share key.\n * This is the preferred method for long-lived share links because it\n * bypasses the session delegation chain entirely.\n */\n onRootDelegationNeeded: z\n .unknown()\n .refine((val) => val === undefined || typeof val === \"function\", {\n message: \"Expected an onRootDelegationNeeded function or undefined\",\n })\n .optional(),\n});\n\nexport type SharingServiceConfig = z.infer<typeof SharingServiceConfigSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validates encoded share data from a decoded link.\n *\n * @param data - Unknown data to validate (from JSON.parse)\n * @returns Result with validated data or validation error\n *\n * @example\n * ```typescript\n * const parsed = JSON.parse(base64UrlDecode(linkData));\n * const result = validateEncodedShareData(parsed);\n * if (!result.ok) {\n * return result; // Forward the error\n * }\n * const shareData = result.data;\n * ```\n */\nexport function validateEncodedShareData(\n data: unknown\n): Result<EncodedShareData, DelegationError> {\n const result = EncodedShareDataSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid share data: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates receive options.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateReceiveOptions(\n data: unknown\n): Result<ReceiveOptions, DelegationError> {\n const result = ReceiveOptionsSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid receive options: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validates SharingService configuration.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateSharingServiceConfig(\n data: unknown\n): Result<SharingServiceConfig, DelegationError> {\n const result = SharingServiceConfigSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: DelegationErrorCodes.VALIDATION_ERROR,\n message: `Invalid SharingService config: ${result.error.message}`,\n service: \"delegation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * TinyCloud App Manifest\n *\n * A declarative description of an app's identity and the capabilities it\n * needs. The manifest drives the SIWE recap at sign-in time, enabling a\n * single wallet prompt that covers the app's own permissions plus any\n * pre-declared delegations.\n *\n * The SDK does NOT fetch external manifests. Apps compose their own manifest\n * (optionally including backend or agent addenda) before handing it to the\n * SDK.\n *\n * Canonical spec: `.claude/specs/manifest.md`.\n *\n * @packageDocumentation\n */\n\nimport ms from \"ms\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A single permission entry inside a manifest. This is the shape apps write\n * in their `manifest.json` and the shape we compare against when performing\n * the capability-subset derivability check in the delegation flow.\n *\n * `service` uses the long form (e.g. `\"tinycloud.kv\"`, `\"tinycloud.sql\"`)\n * which matches the ability-namespace half of the full action URN.\n */\nexport interface PermissionEntry {\n /** Service namespace, e.g. \"tinycloud.kv\", \"tinycloud.sql\", \"tinycloud.duckdb\", \"tinycloud.capabilities\". */\n service: string;\n /** \"default\" for the user's personal space, or a specific space id. */\n space: string;\n /**\n * Service-specific path.\n * - tinycloud.kv: hierarchical prefix. \"/\" = all, \"foo/\" = prefix match, \"foo\" = exact key\n * - tinycloud.sql: database name/file (e.g. \"data.sqlite\") or \"/\" for all\n * - tinycloud.duckdb: database name/file\n * - tinycloud.capabilities: capability key URI or \"/\" for all\n */\n path: string;\n /**\n * Short action names (e.g. \"get\", \"put\", \"read\", \"ddl\"). The SDK expands\n * these to full URNs (e.g. `tinycloud.kv/get`) during resolution.\n * Already-expanded URNs are passed through unchanged.\n */\n actions: string[];\n /** When true, the manifest prefix is NOT prepended to `path`. Default false. */\n skipPrefix?: boolean;\n /** Per-entry expiry override, ms-format. */\n expiry?: string;\n}\n\n/**\n * A pre-declared delegation that will be included in the main SIWE recap as\n * an additional audience.\n */\nexport interface ManifestDelegation {\n /** DID of the delegate (e.g. a backend's wallet DID). */\n to: string;\n /** Informational display name. Optional. */\n name?: string;\n /** Expiry override for this delegation, ms-format. Optional. */\n expiry?: string;\n /**\n * Permissions to delegate. Same shape as the top-level `permissions`, and\n * the manifest prefix is inherited identically (unless `skipPrefix: true`).\n */\n permissions: PermissionEntry[];\n}\n\n/**\n * The valid values for `Manifest.defaults`.\n *\n * - `false` → no auto-included permissions\n * - `true` → standard tier (KV + SQL read/write + capabilities:read)\n * - `\"admin\"` → standard + SQL ddl + capabilities:admin\n * - `\"all\"` → everything the SDK supports (including DuckDB)\n *\n * Unknown string values silently fall back to `true`. Values are normalized\n * (lowercase + trim) before matching.\n */\nexport type ManifestDefaults = boolean | \"admin\" | \"all\";\n\n/**\n * The raw manifest shape an app declares. See `.claude/specs/manifest.md`.\n */\nexport interface Manifest {\n /** Schema version. Optional, defaults to 1. */\n version?: number;\n /** Bundle identifier — reverse DNS. Required. */\n id: string;\n /** Display name. Required. */\n name: string;\n /** One-line description. Optional. */\n description?: string;\n /** URL to app icon. Optional. */\n icon?: string;\n /** App version string. Optional. */\n appVersion?: string;\n /** Default expiry for permissions. ms-format (\"30d\", \"2h\", \"1y\"). Default \"30d\". */\n expiry?: string;\n /**\n * Path prefix auto-prepended to permission paths. Optional, defaults to\n * `id`. Set to `\"\"` to disable entirely. Individual permissions can opt\n * out with `skipPrefix: true`.\n */\n prefix?: string;\n /**\n * Default permission set to auto-include. Optional, defaults to `true`.\n * See {@link ManifestDefaults}.\n */\n defaults?: ManifestDefaults | string;\n /** Whether to include the public-space companion delegation. Default `true`. */\n includePublicSpace?: boolean;\n /**\n * Additional permissions beyond the defaults. Use for cross-space access,\n * DuckDB (opt-in), or `skipPrefix: true` entries.\n */\n permissions?: PermissionEntry[];\n /** Pre-delegations to other DIDs at sign-in. */\n delegations?: ManifestDelegation[];\n}\n\n/**\n * A resolved permission entry with fully-expanded paths and action URNs.\n * This is the shape the delegation flow compares against parsed recap\n * capabilities, and the shape the session-key delegation path actually uses.\n */\nexport interface ResourceCapability {\n /** Long-form service, e.g. \"tinycloud.kv\". */\n service: string;\n /** Space id — \"default\" stays as-is here; the caller resolves it to a full SpaceId at sign-in time. */\n space: string;\n /** Path with the manifest prefix applied (or skipped per `skipPrefix`). */\n path: string;\n /** Full-URN actions, e.g. [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]. */\n actions: string[];\n /** Per-entry expiry override in milliseconds. */\n expiryMs?: number;\n}\n\n/**\n * A resolved delegation entry with fully-expanded permissions.\n */\nexport interface ResolvedDelegate {\n /** DID of the delegate. */\n did: string;\n /** Informational display name. Optional. */\n name?: string;\n /** Expiry in milliseconds (per-delegation > manifest default > 30 days). */\n expiryMs: number;\n /** Fully resolved permissions. */\n permissions: ResourceCapability[];\n}\n\n/**\n * The output of {@link resolveManifest}: a fully-expanded capability set\n * ready to drive the SIWE recap.\n */\nexport interface ResolvedCapabilities {\n /** Bundle identifier copied from manifest.id. */\n id: string;\n /** All session-key resources with paths fully resolved (prefix applied). */\n resources: ResourceCapability[];\n /** Default expiry for the session, in milliseconds. */\n expiryMs: number;\n /** Whether to include the public-space companion. */\n includePublicSpace: boolean;\n /** Additional delegate targets with resolved paths. */\n additionalDelegates: ResolvedDelegate[];\n}\n\n/**\n * Thrown when the manifest fails validation (missing id/name, bad expiry,\n * empty actions on a permission, etc).\n */\nexport class ManifestValidationError extends Error {\n constructor(message: string) {\n super(`Manifest validation failed: ${message}`);\n this.name = \"ManifestValidationError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default expiry when neither the manifest, delegation, nor permission\n * specifies one. Spec: 30 days.\n */\nexport const DEFAULT_EXPIRY = \"30d\";\n\n/**\n * Default `defaults` value when the manifest omits it. Spec: standard tier.\n */\nexport const DEFAULT_DEFAULTS: ManifestDefaults = true;\n\n/**\n * Known services and their short-form (recap URI) names. The TinyCloud\n * node encodes the recap resource URI with the short service name, while\n * action URNs and manifest entries use the long `tinycloud.<short>` form.\n * This table is the canonical bridge between the two.\n */\nexport const SERVICE_SHORT_TO_LONG: Readonly<Record<string, string>> =\n Object.freeze({\n kv: \"tinycloud.kv\",\n sql: \"tinycloud.sql\",\n duckdb: \"tinycloud.duckdb\",\n capabilities: \"tinycloud.capabilities\",\n hooks: \"tinycloud.hooks\",\n });\n\n/**\n * Inverse of {@link SERVICE_SHORT_TO_LONG}.\n */\nexport const SERVICE_LONG_TO_SHORT: Readonly<Record<string, string>> =\n Object.freeze(\n Object.fromEntries(\n Object.entries(SERVICE_SHORT_TO_LONG).map(([s, l]) => [l, s])\n )\n );\n\n/**\n * Default permission entries for the `true` / standard tier.\n *\n * `tinycloud.capabilities:read` is ALWAYS present in any non-false default\n * so delegation chains can be verified.\n */\nconst DEFAULT_STANDARD_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] =\n [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\"],\n },\n ];\n\n/**\n * Default permission entries for the `\"admin\"` tier: standard + sql/ddl +\n * capabilities/admin.\n */\nconst DEFAULT_ADMIN_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] = [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\", \"ddl\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"admin\"],\n },\n];\n\n/**\n * Default permission entries for the `\"all\"` tier: admin + DuckDB.\n *\n * DuckDB is opt-in and only appears in this tier or in explicit manifest\n * `permissions` entries.\n */\nconst DEFAULT_ALL_ENTRIES: readonly Omit<PermissionEntry, \"skipPrefix\">[] = [\n {\n service: \"tinycloud.kv\",\n space: \"default\",\n path: \"/\",\n actions: [\"get\", \"put\", \"del\", \"list\", \"metadata\"],\n },\n {\n service: \"tinycloud.sql\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\", \"ddl\"],\n },\n {\n service: \"tinycloud.duckdb\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"write\"],\n },\n {\n service: \"tinycloud.capabilities\",\n space: \"default\",\n path: \"/\",\n actions: [\"read\", \"admin\"],\n },\n];\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an ms-format duration string (e.g. \"30d\", \"2h\", \"1y\") into\n * milliseconds.\n *\n * @throws {ManifestValidationError} on empty string, non-string input, or\n * any input `ms()` cannot parse.\n */\nexport function parseExpiry(duration: string): number {\n if (typeof duration !== \"string\" || duration.length === 0) {\n throw new ManifestValidationError(\n `expiry must be a non-empty duration string (got ${JSON.stringify(duration)})`\n );\n }\n // `ms` returns `undefined` for unparseable input and can return a number\n // or a string depending on the call signature; cast explicitly.\n const parsed = (ms as unknown as (v: string) => number | undefined)(\n duration\n );\n if (typeof parsed !== \"number\" || !Number.isFinite(parsed) || parsed <= 0) {\n throw new ManifestValidationError(\n `invalid expiry duration: ${JSON.stringify(duration)}`\n );\n }\n return parsed;\n}\n\n/**\n * Expand a list of action short names (or already-expanded URNs) into full\n * ability URNs of the form `<service>/<action>`.\n *\n * Examples:\n * `expandActionShortNames(\"tinycloud.kv\", [\"get\", \"put\"])`\n * → `[\"tinycloud.kv/get\", \"tinycloud.kv/put\"]`\n * `expandActionShortNames(\"tinycloud.kv\", [\"tinycloud.kv/get\"])`\n * → `[\"tinycloud.kv/get\"]` (passed through unchanged)\n */\nexport function expandActionShortNames(\n service: string,\n actions: readonly string[]\n): string[] {\n return actions.map((a) => {\n if (a.includes(\"/\")) {\n // Already a full URN — pass through.\n return a;\n }\n return `${service}/${a}`;\n });\n}\n\n/**\n * Apply the manifest prefix to a permission path per the spec rules.\n *\n * - `skipPrefix: true` → path is returned as-is\n * - `prefix === \"\"` → path is returned as-is\n * - path starts with \"/\" → `prefix + path` (e.g. \"com.listen.app\" + \"/\" → \"com.listen.app/\")\n * - otherwise → `prefix + \"/\" + path` (e.g. \"com.listen.app\" + \"data.sqlite\" → \"com.listen.app/data.sqlite\")\n */\nexport function applyPrefix(\n prefix: string,\n path: string,\n skipPrefix: boolean\n): string {\n if (skipPrefix) {\n return path;\n }\n if (prefix === \"\") {\n return path;\n }\n if (path.startsWith(\"/\")) {\n return `${prefix}${path}`;\n }\n return `${prefix}/${path}`;\n}\n\n/**\n * Fetch and parse a manifest from a URL (browser) or file path (node).\n * The runtime decides the fetch strategy via `globalThis.fetch`; this is\n * platform-agnostic. Callers that want custom loading should JSON.parse a\n * Manifest themselves and skip this helper.\n *\n * @throws if the fetch fails, the JSON is invalid, or the manifest fails\n * validation.\n */\nexport async function loadManifest(url: string): Promise<Manifest> {\n const fetchFn: typeof fetch | undefined = (globalThis as { fetch?: typeof fetch }).fetch;\n if (typeof fetchFn !== \"function\") {\n throw new ManifestValidationError(\n \"loadManifest requires a global fetch; pass the manifest object directly on runtimes without fetch\"\n );\n }\n const res = await fetchFn(url);\n if (!res.ok) {\n throw new ManifestValidationError(\n `failed to fetch manifest from ${url}: HTTP ${res.status}`\n );\n }\n const json = (await res.json()) as unknown;\n return validateManifest(json);\n}\n\n/**\n * Validate a manifest-shaped object and return it strongly-typed.\n * Throws {@link ManifestValidationError} on any hard failure.\n */\nexport function validateManifest(input: unknown): Manifest {\n if (input === null || typeof input !== \"object\") {\n throw new ManifestValidationError(\"manifest must be an object\");\n }\n const m = input as Manifest;\n if (typeof m.id !== \"string\" || m.id.length === 0) {\n throw new ManifestValidationError(\"manifest.id is required and must be a non-empty string\");\n }\n if (typeof m.name !== \"string\" || m.name.length === 0) {\n throw new ManifestValidationError(\"manifest.name is required and must be a non-empty string\");\n }\n if (m.expiry !== undefined) {\n // Will throw with a clear error if invalid.\n parseExpiry(m.expiry);\n }\n if (m.permissions !== undefined) {\n if (!Array.isArray(m.permissions)) {\n throw new ManifestValidationError(\"manifest.permissions must be an array\");\n }\n m.permissions.forEach((p, i) =>\n validatePermissionEntry(p, `permissions[${i}]`)\n );\n }\n if (m.delegations !== undefined) {\n if (!Array.isArray(m.delegations)) {\n throw new ManifestValidationError(\"manifest.delegations must be an array\");\n }\n m.delegations.forEach((d, i) => {\n if (typeof d?.to !== \"string\" || d.to.length === 0) {\n throw new ManifestValidationError(\n `delegations[${i}].to is required and must be a non-empty DID string`\n );\n }\n if (d.expiry !== undefined) {\n parseExpiry(d.expiry);\n }\n if (!Array.isArray(d.permissions)) {\n throw new ManifestValidationError(\n `delegations[${i}].permissions must be an array`\n );\n }\n d.permissions.forEach((p, j) =>\n validatePermissionEntry(p, `delegations[${i}].permissions[${j}]`)\n );\n });\n }\n return m;\n}\n\nfunction validatePermissionEntry(p: unknown, path: string): void {\n if (p === null || typeof p !== \"object\") {\n throw new ManifestValidationError(`${path} must be an object`);\n }\n const entry = p as PermissionEntry;\n if (typeof entry.service !== \"string\" || entry.service.length === 0) {\n throw new ManifestValidationError(`${path}.service is required`);\n }\n if (typeof entry.space !== \"string\" || entry.space.length === 0) {\n throw new ManifestValidationError(`${path}.space is required`);\n }\n if (typeof entry.path !== \"string\") {\n throw new ManifestValidationError(\n `${path}.path is required (use \"\" or \"/\" for root)`\n );\n }\n if (!Array.isArray(entry.actions) || entry.actions.length === 0) {\n throw new ManifestValidationError(\n `${path}.actions must be a non-empty array`\n );\n }\n if (entry.expiry !== undefined) {\n parseExpiry(entry.expiry);\n }\n}\n\n/**\n * Normalize a `defaults` value: lowercase + trim, then match against known\n * tiers. Unknown string values silently fall back to `true` (standard).\n * Boolean values pass through.\n */\nexport function normalizeDefaults(\n value: Manifest[\"defaults\"] | undefined\n): ManifestDefaults {\n if (value === undefined) {\n return DEFAULT_DEFAULTS;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value !== \"string\") {\n // Spec says unknown values silently fall back to `true`.\n return true;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === \"admin\" || normalized === \"all\") {\n return normalized;\n }\n // Anything else, including \"true\"/\"false\"/\"standard\"/garbage, falls back\n // to the standard tier per spec.\n return true;\n}\n\n/**\n * Return the default permission entries for the given tier. Entries are\n * deep-cloned so callers can mutate them without affecting the constants.\n */\nfunction defaultEntriesForTier(\n tier: ManifestDefaults\n): PermissionEntry[] {\n if (tier === false) {\n return [];\n }\n const source =\n tier === \"admin\"\n ? DEFAULT_ADMIN_ENTRIES\n : tier === \"all\"\n ? DEFAULT_ALL_ENTRIES\n : DEFAULT_STANDARD_ENTRIES;\n return source.map((e) => ({\n service: e.service,\n space: e.space,\n path: e.path,\n actions: [...e.actions],\n }));\n}\n\n/**\n * Resolve a raw manifest into a {@link ResolvedCapabilities} object: expand\n * shortform actions, apply the prefix, merge defaults, and compute effective\n * expiries. Pure function — does no I/O.\n *\n * Resolution semantics (spec):\n * - `prefix` defaults to `id`; set to `\"\"` to disable prefix application entirely.\n * - `defaults` defaults to `true` (standard tier); unknown string values fall back to `true`.\n * - Per-entry expiry overrides per-delegation overrides manifest > `DEFAULT_EXPIRY`.\n * - Default entries use `skipPrefix: false` so they inherit the manifest prefix.\n * - Prefix inheritance applies identically to `permissions` and `delegations[*].permissions`.\n */\nexport function resolveManifest(\n input: Manifest\n): ResolvedCapabilities {\n const manifest = validateManifest(input);\n\n const prefix = manifest.prefix !== undefined ? manifest.prefix : manifest.id;\n const expiryMs = parseExpiry(manifest.expiry ?? DEFAULT_EXPIRY);\n const includePublicSpace = manifest.includePublicSpace ?? true;\n const tier = normalizeDefaults(manifest.defaults);\n\n const defaultEntries = defaultEntriesForTier(tier);\n const explicitEntries = manifest.permissions ?? [];\n\n // Merge order: defaults first, then explicit entries, so explicit entries\n // for the same (service, space, path) tuple override defaults.\n const allEntries: PermissionEntry[] = [...defaultEntries, ...explicitEntries];\n\n const resources: ResourceCapability[] = allEntries.map((entry) =>\n resolveEntry(entry, prefix, expiryMs)\n );\n\n const additionalDelegates: ResolvedDelegate[] = (\n manifest.delegations ?? []\n ).map((d) => ({\n did: d.to,\n name: d.name,\n expiryMs: parseExpiry(d.expiry ?? manifest.expiry ?? DEFAULT_EXPIRY),\n permissions: d.permissions.map((entry) =>\n resolveEntry(\n entry,\n prefix,\n parseExpiry(d.expiry ?? manifest.expiry ?? DEFAULT_EXPIRY)\n )\n ),\n }));\n\n return {\n id: manifest.id,\n resources,\n expiryMs,\n includePublicSpace,\n additionalDelegates,\n };\n}\n\n/**\n * Expand a single permission entry into a {@link ResourceCapability}:\n * apply the prefix to the path and expand short actions into full URNs.\n */\nfunction resolveEntry(\n entry: PermissionEntry,\n prefix: string,\n _inheritedExpiryMs: number\n): ResourceCapability {\n const resolvedPath = applyPrefix(\n prefix,\n entry.path,\n entry.skipPrefix === true\n );\n const resolvedActions = expandActionShortNames(entry.service, entry.actions);\n const entryExpiryMs =\n entry.expiry !== undefined ? parseExpiry(entry.expiry) : undefined;\n return {\n service: entry.service,\n space: entry.space,\n path: resolvedPath,\n actions: resolvedActions,\n // Only populate `expiryMs` when the entry had its own expiry override.\n // When absent, callers use the parent (delegation or manifest) expiry\n // which is carried on ResolvedDelegate.expiryMs / ResolvedCapabilities.expiryMs.\n ...(entryExpiryMs !== undefined ? { expiryMs: entryExpiryMs } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Abilities map construction (bridge to WASM prepareSession / createDelegation)\n// ---------------------------------------------------------------------------\n\n/**\n * The shape `prepareSession` and the multi-resource `createDelegation` WASM\n * export both accept:\n *\n * ```\n * { [shortService]: { [path]: [fullUrnAction, ...] } }\n * ```\n *\n * - `shortService` is the recap-level service segment (`\"kv\"`, `\"sql\"`,\n * `\"duckdb\"`, `\"capabilities\"`, `\"hooks\"`) — not the manifest long form.\n * - `path` is the fully-resolved path (prefix already applied). An empty\n * string means \"no path segment\" on the resource URI.\n * - Action strings are full URNs like `\"tinycloud.kv/get\"`.\n *\n * This is a single source of truth for both the session's own recap (at\n * sign-in) and the delegations it can derive (post sign-in). We re-use it\n * for both so one manifest drives both sides.\n */\nexport type AbilitiesMap = Record<string, Record<string, string[]>>;\n\n/**\n * Convert a list of {@link ResourceCapability} entries (manifest\n * long-form service, full-URN actions) into the {@link AbilitiesMap}\n * shape the WASM layer expects.\n *\n * When multiple entries target the same `(service, path)` pair, their\n * action lists are merged and deduped. Entries whose service has no\n * short-form mapping in {@link SERVICE_LONG_TO_SHORT} are rejected with\n * a {@link ManifestValidationError} — the SDK does not silently drop\n * unknown services because the recap encoding would lose them.\n *\n * Paths are kept verbatim: this function does NOT collapse\n * `\"com.listen.app/\"` and `\"com.listen.app\"` or reinterpret empty /\n * slash strings. Callers that care about path canonicalization should\n * normalize before calling.\n */\nexport function resourceCapabilitiesToAbilitiesMap(\n resources: readonly ResourceCapability[]\n): AbilitiesMap {\n const out: AbilitiesMap = {};\n for (const r of resources) {\n const shortService = SERVICE_LONG_TO_SHORT[r.service];\n if (shortService === undefined) {\n throw new ManifestValidationError(\n `unknown service '${r.service}' — no short-form mapping. Known services: ${Object.keys(SERVICE_LONG_TO_SHORT).join(\", \")}`\n );\n }\n if (out[shortService] === undefined) {\n out[shortService] = {};\n }\n const pathsMap = out[shortService];\n const existing = pathsMap[r.path];\n if (existing === undefined) {\n // Copy so downstream mutation can't leak back into the input.\n pathsMap[r.path] = [...r.actions];\n } else {\n // Merge + dedupe while preserving first-seen order.\n const seen = new Set(existing);\n for (const action of r.actions) {\n if (!seen.has(action)) {\n existing.push(action);\n seen.add(action);\n }\n }\n }\n }\n return out;\n}\n\n/**\n * Build the {@link AbilitiesMap} that a session should be signed with,\n * given a {@link ResolvedCapabilities} (i.e. the output of\n * {@link resolveManifest}).\n *\n * The resulting map is the **union** of:\n * 1. the app's own resources (`resolved.resources`), and\n * 2. every permission declared in every `additionalDelegates[*]` entry.\n *\n * The union is what makes the manifest's delegations ergonomic: at\n * sign-in, the session key acquires recap coverage for both the app's\n * runtime needs and every downstream delegation target. Post sign-in,\n * `delegateTo(backendDID, backendPermissions)` can then issue the\n * sub-delegation via the session key (no wallet prompt) because the\n * caps are already part of the granted set.\n *\n * Duplicate `(service, path, action)` triples across resources and\n * delegations are merged and deduped — the session SIWE doesn't need\n * them repeated.\n */\nexport function manifestAbilitiesUnion(\n resolved: ResolvedCapabilities\n): AbilitiesMap {\n const all: ResourceCapability[] = [...resolved.resources];\n for (const delegate of resolved.additionalDelegates) {\n for (const perm of delegate.permissions) {\n all.push(perm);\n }\n }\n return resourceCapabilitiesToAbilitiesMap(all);\n}\n","/**\n * SharingService - v2 sharing link service with embedded private keys.\n *\n * This service implements the v2 sharing specification, which embeds private keys\n * directly in sharing links. This allows recipients to exercise delegations\n * without requiring prior session setup.\n *\n * Key differences from v1 SharingLinks:\n * - Private keys are embedded in the link (not just tokens)\n * - Recipients can optionally sub-delegate to their own session key\n * - Pre-configured KV service returned for immediate use\n *\n * @packageDocumentation\n */\n\nimport type {\n IKVService,\n ServiceSession,\n InvokeFunction,\n FetchFunction,\n} from \"@tinycloud/sdk-services\";\nimport type {\n Result,\n DelegationError,\n Delegation,\n KeyInfo,\n KeyProvider,\n GenerateShareParams,\n ShareLink,\n ShareLinkData,\n ShareSchema,\n JWK,\n IngestOptions,\n CreateDelegationParams,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n} from \"./types\";\nimport { DelegationErrorCodes } from \"./types\";\nimport type { DelegationManager } from \"./DelegationManager\";\nimport type { ICapabilityKeyRegistry } from \"../authorization/CapabilityKeyRegistry\";\nimport { validateEncodedShareData } from \"./SharingService.schema.js\";\nimport { SERVICE_LONG_TO_SHORT } from \"../manifest\";\n\n// ---------------------------------------------------------------------------\n// Local helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Infer the short-form service name (`\"kv\"`, `\"sql\"`, etc) that all of the\n * given full-URN action strings belong to.\n *\n * SharingService issues single-service delegations (KV-only, SQL-only, …) —\n * the multi-resource WASM `createDelegation` call requires the service\n * segment explicitly because it's keyed separately from the action list.\n * This helper extracts the namespace half (`\"tinycloud.kv\"`) from each URN,\n * maps it to the short form via {@link SERVICE_LONG_TO_SHORT}, and returns\n * `undefined` if the actions are not all from the same known service.\n *\n * Returning `undefined` is intentional: the caller must surface a clear\n * error rather than guessing.\n */\nfunction inferShortServiceFromActionUrns(\n actions: readonly string[]\n): string | undefined {\n let short: string | undefined;\n for (const action of actions) {\n const slash = action.indexOf(\"/\");\n if (slash === -1) return undefined;\n const longService = action.slice(0, slash);\n const candidate = SERVICE_LONG_TO_SHORT[longService];\n if (candidate === undefined) return undefined;\n if (short === undefined) {\n short = candidate;\n } else if (short !== candidate) {\n return undefined;\n }\n }\n return short;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default actions for read-only sharing links.\n */\nconst DEFAULT_READ_ACTIONS = [\"tinycloud.kv/get\", \"tinycloud.kv/metadata\"];\n\n/**\n * Default expiry for sharing links (24 hours).\n */\nconst DEFAULT_EXPIRY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Prefix for the base64 schema.\n */\nconst BASE64_PREFIX = \"tc1:\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Creates a DelegationError with the given parameters.\n */\nfunction createError(\n code: string,\n message: string,\n cause?: Error,\n meta?: Record<string, unknown>\n): DelegationError {\n return {\n code,\n message,\n service: \"delegation\",\n cause,\n meta,\n };\n}\n\n/**\n * Base64 encode for URLs (URL-safe base64).\n */\nfunction base64UrlEncode(data: string): string {\n // Use btoa for browser, Buffer for Node.js\n let base64: string;\n if (typeof btoa !== \"undefined\") {\n base64 = btoa(unescape(encodeURIComponent(data)));\n } else if (typeof Buffer !== \"undefined\") {\n base64 = Buffer.from(data, \"utf-8\").toString(\"base64\");\n } else {\n throw new Error(\"No base64 encoding available\");\n }\n // Make URL-safe\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * Base64 decode for URLs (URL-safe base64).\n */\nfunction base64UrlDecode(encoded: string): string {\n // Restore standard base64\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n // Decode\n if (typeof atob !== \"undefined\") {\n return decodeURIComponent(escape(atob(base64)));\n } else if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\").toString(\"utf-8\");\n } else {\n throw new Error(\"No base64 decoding available\");\n }\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Data encoded in a sharing link.\n */\nexport interface EncodedShareData {\n /** Private key in JWK format (includes d parameter) */\n key: JWK;\n /** DID of the key */\n keyDid: string;\n /** The delegation granting access */\n delegation: Delegation;\n /** Resource path this link grants access to */\n path: string;\n /** TinyCloud host URL */\n host: string;\n /** Space ID */\n spaceId: string;\n /** Schema version */\n version: 1;\n}\n\n/**\n * Options for receiving a sharing link.\n */\nexport interface ReceiveOptions {\n /**\n * Whether to automatically create a sub-delegation to the current session key.\n * Default: true\n */\n autoSubdelegate?: boolean;\n /**\n * Whether to use the current session key for operations (requires autoSubdelegate).\n * Default: true\n */\n useSessionKey?: boolean;\n /**\n * Ingestion options passed to CapabilityKeyRegistry.\n */\n ingestOptions?: IngestOptions;\n}\n\n/**\n * Result of receiving a sharing link.\n */\nexport interface ShareAccess {\n /** The delegation that was received/created */\n delegation: Delegation;\n /** Key info for the received key */\n key: KeyInfo;\n /** Pre-configured KV service for the shared path */\n kv: IKVService;\n /** The space ID */\n spaceId: string;\n /** The path prefix for this share */\n path: string;\n}\n\n/**\n * Configuration for SharingService.\n */\nexport interface SharingServiceConfig {\n /** TinyCloud host URLs */\n hosts: string[];\n /**\n * Active session for authentication.\n * Required for generate(), optional for receive().\n */\n session?: ServiceSession;\n /** Platform-specific invoke function */\n invoke: InvokeFunction;\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n /** Key provider for cryptographic operations */\n keyProvider: KeyProvider;\n /** Capability key registry for key/delegation management */\n registry: ICapabilityKeyRegistry;\n /**\n * Delegation manager for creating delegations (used if createDelegation not provided).\n * Required for generate(), optional for receive().\n */\n delegationManager?: DelegationManager;\n /** Factory for creating KV service instances */\n createKVService: (config: {\n hosts: string[];\n session: ServiceSession;\n invoke: InvokeFunction;\n fetch?: FetchFunction;\n pathPrefix?: string;\n }) => IKVService;\n /** Base URL for sharing links (e.g., \"https://share.myapp.com\") */\n baseUrl?: string;\n /**\n * Custom delegation creation function. When provided, this is used instead\n * of delegationManager.create(). This allows platforms to use their own\n * delegation creation logic (e.g., SIWE-based /delegate endpoint).\n */\n createDelegation?: (params: CreateDelegationParams) => Promise<Result<Delegation, DelegationError>>;\n /**\n * WASM function for client-side delegation creation.\n * When provided, this is preferred over server-side creation (createDelegation/delegationManager).\n * Creates UCAN delegations directly without requiring server roundtrip.\n */\n createDelegationWasm?: (params: CreateDelegationWasmParams) => CreateDelegationWasmResult;\n /**\n * Path prefix for KV operations.\n * When set, paths passed to generate() are prefixed with this value.\n * This ensures the share path matches the session's authorized paths.\n */\n pathPrefix?: string;\n /**\n * Session expiry time.\n * When set, sharing link expiry is clamped to not exceed this value\n * unless onRootDelegationNeeded is provided and returns a new delegation.\n */\n sessionExpiry?: Date;\n /**\n * Callback to create a DIRECT delegation from the root (wallet) to a share key.\n * This bypasses the session delegation chain, allowing share links with\n * expiry longer than the current session.\n *\n * When provided and share expiry > session expiry:\n * 1. SharingService creates the ephemeral share key\n * 2. This callback is invoked with the share key DID\n * 3. The callback signs a direct PKH -> share key delegation with the wallet\n * 4. The returned delegation is used for the share link\n *\n * This is the CORRECT solution for long-lived share links because:\n * - It creates a fresh delegation chain: PKH -> share key\n * - Not constrained by session expiry (no sub-delegation from session key)\n *\n * @param params - Parameters for creating the root delegation\n * @returns The delegation from wallet to share key, or undefined to fall back to session extension\n */\n onRootDelegationNeeded?: (params: {\n /** DID of the share key to delegate to */\n shareKeyDID: string;\n /** Space ID */\n spaceId: string;\n /** Path to grant access to */\n path: string;\n /** Actions to grant */\n actions: string[];\n /** Requested expiry time */\n requestedExpiry: Date;\n }) => Promise<Delegation | undefined>;\n}\n\n/**\n * Interface for the SharingService.\n */\nexport interface ISharingService {\n /**\n * Generate a sharing link with an embedded private key.\n *\n * This creates a new session key, delegates to it, and encodes\n * the key and delegation into a shareable link.\n */\n generate(params: GenerateShareParams): Promise<Result<ShareLink, DelegationError>>;\n\n /**\n * Receive and activate a sharing link.\n *\n * Decodes the link, ingests the key into the registry, and optionally\n * creates a sub-delegation to the current session key.\n */\n receive(link: string, options?: ReceiveOptions): Promise<Result<ShareAccess, DelegationError>>;\n\n /**\n * Encode sharing data into a link string.\n */\n encodeLink(data: EncodedShareData, schema?: ShareSchema): string;\n\n /**\n * Decode a link string into sharing data.\n */\n decodeLink(link: string): EncodedShareData;\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * SharingService - v2 sharing link service with embedded private keys.\n *\n * @example\n * ```typescript\n * import { SharingService } from \"@tinycloud/sdk-core/delegations\";\n *\n * const sharing = new SharingService({\n * hosts: [\"https://node.tinycloud.xyz\"],\n * session,\n * invoke,\n * keyProvider,\n * registry,\n * delegationManager,\n * createKVService,\n * baseUrl: \"https://share.myapp.com\"\n * });\n *\n * // Generate a sharing link\n * const result = await sharing.generate({\n * path: \"/kv/documents/report.pdf\",\n * actions: [\"tinycloud.kv/get\"],\n * expiry: new Date(\"2024-12-31\")\n * });\n *\n * if (result.ok) {\n * console.log(\"Share this URL:\", result.data.url);\n * }\n *\n * // Receive a sharing link\n * const receiveResult = await sharing.receive(shareUrl);\n * if (receiveResult.ok) {\n * // Use the pre-configured KV service\n * const data = await receiveResult.data.kv.get(\"report.pdf\");\n * }\n * ```\n */\nexport class SharingService implements ISharingService {\n private hosts: string[];\n private session?: ServiceSession;\n private invoke: InvokeFunction;\n private fetchFn: FetchFunction;\n private keyProvider: KeyProvider;\n private registry: ICapabilityKeyRegistry;\n private delegationManager?: DelegationManager;\n private createKVService: SharingServiceConfig[\"createKVService\"];\n private baseUrl: string;\n private createDelegationFn?: SharingServiceConfig[\"createDelegation\"];\n private createDelegationWasmFn?: SharingServiceConfig[\"createDelegationWasm\"];\n private pathPrefix: string;\n private sessionExpiry?: Date;\n private onRootDelegationNeeded?: SharingServiceConfig[\"onRootDelegationNeeded\"];\n\n /**\n * Creates a new SharingService instance.\n */\n constructor(config: SharingServiceConfig) {\n this.hosts = config.hosts;\n this.session = config.session;\n this.invoke = config.invoke;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.keyProvider = config.keyProvider;\n this.registry = config.registry;\n this.delegationManager = config.delegationManager;\n this.createKVService = config.createKVService;\n this.baseUrl = (config.baseUrl ?? \"\").replace(/\\/$/, \"\"); // Remove trailing slash\n this.createDelegationFn = config.createDelegation;\n this.createDelegationWasmFn = config.createDelegationWasm;\n this.pathPrefix = config.pathPrefix ?? \"\";\n this.sessionExpiry = config.sessionExpiry;\n this.onRootDelegationNeeded = config.onRootDelegationNeeded;\n }\n\n /**\n * Gets the primary host URL.\n */\n private get host(): string {\n return this.hosts[0];\n }\n\n /**\n * Updates the session (e.g., after re-authentication).\n */\n public updateSession(session: ServiceSession): void {\n this.session = session;\n }\n\n /**\n * Updates the service configuration.\n * Used to add full capabilities (session, delegationManager, createDelegation, createDelegationWasm) after signIn.\n */\n public updateConfig(config: Partial<Pick<SharingServiceConfig, \"session\" | \"delegationManager\" | \"createDelegation\" | \"createDelegationWasm\" | \"sessionExpiry\" | \"onRootDelegationNeeded\">>): void {\n if (config.session !== undefined) {\n this.session = config.session;\n }\n if (config.delegationManager !== undefined) {\n this.delegationManager = config.delegationManager;\n }\n if (config.createDelegation !== undefined) {\n this.createDelegationFn = config.createDelegation;\n }\n if (config.createDelegationWasm !== undefined) {\n this.createDelegationWasmFn = config.createDelegationWasm;\n }\n if (config.sessionExpiry !== undefined) {\n this.sessionExpiry = config.sessionExpiry;\n }\n if (config.onRootDelegationNeeded !== undefined) {\n this.onRootDelegationNeeded = config.onRootDelegationNeeded;\n }\n }\n\n /**\n * Generate a sharing link with an embedded private key.\n *\n * Flow:\n * 1. Spawn new session key (unique per share)\n * 2. Create delegation from current session to spawned key\n * 3. Package: { key (with private!), delegation, path, host }\n * 4. Encode based on schema (base64 for now)\n * 5. Return link string\n */\n async generate(params: GenerateShareParams): Promise<Result<ShareLink, DelegationError>> {\n // Require session for generating (not for receiving)\n if (!this.session) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"Session required for generating sharing links. Call signIn() first.\"\n ),\n };\n }\n\n // Require delegation capability\n if (!this.createDelegationWasmFn && !this.createDelegationFn && !this.delegationManager) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"DelegationManager, createDelegation, or createDelegationWasm function required for generating sharing links.\"\n ),\n };\n }\n\n // Validate path\n if (!params.path) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n \"path is required\"\n ),\n };\n }\n\n const actions = params.actions ?? DEFAULT_READ_ACTIONS;\n const requestedExpiry = params.expiry ?? new Date(Date.now() + DEFAULT_EXPIRY_MS);\n let expiry = requestedExpiry;\n\n const schema: ShareSchema = params.schema ?? \"base64\";\n\n // Build full path with prefix (matches how KVService stores data)\n // If pathPrefix is \"demo-app\" and path is \"hello\", fullPath is \"demo-app/hello\"\n const fullPath = this.pathPrefix\n ? `${this.pathPrefix}/${params.path}`.replace(/\\/+/g, \"/\") // Normalize slashes\n : params.path;\n\n // Only base64 schema is implemented in v1\n if (schema !== \"base64\") {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_INPUT,\n `Schema '${schema}' not implemented. Only 'base64' is supported.`\n ),\n };\n }\n\n // Step 1: Spawn a new session key unique to this share\n // We create this FIRST so we can pass its DID to onRootDelegationNeeded if needed\n let keyId: string;\n let keyDid: string;\n let keyJwk: JWK;\n\n try {\n const shareKeyName = `share:${Date.now()}:${Math.random().toString(36).substring(2, 10)}`;\n keyId = await this.keyProvider.createSessionKey(shareKeyName);\n keyDid = await this.keyProvider.getDID(keyId);\n keyJwk = this.keyProvider.getJWK(keyId) as JWK;\n\n // Ensure the private key is included\n if (!keyJwk.d) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n \"KeyProvider did not return private key (d parameter) in JWK\"\n ),\n };\n }\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to generate session key for share: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n // Step 2: Check if any existing key can satisfy this delegation\n // Only prompt for root delegation if NO existing key in the registry can handle it\n let delegation: Delegation;\n // Strip fragment from DID URL to get plain DID for UCAN audience\n // getDID() returns \"did:key:z6Mk...#z6Mk...\" but audience needs \"did:key:z6Mk...\"\n const plainDID = keyDid.split('#')[0];\n\n // Helper to handle delegation result (returns early on error)\n const handleDelegationResult = (\n result: Awaited<ReturnType<typeof this.createSessionDelegation>>\n ): Delegation | { ok: false; error: DelegationError } => {\n if (result && typeof result === 'object' && 'ok' in result) {\n return result as { ok: false; error: DelegationError };\n }\n return result as Delegation;\n };\n\n // Check if any key in the registry can satisfy this delegation request\n // A key can satisfy the request if it has a delegation that:\n // 1. Covers the required path and actions\n // 2. Has sufficient expiry (delegation.expiry >= requestedExpiry)\n // 3. Allows sub-delegation\n const canSatisfyFromRegistry = this.findSuitableKeyForDelegation(\n fullPath,\n actions,\n requestedExpiry\n );\n\n if (canSatisfyFromRegistry) {\n // An existing key can satisfy this request - use session delegation (no prompt)\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n } else if (this.onRootDelegationNeeded) {\n // No existing key can satisfy the request - try root delegation\n try {\n const rootDelegation = await this.onRootDelegationNeeded({\n shareKeyDID: plainDID,\n spaceId: this.session.spaceId,\n path: fullPath,\n actions,\n requestedExpiry,\n });\n\n if (rootDelegation) {\n delegation = rootDelegation;\n expiry = requestedExpiry;\n } else {\n // Root delegation declined, clamp to session expiry\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n } catch (err) {\n // Root delegation failed, clamp to session expiry\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n } else {\n // No root delegation callback, clamp to what session can provide\n const fallbackResult = await this.handleSessionExtensionFallback(requestedExpiry);\n expiry = fallbackResult.expiry;\n const delegationResult = await this.createSessionDelegation(plainDID, fullPath, actions, expiry);\n const parsed = handleDelegationResult(delegationResult);\n if ('ok' in parsed && parsed.ok === false) {\n return parsed;\n }\n delegation = parsed as Delegation;\n }\n\n // Step 3: Package the share data\n const shareData: EncodedShareData = {\n key: keyJwk,\n keyDid,\n delegation,\n path: fullPath,\n host: this.host,\n spaceId: this.session.spaceId,\n version: 1,\n };\n\n // Step 4: Encode the link\n const encodedData = this.encodeLink(shareData, schema);\n\n // Step 5: Build the full URL\n const baseUrl = params.baseUrl ?? this.baseUrl;\n const url = baseUrl ? `${baseUrl}/share/${encodedData}` : encodedData;\n\n const shareLink: ShareLink = {\n token: encodedData,\n url,\n delegation,\n schema,\n expiresAt: expiry,\n description: params.description,\n };\n\n return { ok: true, data: shareLink };\n }\n\n /**\n * Check if any key in the registry can satisfy the delegation request.\n * A key can satisfy if it has a delegation that:\n * 1. Covers the required path (exact match or parent path)\n * 2. Has all required actions\n * 3. Has sufficient expiry (delegation.expiry >= requestedExpiry)\n * 4. Allows sub-delegation\n * @internal\n */\n private findSuitableKeyForDelegation(\n path: string,\n actions: string[],\n requestedExpiry: Date\n ): boolean {\n // Check session expiry first (most common case)\n if (this.sessionExpiry && requestedExpiry <= this.sessionExpiry) {\n return true;\n }\n\n // Check registry for keys with sufficient capabilities\n const allKeys = this.registry.getAllKeys();\n for (const key of allKeys) {\n const delegations = this.registry.getDelegationsForKey(key.id);\n for (const delegation of delegations) {\n // Check if delegation is valid and not expired\n if (!this.registry.isDelegationValid(delegation)) {\n continue;\n }\n\n // Check if delegation has sufficient expiry\n if (delegation.expiry < requestedExpiry) {\n continue;\n }\n\n // Check if delegation allows sub-delegation\n if (delegation.allowSubDelegation === false) {\n continue;\n }\n\n // Check if delegation covers the path (exact match or parent path)\n const delegationPath = delegation.path || '';\n if (!this.pathMatches(delegationPath, path)) {\n continue;\n }\n\n // Check if delegation has all required actions\n const delegationActions = delegation.actions || [];\n const hasAllActions = actions.every(action =>\n delegationActions.includes(action) || delegationActions.includes('*')\n );\n if (!hasAllActions) {\n continue;\n }\n\n // Found a suitable key\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a delegation path matches/covers the requested path.\n * A delegation path covers the request if:\n * - It's an exact match\n * - It's a parent path (e.g., delegation for \"\" covers \"foo/bar\")\n * - It uses wildcards that match\n * @internal\n */\n private pathMatches(delegationPath: string, requestedPath: string): boolean {\n // Empty delegation path covers everything\n if (delegationPath === '' || delegationPath === '*') {\n return true;\n }\n\n // Exact match\n if (delegationPath === requestedPath) {\n return true;\n }\n\n // Check if delegation path is a parent of requested path\n const normalizedDelegation = delegationPath.replace(/\\/$/, '');\n const normalizedRequest = requestedPath.replace(/\\/$/, '');\n\n if (normalizedRequest.startsWith(normalizedDelegation + '/')) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Handle fallback to session extension when root delegation is not available.\n * @internal\n */\n private async handleSessionExtensionFallback(requestedExpiry: Date): Promise<{ expiry: Date }> {\n // Clamp to current session expiry\n return { expiry: this.sessionExpiry ?? requestedExpiry };\n }\n\n /**\n * Create a delegation from the current session to a share key.\n * This is the fallback path when root delegation is not available.\n * @internal\n */\n private async createSessionDelegation(\n delegateDID: string,\n path: string,\n actions: string[],\n expiry: Date\n ): Promise<Delegation | Result<never, DelegationError>> {\n if (!this.session) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.NOT_INITIALIZED,\n \"Session required for creating delegation\"\n ),\n };\n }\n\n if (this.createDelegationWasmFn) {\n // Client-side delegation creation via WASM.\n //\n // SharingService always issues single-resource delegations (one\n // path, one action list). The multi-resource WASM API takes an\n // `abilities` map shaped `Record<shortService, Record<path,\n // actions[]>>`, so we infer the short service from the first\n // action URN (every action in a share call shares the same\n // service namespace by construction — KV-only, SQL-only, etc).\n //\n // The result comes back with a `resources` array; for a\n // single-entry call it always has exactly one entry, and we\n // mirror that entry's `path` + `actions` back into the flat\n // Delegation shape that the rest of SharingService works with.\n try {\n if (actions.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.VALIDATION_ERROR,\n \"createDelegation requires at least one action\"\n ),\n };\n }\n const shortService = inferShortServiceFromActionUrns(actions);\n if (shortService === undefined) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.VALIDATION_ERROR,\n `createDelegation: cannot infer service from actions ${JSON.stringify(actions)} — expected full URNs like \"tinycloud.kv/get\"`\n ),\n };\n }\n\n const wasmResult = this.createDelegationWasmFn({\n session: this.session,\n delegateDID,\n spaceId: this.session.spaceId,\n abilities: {\n [shortService]: {\n [path]: [...actions],\n },\n },\n expirationSecs: Math.floor(expiry.getTime() / 1000),\n });\n\n // Register the delegation with the server\n const registerRes = await this.fetchFn(`${this.host}/delegate`, {\n method: \"POST\",\n headers: {\n Authorization: wasmResult.delegation,\n },\n });\n\n if (!registerRes.ok) {\n const errorText = await registerRes.text();\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to register delegation with server: ${registerRes.status} ${errorText}`\n ),\n };\n }\n\n // Single-entry call → resources[0] is authoritative for the\n // flat Delegation shape. We assert length here because a\n // zero-length result would mean the Rust side dropped our\n // single input — that's a protocol bug, not a runtime\n // condition to silently coerce.\n if (wasmResult.resources.length === 0) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n \"createDelegation WASM returned empty resources array for a single-entry request\"\n ),\n };\n }\n const primary = wasmResult.resources[0];\n return {\n cid: wasmResult.cid,\n delegateDID: wasmResult.delegateDID,\n spaceId: this.session.spaceId,\n path: primary.path,\n actions: primary.actions,\n expiry: wasmResult.expiry,\n isRevoked: false,\n authHeader: wasmResult.delegation,\n allowSubDelegation: true,\n createdAt: new Date(),\n };\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation via WASM: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n } else {\n // Server-side delegation creation (fallback)\n const delegationParams: CreateDelegationParams = {\n delegateDID,\n path,\n actions,\n expiry,\n disableSubDelegation: false,\n };\n\n const delegationResult = this.createDelegationFn\n ? await this.createDelegationFn(delegationParams)\n : await this.delegationManager!.create(delegationParams);\n\n if (!delegationResult.ok) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.CREATION_FAILED,\n `Failed to create delegation for share: ${delegationResult.error.message}`,\n delegationResult.error.cause,\n delegationResult.error.meta\n ),\n };\n }\n\n return delegationResult.data;\n }\n }\n\n /**\n * Receive and activate a sharing link.\n *\n * Flow:\n * 1. Decode link -> extract { key, delegation, path, host }\n * 2. Ingest key into CapabilityKeyRegistry\n * 3. If autoSubdelegate (default true) + useSessionKey:\n * - Create sub-delegation from ingested key -> current session\n * - Register sub-delegation capabilities\n * 4. Return ShareAccess with pre-configured KV service\n */\n async receive(\n link: string,\n options: ReceiveOptions = {}\n ): Promise<Result<ShareAccess, DelegationError>> {\n const {\n autoSubdelegate = true,\n useSessionKey = true,\n ingestOptions,\n } = options;\n\n // Step 1: Decode and validate the link\n const decodeResult = this.decodeLinkWithValidation(link);\n if (!decodeResult.ok) {\n return decodeResult;\n }\n const shareData = decodeResult.data;\n\n // Schema validation ensures key.d and delegation exist, but we need\n // to check business rules (expiry, revocation) separately\n\n // Check delegation expiry\n const delegationExpiry = new Date(shareData.delegation.expiry);\n if (delegationExpiry < new Date()) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.AUTH_EXPIRED,\n \"Sharing link has expired\"\n ),\n };\n }\n\n // Check delegation revocation\n if (shareData.delegation.isRevoked) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.REVOKED,\n \"Sharing link has been revoked\"\n ),\n };\n }\n\n // Step 2: Create KeyInfo and ingest into registry\n const keyInfo: KeyInfo = {\n id: `ingested:${shareData.keyDid}`,\n did: shareData.keyDid,\n type: \"ingested\",\n jwk: shareData.key,\n priority: 2, // Ingested keys have lowest priority\n };\n\n this.registry.ingestKey(keyInfo, shareData.delegation, ingestOptions);\n\n // The delegation and key to use for operations\n let activeDelegation = shareData.delegation;\n let activeKey = keyInfo;\n\n // Step 3: Auto-subdelegate if requested\n if (autoSubdelegate && useSessionKey && this.session) {\n try {\n // Get current session key DID\n // Note: We need to create a sub-delegation from the ingested key to the session key\n // This requires the session key DID, which should be available from the session\n\n // For now, we'll register the ingested key's capabilities directly\n // The auto-subdelegation would require additional infrastructure to sign with the ingested key\n // This is a simplification - full implementation would sign a new delegation with the ingested key\n\n // TODO: Implement full auto-subdelegation when signing infrastructure is available\n // For now, the ingested key can be used directly via the registry\n\n } catch (err) {\n // Log but don't fail - can still use the ingested key directly\n console.warn(\"Auto-subdelegation failed, using ingested key directly:\", err);\n }\n }\n\n // Step 4: Create pre-configured KV service for the shared path\n // Construct session from share data - no need for existing session\n // Use the authHeader if available, otherwise fall back to constructing from CID\n const authHeader = shareData.delegation.authHeader ?? `Bearer ${shareData.delegation.cid}`;\n const shareSession: ServiceSession = {\n delegationHeader: { Authorization: authHeader },\n delegationCid: shareData.delegation.cid,\n spaceId: shareData.spaceId,\n verificationMethod: shareData.keyDid,\n jwk: shareData.key,\n };\n\n const kvService = this.createKVService({\n hosts: [shareData.host],\n session: shareSession,\n invoke: this.invoke,\n fetch: this.fetchFn,\n pathPrefix: shareData.path,\n });\n\n const shareAccess: ShareAccess = {\n delegation: activeDelegation,\n key: activeKey,\n kv: kvService,\n spaceId: shareData.spaceId,\n path: shareData.path,\n };\n\n return { ok: true, data: shareAccess };\n }\n\n /**\n * Encode sharing data into a link string.\n *\n * @param data - The share data to encode\n * @param schema - The encoding schema (default: \"base64\")\n * @returns Encoded link string\n */\n encodeLink(data: EncodedShareData, schema: ShareSchema = \"base64\"): string {\n if (schema !== \"base64\") {\n throw new Error(`Schema '${schema}' not implemented. Only 'base64' is supported.`);\n }\n\n const jsonString = JSON.stringify(data);\n const encoded = base64UrlEncode(jsonString);\n return `${BASE64_PREFIX}${encoded}`;\n }\n\n /**\n * Decode a link string into sharing data.\n *\n * @param link - The encoded link string (may include URL prefix)\n * @returns Decoded share data\n * @throws Error if link format is invalid or data fails validation\n */\n decodeLink(link: string): EncodedShareData {\n const result = this.decodeLinkWithValidation(link);\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return result.data;\n }\n\n /**\n * Decode and validate a link string into sharing data.\n *\n * Internal method that returns a Result instead of throwing.\n * Used by receive() for proper error handling.\n *\n * @param link - The encoded link string (may include URL prefix)\n * @returns Result with decoded share data or validation error\n */\n private decodeLinkWithValidation(link: string): Result<EncodedShareData, DelegationError> {\n // Extract the encoded data from the link\n let encoded = link;\n\n // Handle full URL format: https://share.example.com/share/tc1:...\n if (link.includes(\"/share/\")) {\n const parts = link.split(\"/share/\");\n encoded = parts[parts.length - 1];\n }\n\n // Handle query parameter format: ?share=tc1:...\n if (link.includes(\"?share=\")) {\n try {\n const url = new URL(link);\n encoded = url.searchParams.get(\"share\") ?? encoded;\n } catch {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n \"Invalid URL format in sharing link\"\n ),\n };\n }\n }\n\n // Remove the schema prefix\n if (!encoded.startsWith(BASE64_PREFIX)) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Invalid sharing link format. Expected prefix '${BASE64_PREFIX}'`\n ),\n };\n }\n\n const base64Data = encoded.slice(BASE64_PREFIX.length);\n\n let jsonString: string;\n try {\n jsonString = base64UrlDecode(base64Data);\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Failed to decode base64 data: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonString);\n } catch (err) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n `Failed to parse share data JSON: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n ),\n };\n }\n\n // Convert delegation expiry to Date before validation if it's a string\n // This is needed because JSON.parse doesn't restore Date objects\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"delegation\" in parsed &&\n parsed.delegation &&\n typeof parsed.delegation === \"object\" &&\n \"expiry\" in parsed.delegation &&\n typeof parsed.delegation.expiry === \"string\"\n ) {\n (parsed.delegation as { expiry: Date }).expiry = new Date(parsed.delegation.expiry);\n }\n\n // Validate against schema\n const validationResult = validateEncodedShareData(parsed);\n if (!validationResult.ok) {\n return {\n ok: false,\n error: createError(\n DelegationErrorCodes.INVALID_TOKEN,\n validationResult.error.message,\n undefined,\n validationResult.error.meta\n ),\n };\n }\n\n return { ok: true, data: validationResult.data };\n }\n}\n\n/**\n * Create a new SharingService instance.\n */\nexport function createSharingService(config: SharingServiceConfig): ISharingService {\n return new SharingService(config);\n}\n","/**\n * CapabilityKeyRegistry - Tracks keys and their capabilities for automatic key selection.\n *\n * The registry maintains mappings between:\n * - Keys and their associated delegations\n * - Capabilities (resource/action pairs) and the keys that can exercise them\n *\n * This enables automatic key selection when performing operations, choosing\n * the most appropriate key based on priority and validity.\n *\n * @packageDocumentation\n */\n\nimport type { Result, ServiceError } from \"@tinycloud/sdk-services\";\nimport { ok, err, serviceError } from \"@tinycloud/sdk-services\";\nimport type {\n KeyInfo,\n CapabilityEntry,\n Delegation,\n IngestOptions,\n} from \"../delegations/types\";\n\n// =============================================================================\n// Service Name\n// =============================================================================\n\nconst SERVICE_NAME = \"capability-key-registry\";\n\n// =============================================================================\n// Error Codes\n// =============================================================================\n\n/**\n * Error codes specific to CapabilityKeyRegistry operations.\n */\nexport const CapabilityKeyRegistryErrorCodes = {\n /** Key not found in registry */\n KEY_NOT_FOUND: \"KEY_NOT_FOUND\",\n /** No key available for the requested capability */\n NO_CAPABLE_KEY: \"NO_CAPABLE_KEY\",\n /** Delegation has expired */\n DELEGATION_EXPIRED: \"DELEGATION_EXPIRED\",\n /** Delegation has been revoked */\n DELEGATION_REVOKED: \"DELEGATION_REVOKED\",\n /** Invalid delegation data */\n INVALID_DELEGATION: \"INVALID_DELEGATION\",\n /** Key already registered */\n KEY_EXISTS: \"KEY_EXISTS\",\n} as const;\n\nexport type CapabilityKeyRegistryErrorCode =\n (typeof CapabilityKeyRegistryErrorCodes)[keyof typeof CapabilityKeyRegistryErrorCodes];\n\n// =============================================================================\n// Storage Types\n// =============================================================================\n\n/**\n * Stored delegation with chain information.\n */\nexport interface StoredDelegationChain {\n /** The delegation itself */\n delegation: Delegation;\n /** Parent delegation CID if this is a sub-delegation */\n parentCid?: string;\n /** Key ID used to sign/exercise this delegation */\n keyId: string;\n /** When this was stored */\n storedAt: Date;\n}\n\n/**\n * Internal delegation store structure.\n */\ninterface DelegationStore {\n /** Delegations indexed by key ID */\n byKey: Map<string, Delegation[]>;\n /** Delegations indexed by CID */\n byCid: Map<string, StoredDelegationChain>;\n /** Capability entries indexed by \"resource|action\" key */\n byCapability: Map<string, CapabilityEntry[]>;\n}\n\n// =============================================================================\n// Interface\n// =============================================================================\n\n/**\n * Interface for the CapabilityKeyRegistry.\n *\n * Tracks keys and their capabilities for automatic key selection.\n */\nexport interface ICapabilityKeyRegistry {\n /**\n * Register a key with its associated delegations.\n *\n * @param key - Key information\n * @param delegations - Delegations granted to this key\n */\n registerKey(key: KeyInfo, delegations: Delegation[]): void;\n\n /**\n * Remove a key and all its associated delegations.\n *\n * @param keyId - The key ID to remove\n */\n removeKey(keyId: string): void;\n\n /**\n * Get a key that can exercise the specified capability.\n *\n * Uses the key selection algorithm:\n * 1. Filter keys that have the required capability\n * 2. Check delegation validity (not expired, not revoked)\n * 3. Sort by priority (session=0, main=1, ingested=2)\n * 4. Return highest priority valid key\n *\n * @param resource - Resource URI (e.g., \"tinycloud://space-id/kv/my-data\")\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @returns The best matching key, or null if none available\n */\n getKeyForCapability(resource: string, action: string): KeyInfo | null;\n\n /**\n * Get all registered capabilities.\n *\n * @returns All capability entries in the registry\n */\n getAllCapabilities(): CapabilityEntry[];\n\n /**\n * Get all delegations for a specific key.\n *\n * @param keyId - The key ID\n * @returns Array of delegations for this key\n */\n getDelegationsForKey(keyId: string): Delegation[];\n\n /**\n * Ingest a key and delegation from an external source (e.g., sharing link).\n *\n * @param key - Key information to ingest\n * @param delegation - Delegation to associate with the key\n * @param options - Ingestion options\n */\n ingestKey(\n key: KeyInfo,\n delegation: Delegation,\n options?: IngestOptions\n ): void;\n\n /**\n * Check if a delegation is currently valid.\n *\n * @param delegation - The delegation to check\n * @returns true if valid, false if expired or revoked\n */\n isDelegationValid(delegation: Delegation): boolean;\n\n /**\n * Get a key by its ID.\n *\n * @param keyId - The key ID\n * @returns The key info, or undefined if not found\n */\n getKey(keyId: string): KeyInfo | undefined;\n\n /**\n * Get all registered keys.\n *\n * @returns Array of all registered keys\n */\n getAllKeys(): KeyInfo[];\n\n /**\n * Clear all registered keys and delegations.\n */\n clear(): void;\n\n /**\n * Revoke a delegation by CID.\n *\n * @param cid - The delegation CID to revoke\n * @returns Result indicating success or failure\n */\n revokeDelegation(cid: string): Result<void, ServiceError>;\n\n /**\n * Find capabilities that match a resource path pattern.\n *\n * @param resourcePattern - Resource pattern (supports wildcards)\n * @param action - Optional action filter\n * @returns Matching capability entries\n */\n findCapabilities(\n resourcePattern: string,\n action?: string\n ): CapabilityEntry[];\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * CapabilityKeyRegistry - Tracks keys and their capabilities for automatic key selection.\n *\n * @example\n * ```typescript\n * const registry = new CapabilityKeyRegistry();\n *\n * // Register a session key with its delegations\n * registry.registerKey(sessionKey, [rootDelegation]);\n *\n * // Get the best key for an operation\n * const key = registry.getKeyForCapability(\n * \"tinycloud://my-space/kv/data\",\n * \"tinycloud.kv/get\"\n * );\n *\n * if (key) {\n * // Use this key for the operation\n * console.log(\"Using key:\", key.id);\n * }\n * ```\n */\nexport class CapabilityKeyRegistry implements ICapabilityKeyRegistry {\n /**\n * Registry of all keys indexed by ID.\n */\n private keys: Map<string, KeyInfo> = new Map();\n\n /**\n * Delegation storage.\n */\n private store: DelegationStore = {\n byKey: new Map(),\n byCid: new Map(),\n byCapability: new Map(),\n };\n\n // ===========================================================================\n // Key Management\n // ===========================================================================\n\n /**\n * Register a key with its associated delegations.\n *\n * @param key - Key information\n * @param delegations - Delegations granted to this key\n */\n registerKey(key: KeyInfo, delegations: Delegation[]): void {\n // Store the key\n this.keys.set(key.id, key);\n\n // Initialize delegation storage for this key\n if (!this.store.byKey.has(key.id)) {\n this.store.byKey.set(key.id, []);\n }\n\n // Process each delegation\n for (const delegation of delegations) {\n this.addDelegation(key, delegation);\n }\n }\n\n /**\n * Remove a key and all its associated delegations.\n *\n * @param keyId - The key ID to remove\n */\n removeKey(keyId: string): void {\n // Get delegations for this key\n const delegations = this.store.byKey.get(keyId) || [];\n\n // Remove from byCid\n for (const delegation of delegations) {\n this.store.byCid.delete(delegation.cid);\n }\n\n // Remove from byCapability\n for (const [capKey, entries] of this.store.byCapability) {\n const filtered = entries.filter(\n (entry) => !entry.keys.some((k: KeyInfo) => k.id === keyId)\n );\n if (filtered.length === 0) {\n this.store.byCapability.delete(capKey);\n } else {\n // Remove this key from entries that have multiple keys\n for (const entry of filtered) {\n entry.keys = entry.keys.filter((k: KeyInfo) => k.id !== keyId);\n }\n this.store.byCapability.set(capKey, filtered.filter((e) => e.keys.length > 0));\n }\n }\n\n // Remove from byKey\n this.store.byKey.delete(keyId);\n\n // Remove the key itself\n this.keys.delete(keyId);\n }\n\n // ===========================================================================\n // Capability Lookup\n // ===========================================================================\n\n /**\n * Get a key that can exercise the specified capability.\n *\n * Key selection algorithm:\n * 1. Filter keys that have the required capability\n * 2. Check delegation validity (not expired, not revoked)\n * 3. Sort by priority (session=0, main=1, ingested=2)\n * 4. Return highest priority valid key\n *\n * @param resource - Resource URI\n * @param action - Action to perform\n * @returns The best matching key, or null if none available\n */\n getKeyForCapability(resource: string, action: string): KeyInfo | null {\n // Find matching capabilities\n const matchingEntries = this.findMatchingEntries(resource, action);\n\n if (matchingEntries.length === 0) {\n return null;\n }\n\n // Collect all valid keys from matching entries\n const validKeys: KeyInfo[] = [];\n\n for (const entry of matchingEntries) {\n // Check if the delegation is valid\n if (!this.isDelegationValid(entry.delegation)) {\n continue;\n }\n\n // Add keys from this entry\n for (const key of entry.keys) {\n if (!validKeys.some((k: KeyInfo) => k.id === key.id)) {\n validKeys.push(key);\n }\n }\n }\n\n if (validKeys.length === 0) {\n return null;\n }\n\n // Sort by priority (lower is better)\n validKeys.sort((a: KeyInfo, b: KeyInfo) => a.priority - b.priority);\n\n return validKeys[0];\n }\n\n /**\n * Get all registered capabilities.\n *\n * @returns All capability entries in the registry\n */\n getAllCapabilities(): CapabilityEntry[] {\n const all: CapabilityEntry[] = [];\n for (const entries of this.store.byCapability.values()) {\n all.push(...entries);\n }\n return all;\n }\n\n // ===========================================================================\n // Delegation Tracking\n // ===========================================================================\n\n /**\n * Get all delegations for a specific key.\n *\n * @param keyId - The key ID\n * @returns Array of delegations for this key\n */\n getDelegationsForKey(keyId: string): Delegation[] {\n return this.store.byKey.get(keyId) || [];\n }\n\n // ===========================================================================\n // Ingestion\n // ===========================================================================\n\n /**\n * Ingest a key and delegation from an external source.\n *\n * @param key - Key information to ingest\n * @param delegation - Delegation to associate with the key\n * @param options - Ingestion options\n */\n ingestKey(\n key: KeyInfo,\n delegation: Delegation,\n options?: IngestOptions\n ): void {\n // Apply priority override if specified\n const keyToStore: KeyInfo = options?.priority !== undefined\n ? { ...key, priority: options.priority }\n : key;\n\n // Store the key\n this.keys.set(keyToStore.id, keyToStore);\n\n // Initialize delegation storage\n if (!this.store.byKey.has(keyToStore.id)) {\n this.store.byKey.set(keyToStore.id, []);\n }\n\n // Add the delegation\n this.addDelegation(keyToStore, delegation);\n }\n\n // ===========================================================================\n // Validation\n // ===========================================================================\n\n /**\n * Check if a delegation is currently valid.\n *\n * @param delegation - The delegation to check\n * @returns true if valid, false if expired or revoked\n */\n isDelegationValid(delegation: Delegation): boolean {\n // Check if revoked\n if (delegation.isRevoked) {\n return false;\n }\n\n // Check expiry\n const now = new Date();\n if (delegation.expiry && delegation.expiry < now) {\n return false;\n }\n\n return true;\n }\n\n // ===========================================================================\n // Key Access\n // ===========================================================================\n\n /**\n * Get a key by its ID.\n *\n * @param keyId - The key ID\n * @returns The key info, or undefined if not found\n */\n getKey(keyId: string): KeyInfo | undefined {\n return this.keys.get(keyId);\n }\n\n /**\n * Get all registered keys.\n *\n * @returns Array of all registered keys\n */\n getAllKeys(): KeyInfo[] {\n return Array.from(this.keys.values());\n }\n\n // ===========================================================================\n // Clear\n // ===========================================================================\n\n /**\n * Clear all registered keys and delegations.\n */\n clear(): void {\n this.keys.clear();\n this.store.byKey.clear();\n this.store.byCid.clear();\n this.store.byCapability.clear();\n }\n\n // ===========================================================================\n // Revocation\n // ===========================================================================\n\n /**\n * Revoke a delegation by CID.\n *\n * @param cid - The delegation CID to revoke\n * @returns Result indicating success or failure\n */\n revokeDelegation(cid: string): Result<void, ServiceError> {\n const stored = this.store.byCid.get(cid);\n\n if (!stored) {\n return err(\n serviceError(\n CapabilityKeyRegistryErrorCodes.KEY_NOT_FOUND,\n `Delegation not found: ${cid}`,\n SERVICE_NAME\n )\n );\n }\n\n // Mark the delegation as revoked\n stored.delegation.isRevoked = true;\n\n // Update in byKey\n const keyDelegations = this.store.byKey.get(stored.keyId);\n if (keyDelegations) {\n const delegation = keyDelegations.find((d) => d.cid === cid);\n if (delegation) {\n delegation.isRevoked = true;\n }\n }\n\n // Update in byCapability\n for (const entries of this.store.byCapability.values()) {\n for (const entry of entries) {\n if (entry.delegation.cid === cid) {\n entry.delegation.isRevoked = true;\n }\n }\n }\n\n return ok(undefined);\n }\n\n // ===========================================================================\n // Search\n // ===========================================================================\n\n /**\n * Find capabilities that match a resource path pattern.\n *\n * @param resourcePattern - Resource pattern (supports wildcards)\n * @param action - Optional action filter\n * @returns Matching capability entries\n */\n findCapabilities(\n resourcePattern: string,\n action?: string\n ): CapabilityEntry[] {\n const results: CapabilityEntry[] = [];\n\n for (const entries of this.store.byCapability.values()) {\n for (const entry of entries) {\n // Check action match if specified\n if (action && entry.action !== action) {\n continue;\n }\n\n // Check resource pattern match\n if (this.matchesResourcePattern(entry.resource, resourcePattern)) {\n results.push(entry);\n }\n }\n }\n\n return results;\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * Add a delegation to the store.\n *\n * @param key - The key associated with this delegation\n * @param delegation - The delegation to add\n */\n private addDelegation(key: KeyInfo, delegation: Delegation): void {\n // Add to byKey\n const keyDelegations = this.store.byKey.get(key.id) || [];\n if (!keyDelegations.some((d) => d.cid === delegation.cid)) {\n keyDelegations.push(delegation);\n this.store.byKey.set(key.id, keyDelegations);\n }\n\n // Add to byCid\n if (!this.store.byCid.has(delegation.cid)) {\n this.store.byCid.set(delegation.cid, {\n delegation,\n parentCid: delegation.parentCid,\n keyId: key.id,\n storedAt: new Date(),\n });\n }\n\n // Add to byCapability for each action\n for (const action of delegation.actions) {\n const capKey = this.makeCapabilityKey(delegation.path, action);\n const entries = this.store.byCapability.get(capKey) || [];\n\n // Check if we already have an entry for this exact delegation\n const existingEntry = entries.find((e) => e.delegation.cid === delegation.cid);\n\n if (existingEntry) {\n // Add this key if not already present\n if (!existingEntry.keys.some((k: KeyInfo) => k.id === key.id)) {\n existingEntry.keys.push(key);\n // Re-sort by priority\n existingEntry.keys.sort((a: KeyInfo, b: KeyInfo) => a.priority - b.priority);\n }\n } else {\n // Create new capability entry\n const entry: CapabilityEntry = {\n resource: delegation.path,\n action,\n keys: [key],\n delegation,\n expiresAt: delegation.expiry,\n };\n entries.push(entry);\n this.store.byCapability.set(capKey, entries);\n }\n }\n }\n\n /**\n * Create a capability key for indexing.\n *\n * @param resource - Resource path\n * @param action - Action\n * @returns Combined key string\n */\n private makeCapabilityKey(resource: string, action: string): string {\n return `${resource}|${action}`;\n }\n\n /**\n * Find capability entries that match a resource and action.\n *\n * @param resource - Resource to match\n * @param action - Action to match\n * @returns Matching entries\n */\n private findMatchingEntries(\n resource: string,\n action: string\n ): CapabilityEntry[] {\n const results: CapabilityEntry[] = [];\n\n // Exact match\n const exactKey = this.makeCapabilityKey(resource, action);\n const exactEntries = this.store.byCapability.get(exactKey);\n if (exactEntries) {\n results.push(...exactEntries);\n }\n\n // Wildcard matches - check all entries for patterns that match this resource\n for (const [capKey, entries] of this.store.byCapability) {\n if (capKey === exactKey) continue; // Already handled\n\n for (const entry of entries) {\n // Check if the entry's action matches\n if (!this.actionMatches(entry.action, action)) {\n continue;\n }\n\n // Check if the entry's resource pattern matches the requested resource\n if (this.resourceMatchesPattern(resource, entry.resource)) {\n if (!results.some((r) => r.delegation.cid === entry.delegation.cid)) {\n results.push(entry);\n }\n }\n }\n }\n\n return results;\n }\n\n /**\n * Check if an action pattern matches a specific action.\n *\n * @param pattern - Action pattern (may include wildcard like \"tinycloud.kv/*\")\n * @param action - Specific action to check\n * @returns true if pattern matches action\n */\n private actionMatches(pattern: string, action: string): boolean {\n // Exact match\n if (pattern === action) {\n return true;\n }\n\n // Wildcard match (e.g., \"tinycloud.kv/*\" matches \"tinycloud.kv/get\")\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n return action.startsWith(prefix + \"/\") || action === prefix;\n }\n\n return false;\n }\n\n /**\n * Check if a resource matches a pattern.\n *\n * Patterns support:\n * - Exact match: \"/kv/data\" matches \"/kv/data\"\n * - Wildcard suffix: \"/kv/*\" matches \"/kv/anything\"\n * - Double wildcard: \"/kv/**\" matches \"/kv/any/nested/path\"\n *\n * @param resource - The specific resource being accessed\n * @param pattern - The pattern from the delegation\n * @returns true if resource matches pattern\n */\n private resourceMatchesPattern(resource: string, pattern: string): boolean {\n // Exact match\n if (pattern === resource) {\n return true;\n }\n\n // Double wildcard (**) - matches any nested path\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n return resource.startsWith(prefix);\n }\n\n // Single wildcard (*) - matches one path segment\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n if (!resource.startsWith(prefix)) {\n return false;\n }\n const remainder = resource.slice(prefix.length);\n // Should be a single segment (no more slashes except possibly trailing)\n return !remainder.includes(\"/\") || remainder === \"/\";\n }\n\n // Prefix match for paths ending with /\n if (pattern.endsWith(\"/\") && resource.startsWith(pattern)) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Check if a specific resource matches a resource pattern for searching.\n *\n * @param entryResource - The resource from a capability entry\n * @param searchPattern - The pattern to search for\n * @returns true if entry resource matches search pattern\n */\n private matchesResourcePattern(\n entryResource: string,\n searchPattern: string\n ): boolean {\n // Use the same logic as resourceMatchesPattern\n return this.resourceMatchesPattern(entryResource, searchPattern) ||\n this.resourceMatchesPattern(searchPattern, entryResource);\n }\n}\n\n/**\n * Create a new CapabilityKeyRegistry instance.\n *\n * @returns A new registry instance\n */\nexport function createCapabilityKeyRegistry(): ICapabilityKeyRegistry {\n return new CapabilityKeyRegistry();\n}\n","/**\n * SignStrategy types for TinyCloud authorization.\n *\n * These types define how sign requests are handled across different\n * SDK implementations (web-sdk, node-sdk). The pattern allows for\n * automatic signing, rejection, callback-based approval, or event-driven\n * workflows.\n *\n * @packageDocumentation\n */\n\n/**\n * Sign request passed to callback or event handlers.\n */\nexport interface SignRequest {\n /** Ethereum address of the signer */\n address: string;\n /** Chain ID for the signing context */\n chainId: number;\n /** Message to be signed */\n message: string;\n /** Type of sign operation */\n type: \"siwe\" | \"message\";\n}\n\n/**\n * Sign response from callback or event handlers.\n */\nexport interface SignResponse {\n /** Whether the sign request was approved */\n approved: boolean;\n /** The signature if approved */\n signature?: string;\n /** Reason for rejection if not approved */\n reason?: string;\n}\n\n/**\n * Callback handler type for sign requests.\n */\nexport type SignCallback = (request: SignRequest) => Promise<SignResponse>;\n\n/**\n * Auto-sign strategy: automatically signs all requests.\n *\n * Use cases:\n * - Trusted backend services\n * - Automated scripts\n * - CI/CD pipelines\n *\n * @example\n * ```typescript\n * const strategy: AutoSignStrategy = { type: 'auto-sign' };\n * ```\n */\nexport interface AutoSignStrategy {\n type: \"auto-sign\";\n}\n\n/**\n * Auto-reject strategy: rejects all sign requests.\n *\n * Use cases:\n * - Read-only applications\n * - Testing rejection flows\n *\n * @example\n * ```typescript\n * const strategy: AutoRejectStrategy = { type: 'auto-reject' };\n * ```\n */\nexport interface AutoRejectStrategy {\n type: \"auto-reject\";\n}\n\n/**\n * Callback strategy: delegates sign decisions to a callback function.\n *\n * Use cases:\n * - CLI applications with user prompts\n * - Custom approval workflows\n * - Interactive sign flows\n *\n * @example\n * ```typescript\n * const strategy: CallbackStrategy = {\n * type: 'callback',\n * handler: async (req) => {\n * const approved = await promptUser(`Sign message for ${req.address}?`);\n * return { approved, signature: approved ? await signer.sign(req.message) : undefined };\n * }\n * };\n * ```\n */\nexport interface CallbackStrategy {\n type: \"callback\";\n handler: SignCallback;\n}\n\n/**\n * Event emitter strategy: emits sign requests as events.\n *\n * Uses EventTarget for cross-platform compatibility (browser + Node.js).\n *\n * Events emitted:\n * - 'sign-request': When a sign request is received\n *\n * Use cases:\n * - Async approval workflows\n * - External signing services\n * - Multi-step authorization flows\n *\n * @example\n * ```typescript\n * const emitter = new EventTarget();\n * const strategy: EventEmitterStrategy = { type: 'event-emitter', emitter };\n *\n * emitter.addEventListener('sign-request', async (event) => {\n * const { request, respond } = (event as CustomEvent).detail;\n * const approved = await externalApprovalService.check(request);\n * respond({ approved, signature: approved ? await sign(request.message) : undefined });\n * });\n * ```\n */\nexport interface EventEmitterStrategy {\n type: \"event-emitter\";\n emitter: EventTarget;\n /** Timeout in milliseconds for waiting on event response (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Sign strategy union type.\n *\n * Determines how sign requests are handled in UserAuthorization implementations.\n */\nexport type SignStrategy =\n | AutoSignStrategy\n | AutoRejectStrategy\n | CallbackStrategy\n | EventEmitterStrategy;\n\n/**\n * Default sign strategy is auto-sign for convenience.\n */\nexport const defaultSignStrategy: SignStrategy = { type: \"auto-sign\" };\n","/**\n * Space creation handler types for TinyCloud authorization.\n *\n * These types abstract space creation confirmation, allowing different\n * implementations for web (modal) vs node (auto-approve) environments.\n *\n * @packageDocumentation\n */\n\n/**\n * Context passed to space creation handlers.\n */\nexport interface SpaceCreationContext {\n /** The unique identifier for the space being created */\n spaceId: string;\n /** Ethereum address of the user creating the space */\n address: string;\n /** Chain ID for the creation context */\n chainId: number;\n /** Host URL where the space will be created */\n host: string;\n}\n\n/**\n * Interface for handling space creation confirmation.\n *\n * Implementations can provide different UX patterns:\n * - Auto-approve for backend services\n * - Modal confirmation for web apps\n * - CLI prompts for terminal apps\n *\n * @example\n * ```typescript\n * class ModalSpaceCreationHandler implements ISpaceCreationHandler {\n * async confirmSpaceCreation(context: SpaceCreationContext): Promise<boolean> {\n * return await showConfirmationModal(`Create space ${context.spaceId}?`);\n * }\n *\n * onSpaceCreated(context: SpaceCreationContext): void {\n * showToast(`Space ${context.spaceId} created!`);\n * }\n *\n * onSpaceCreationFailed(context: SpaceCreationContext, error: Error): void {\n * showErrorModal(`Failed to create space: ${error.message}`);\n * }\n * }\n * ```\n */\nexport interface ISpaceCreationHandler {\n /**\n * Called when a new space needs to be created.\n * Returns true if space should be created, false to skip.\n *\n * @param context - Information about the space to be created\n * @returns Promise resolving to true to proceed, false to cancel\n */\n confirmSpaceCreation(context: SpaceCreationContext): Promise<boolean>;\n\n /**\n * Called after successful space creation.\n * Optional - implement to show success UI or perform cleanup.\n *\n * @param context - Information about the created space\n */\n onSpaceCreated?(context: SpaceCreationContext): void;\n\n /**\n * Called if space creation fails.\n * Optional - implement to show error UI or perform recovery.\n *\n * @param context - Information about the space that failed to create\n * @param error - The error that occurred\n */\n onSpaceCreationFailed?(context: SpaceCreationContext, error: Error): void;\n}\n\n/**\n * Default handler that auto-approves all space creation.\n *\n * Use cases:\n * - Backend services\n * - Automated scripts\n * - Node.js applications without UI\n *\n * @example\n * ```typescript\n * const handler = new AutoApproveSpaceCreationHandler();\n * const config = { spaceCreationHandler: handler };\n * ```\n */\nexport class AutoApproveSpaceCreationHandler implements ISpaceCreationHandler {\n /**\n * Always returns true to auto-approve space creation.\n */\n async confirmSpaceCreation(): Promise<boolean> {\n return true;\n }\n}\n\n/**\n * Default space creation handler that auto-approves all requests.\n */\nexport const defaultSpaceCreationHandler: ISpaceCreationHandler =\n new AutoApproveSpaceCreationHandler();\n","/**\n * Protocol version checking for SDK-to-node compatibility.\n *\n * @packageDocumentation\n */\n\nexport class ProtocolMismatchError extends Error {\n name = \"ProtocolMismatchError\" as const;\n constructor(\n public readonly sdkProtocol: number,\n public readonly nodeProtocol: number,\n public readonly nodeVersion: string,\n public readonly host: string\n ) {\n super(\n `SDK protocol version ${sdkProtocol} is incompatible with node protocol version ${nodeProtocol} (node v${nodeVersion}) at ${host}. ` +\n (sdkProtocol < nodeProtocol\n ? \"Please update your SDK.\"\n : \"Please update the TinyCloud node.\")\n );\n }\n}\n\nexport class VersionCheckError extends Error {\n name = \"VersionCheckError\" as const;\n constructor(\n public readonly host: string,\n public readonly cause?: Error\n ) {\n super(\n `Failed to fetch node info at ${host}. Ensure the node is running and the /info endpoint is accessible.`\n );\n }\n}\n\nexport class UnsupportedFeatureError extends Error {\n name = \"UnsupportedFeatureError\" as const;\n constructor(\n public readonly feature: string,\n public readonly host: string,\n public readonly availableFeatures: string[]\n ) {\n super(\n `Feature \"${feature}\" is not supported by the node at ${host}. ` +\n `Available features: ${availableFeatures.join(\", \") || \"none\"}.`\n );\n }\n}\n\nexport interface NodeInfo {\n features: string[];\n quotaUrl?: string;\n}\n\nexport async function checkNodeInfo(\n host: string,\n sdkProtocol: number,\n fetchFn: typeof globalThis.fetch = globalThis.fetch.bind(globalThis)\n): Promise<NodeInfo> {\n let response: Response;\n try {\n response = await fetchFn(`${host}/info`, {\n signal: AbortSignal.timeout(5000),\n });\n } catch (err) {\n throw new VersionCheckError(host, err as Error);\n }\n\n if (!response.ok) {\n throw new VersionCheckError(host);\n }\n\n const data = (await response.json()) as {\n protocol: number;\n version: string;\n features: string[];\n quota_url?: string;\n };\n\n if (sdkProtocol !== data.protocol) {\n throw new ProtocolMismatchError(\n sdkProtocol,\n data.protocol,\n data.version,\n host\n );\n }\n\n return {\n features: data.features ?? [],\n quotaUrl: data.quota_url,\n };\n}\n","/**\n * Capability subset checking and recap parsing.\n *\n * This module powers the capability-chain delegation flow. The key decision\n * a `delegateTo` call has to make is: \"are the requested capabilities a\n * subset of what the current session already grants?\"\n *\n * - If yes → issue the delegation via the session-key UCAN path (no wallet prompt).\n * - If no → raise {@link PermissionNotInManifestError} so the caller can\n * trigger an escalation flow via `requestPermissions`.\n *\n * Canonical spec: `.claude/specs/capability-chain.md`.\n *\n * @packageDocumentation\n */\n\nimport {\n type PermissionEntry,\n SERVICE_SHORT_TO_LONG,\n expandActionShortNames,\n} from \"./manifest\";\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a `delegateTo` call requests capabilities that the current\n * session does not already grant. The caller can catch this and trigger\n * `requestPermissions(missing)` to show an escalation modal.\n */\nexport class PermissionNotInManifestError extends Error {\n public readonly missing: PermissionEntry[];\n public readonly granted: PermissionEntry[];\n\n constructor(missing: PermissionEntry[], granted: PermissionEntry[]) {\n super(\n `Requested capabilities exceed current session. Missing ${missing.length} entries.`\n );\n this.name = \"PermissionNotInManifestError\";\n this.missing = missing;\n this.granted = granted;\n }\n}\n\n/**\n * Thrown when the current session has expired (or will expire within the\n * safety margin). The caller should trigger a fresh sign-in.\n */\nexport class SessionExpiredError extends Error {\n public readonly expiredAt: Date;\n\n constructor(expiredAt: Date) {\n super(`Session expired at ${expiredAt.toISOString()}`);\n this.name = \"SessionExpiredError\";\n this.expiredAt = expiredAt;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Space normalization\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a space identifier to its short-name form.\n *\n * Recap resource URIs in a signed SIWE encode the space as a full URI of the\n * form `tinycloud:pkh:eip155:{chainId}:{address}:{name}` (e.g.\n * `tinycloud:pkh:eip155:1:0xd559...:default`). Manifest permissions and\n * backend-advertised permissions use the short `{name}` form (e.g.\n * `\"default\"`).\n *\n * Strict string comparison between these two forms would always fail, so we\n * normalize both sides to the short name before comparing. The trailing\n * segment after the last `:` in a `tinycloud:` URI is the space name.\n *\n * Short names (`\"default\"`, `\"work-space\"`) are returned unchanged.\n * Any non-`tinycloud:` string is returned unchanged. A malformed URI with a\n * trailing colon is returned unchanged (so the check degrades to a strict\n * mismatch rather than collapsing to an empty string).\n *\n * @internal\n */\nexport function normalizeSpace(space: string): string {\n if (!space.startsWith(\"tinycloud:\")) {\n return space;\n }\n const lastColon = space.lastIndexOf(\":\");\n if (lastColon === -1 || lastColon === space.length - 1) {\n return space;\n }\n return space.slice(lastColon + 1);\n}\n\n// ---------------------------------------------------------------------------\n// Subset check\n// ---------------------------------------------------------------------------\n\nexport interface SubsetCheckResult {\n /** True when every requested entry is covered by a granted entry. */\n subset: boolean;\n /** Entries the granted set does not cover (empty when `subset` is true). */\n missing: PermissionEntry[];\n}\n\n/**\n * Check whether `requested` is a strict subset of `granted`.\n *\n * Matching rules for each `requested[i]`:\n * - `service` matches exactly.\n * - `space` matches exactly.\n * - Path containment:\n * - If `granted.path` ends with `/`, it covers any `requested.path` that\n * starts with `granted.path`.\n * - Otherwise, the paths must match exactly.\n * - Action containment: every URN in `requested.actions` must appear in\n * `granted.actions` (set subset).\n *\n * Any `requested` entry that does not find a matching `granted` entry is\n * added to `missing` and the overall result is non-subset.\n *\n * Both sides are expected to be in the canonical long-form shape (service\n * starts with `tinycloud.`, actions are full URNs). Use {@link parseRecapCapabilities}\n * or `expandActionShortNames` to normalize inputs first.\n */\nexport function isCapabilitySubset(\n requested: readonly PermissionEntry[],\n granted: readonly PermissionEntry[]\n): SubsetCheckResult {\n const missing: PermissionEntry[] = [];\n\n for (const req of requested) {\n const match = granted.find((g) => canonicalizeEntryMatches(req, g));\n if (match === undefined) {\n missing.push(cloneEntry(req));\n continue;\n }\n // `match` is confirmed to cover `req`; nothing to record.\n }\n\n return { subset: missing.length === 0, missing };\n}\n\n/**\n * Returns true when `granted` fully covers `requested` — same service, same\n * space, path containment per spec, and action set containment.\n */\nfunction canonicalizeEntryMatches(\n requested: PermissionEntry,\n granted: PermissionEntry\n): boolean {\n if (requested.service !== granted.service) {\n return false;\n }\n // Normalize both sides so callers passing short names (`\"default\"`) match\n // recap-parsed full URIs (`\"tinycloud:pkh:eip155:1:0xd559...:default\"`) and\n // vice versa. Idempotent for short names.\n if (normalizeSpace(requested.space) !== normalizeSpace(granted.space)) {\n return false;\n }\n if (!pathContains(granted.path, requested.path)) {\n return false;\n }\n // Normalize actions to full URN form on both sides before set comparison,\n // so a caller passing short names (\"get\") against a granted entry with\n // full URNs still behaves correctly.\n const reqActions = new Set(\n expandActionShortNames(requested.service, requested.actions)\n );\n const grantedActions = new Set(\n expandActionShortNames(granted.service, granted.actions)\n );\n for (const a of reqActions) {\n if (!grantedActions.has(a)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Path containment per spec:\n * - `granted.path` ends with `/` → prefix match (requested starts with granted)\n * - otherwise → exact string match\n *\n * The empty string is treated as \"no path constraint\" and matches anything.\n * The single-character `\"/\"` also matches anything (it is a trailing-slash\n * prefix of zero-length).\n */\nfunction pathContains(grantedPath: string, requestedPath: string): boolean {\n if (grantedPath === \"\" || grantedPath === \"/\") {\n return true;\n }\n if (grantedPath.endsWith(\"/\")) {\n return requestedPath.startsWith(grantedPath);\n }\n return requestedPath === grantedPath;\n}\n\nfunction cloneEntry(entry: PermissionEntry): PermissionEntry {\n return {\n service: entry.service,\n space: entry.space,\n path: entry.path,\n actions: [...entry.actions],\n ...(entry.skipPrefix !== undefined ? { skipPrefix: entry.skipPrefix } : {}),\n ...(entry.expiry !== undefined ? { expiry: entry.expiry } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Recap parsing (WASM wrapper)\n// ---------------------------------------------------------------------------\n\n/**\n * The raw shape returned from the WASM `parseRecapFromSiwe` export. The\n * Rust layer encodes the service in the short form (e.g. `\"kv\"`) because\n * that is what the SIWE recap resource URI actually contains. We normalize\n * to the manifest long form (`\"tinycloud.kv\"`) in {@link parseRecapCapabilities}.\n *\n * @internal\n */\nexport interface WasmRecapEntry {\n service: string;\n space: string;\n path: string;\n actions: string[];\n}\n\n/**\n * Signature of the WASM `parseRecapFromSiwe` export. Accepts the signed\n * SIWE message string and returns an array of raw recap entries. Throws if\n * the SIWE is malformed or the recap statement has been tampered.\n *\n * Exposed as an interface so the SDK can inject the web or node binding\n * without `capabilities.ts` needing to know which.\n */\nexport type ParseRecapFromSiwe = (siweString: string) => WasmRecapEntry[];\n\n/**\n * Parse a signed SIWE message into an array of {@link PermissionEntry}\n * objects in the canonical long-form manifest shape.\n *\n * This is a thin wrapper around the WASM `parseRecapFromSiwe` export that:\n * 1. Normalizes short-form services (`\"kv\"`) to long-form (`\"tinycloud.kv\"`).\n * 2. Returns entries in a deterministic order (sorted by space, then service,\n * then path) so downstream equality checks are stable.\n *\n * Returns an empty array when the SIWE has no recap resource (plain auth\n * SIWE); this matches the WASM function's behavior and the spec.\n *\n * @param parseWasm The WASM `parseRecapFromSiwe` binding.\n * @param siwe The signed SIWE message string (exactly what `session.siwe` stores).\n */\nexport function parseRecapCapabilities(\n parseWasm: ParseRecapFromSiwe,\n siwe: string\n): PermissionEntry[] {\n const raw = parseWasm(siwe);\n if (!Array.isArray(raw)) {\n throw new Error(\n \"parseRecapFromSiwe returned a non-array value; wasm binding may be out of sync\"\n );\n }\n const normalized: PermissionEntry[] = raw.map((entry) => {\n const longService =\n SERVICE_SHORT_TO_LONG[entry.service] ??\n // Unknown short names pass through. If the recap already contained a\n // long-form service (e.g. a future tinycloud-node version emits long\n // form directly), don't double-prefix.\n (entry.service.startsWith(\"tinycloud.\")\n ? entry.service\n : `tinycloud.${entry.service}`);\n return {\n service: longService,\n // The Rust layer emits the space as a full `tinycloud:pkh:...:name`\n // URI (the recap target URI). Normalize to the short name so the\n // returned entries match the shape manifests use.\n space: normalizeSpace(entry.space),\n path: entry.path,\n actions: [...entry.actions],\n };\n });\n\n // Sort for determinism (callers do equality checks on arrays of entries\n // in tests; deterministic ordering keeps those stable).\n normalized.sort((a, b) => {\n if (a.space !== b.space) return a.space < b.space ? -1 : 1;\n if (a.service !== b.service) return a.service < b.service ? -1 : 1;\n if (a.path !== b.path) return a.path < b.path ? -1 : 1;\n return 0;\n });\n\n return normalized;\n}\n"],"mappings":"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","names":["import_zod","EnsDataSchema","import_sdk_services","import_zod","import_zod","errorText","import_sdk_services","import_zod","ms","createError","err","import_sdk_services","SERVICE_NAME","err"]}
|