@pindownai/client-js 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/tier-limits.json","../src/config/token-costs.json","../src/errors/index.ts","../src/utils/RateLimiter.ts","../src/client/pins/index.ts","../src/client/pinboards/index.ts","../src/client/datasets/index.ts","../src/client/blocks/index.ts","../src/client/collaborators/index.ts","../src/client/PindownClient.ts"],"names":["tier_limits_default","token_costs_default","PindownError","message","AuthenticationError","ForbiddenError","NotFoundError","resource","ValidationError","details","RateLimitError","params","ServerError","statusCode","NetworkError","TIER_LIMITS","TOKEN_COSTS","RateLimiter","tier","method","endpoint","body","cost","minuteWindow","hourWindow","limits","used","hourUsed","ops","pins","now","window","current","minuteUsed","twoHoursAgo","key","windowKey","parts","year","month","day","hour","minute","PinsMethods","client","request","pinId","options","query","content","metadata","data","url","PinboardsMethods","boardId","DatasetsMethods","datasetId","BlocksMethods","blockId","CollaboratorsMethods","userId","PindownClient","config","headers","requestOptions","response","error","errorData","tierHeader"],"mappings":"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","file":"index.cjs","sourcesContent":["{\r\n \"starter\": {\r\n \"tokensPerHour\": 16,\r\n \"tokensPerMinute\": null\r\n },\r\n \"hobby\": {\r\n \"tokensPerHour\": 6000,\r\n \"tokensPerMinute\": 100\r\n },\r\n \"pro\": {\r\n \"tokensPerHour\": 24000,\r\n \"tokensPerMinute\": 400\r\n },\r\n \"teams\": {\r\n \"tokensPerHour\": 60000,\r\n \"tokensPerMinute\": 1000\r\n },\r\n \"agency\": {\r\n \"tokensPerHour\": 240000,\r\n \"tokensPerMinute\": 4000\r\n }\r\n}\r\n\r\n","{\r\n \"GET\": 1,\r\n \"POST\": 1,\r\n \"PUT\": 1,\r\n \"DELETE\": 1,\r\n \"INVITE\": 3,\r\n \"SHARE\": 3,\r\n \"BATCH_1_10\": 3,\r\n \"BATCH_11_25\": 5,\r\n \"BATCH_26_50\": 10\r\n}\r\n","/**\r\n * Error classes for Pindown API Client\r\n */\r\n\r\nimport type { Tier } from '../types/config'\r\n\r\nexport class PindownError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'PindownError'\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PindownError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message)\r\n this.name = 'AuthenticationError'\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends PindownError {\r\n constructor(message: string = 'Access forbidden') {\r\n super(message)\r\n this.name = 'ForbiddenError'\r\n }\r\n}\r\n\r\nexport class NotFoundError extends PindownError {\r\n constructor(resource: string) {\r\n super(`${resource} not found`)\r\n this.name = 'NotFoundError'\r\n }\r\n}\r\n\r\nexport class ValidationError extends PindownError {\r\n public details?: any\r\n\r\n constructor(message: string, details?: any) {\r\n super(message)\r\n this.name = 'ValidationError'\r\n this.details = details\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PindownError {\r\n public window: 'minute' | 'hour'\r\n public limit: number\r\n public used: number\r\n public remaining: number\r\n public resetAt: Date\r\n public tier: Tier\r\n\r\n constructor(params: {\r\n window: 'minute' | 'hour'\r\n limit: number\r\n used: number\r\n remaining: number\r\n resetAt: Date\r\n tier: Tier\r\n }) {\r\n super(\r\n `Rate limit exceeded: ${params.used}/${params.limit} tokens used in ${params.window} window. ` +\r\n `Resets at ${params.resetAt.toISOString()}`\r\n )\r\n this.name = 'RateLimitError'\r\n this.window = params.window\r\n this.limit = params.limit\r\n this.used = params.used\r\n this.remaining = params.remaining\r\n this.resetAt = params.resetAt\r\n this.tier = params.tier\r\n }\r\n}\r\n\r\nexport class ServerError extends PindownError {\r\n public statusCode: number\r\n\r\n constructor(message: string, statusCode: number = 500) {\r\n super(message)\r\n this.name = 'ServerError'\r\n this.statusCode = statusCode\r\n }\r\n}\r\n\r\nexport class NetworkError extends PindownError {\r\n constructor(message: string = 'Network request failed') {\r\n super(message)\r\n this.name = 'NetworkError'\r\n }\r\n}\r\n\r\n","/**\r\n * Rate Limiter - Client-side rate limiting with in-memory counters\r\n */\r\n\r\nimport tierLimitsJson from '../config/tier-limits.json'\r\nimport tokenCostsJson from '../config/token-costs.json'\r\nimport { RateLimitError } from '../errors'\r\nimport type { Tier } from '../types/config'\r\nimport type { RateLimitInfo } from '../types/api'\r\n\r\nconst TIER_LIMITS = tierLimitsJson as Record<Tier, { tokensPerHour: number; tokensPerMinute: number | null }>\r\nconst TOKEN_COSTS = tokenCostsJson as Record<string, number>\r\n\r\nexport class RateLimiter {\r\n private tier: Tier\r\n private minuteTokens = new Map<string, number>()\r\n private hourTokens = new Map<string, number>()\r\n private cleanupInterval: NodeJS.Timeout | number\r\n\r\n constructor(tier: Tier) {\r\n this.tier = tier\r\n \r\n // Auto-cleanup expired windows every 5 minutes\r\n this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000)\r\n }\r\n\r\n /**\r\n * Check if request is allowed, throw RateLimitError if limit reached\r\n */\r\n checkLimit(method: string, endpoint: string, body?: any): void {\r\n const cost = this.calculateTokenCost(method, endpoint, body)\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const limits = TIER_LIMITS[this.tier]\r\n \r\n // Check minute limit (if exists)\r\n if (limits.tokensPerMinute !== null) {\r\n const used = this.minuteTokens.get(minuteWindow) || 0\r\n if (used + cost > limits.tokensPerMinute) {\r\n throw new RateLimitError({\r\n window: 'minute',\r\n limit: limits.tokensPerMinute,\r\n used,\r\n remaining: Math.max(0, limits.tokensPerMinute - used),\r\n resetAt: this.getMinuteResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n }\r\n \r\n // Check hour limit\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n if (hourUsed + cost > limits.tokensPerHour) {\r\n throw new RateLimitError({\r\n window: 'hour',\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n \r\n // Increment counters\r\n this.incrementToken(minuteWindow, cost)\r\n this.incrementToken(hourWindow, cost)\r\n }\r\n\r\n /**\r\n * Calculate token cost for a request\r\n */\r\n private calculateTokenCost(method: string, endpoint: string, body?: any): number {\r\n // Check for batch endpoints\r\n if (endpoint.includes('/batch') || endpoint.includes('/sync')) {\r\n if (body?.operations) {\r\n const ops = Array.isArray(body.operations) ? body.operations.length : 0\r\n if (ops <= 10) return TOKEN_COSTS.BATCH_1_10\r\n if (ops <= 25) return TOKEN_COSTS.BATCH_11_25\r\n if (ops <= 50) return TOKEN_COSTS.BATCH_26_50\r\n return TOKEN_COSTS.BATCH_26_50 // Cap at 50\r\n }\r\n // For /sync endpoints, check pins array\r\n if (body?.pins) {\r\n const pins = Array.isArray(body.pins) ? body.pins.length : 0\r\n if (pins <= 16) return 5 // As per RATE_LIMITING_STRATEGY.md\r\n if (pins <= 32) return 8\r\n return 8 // Cap at 32\r\n }\r\n }\r\n \r\n // Check for invite/share endpoints\r\n if (endpoint.includes('/collaborators') || endpoint.includes('/invite') || endpoint.includes('/share')) {\r\n return TOKEN_COSTS.INVITE\r\n }\r\n \r\n // Standard methods (all cost 1 token)\r\n return TOKEN_COSTS[method] || 1\r\n }\r\n\r\n /**\r\n * Get current minute window key\r\n */\r\n private getMinuteWindow(): string {\r\n const now = new Date()\r\n return `minute_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}-${String(now.getMinutes()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Get current hour window key\r\n */\r\n private getHourWindow(): string {\r\n const now = new Date()\r\n return `hour_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Increment token count for a window\r\n */\r\n private incrementToken(window: string, cost: number): void {\r\n if (window.startsWith('minute')) {\r\n const current = this.minuteTokens.get(window) || 0\r\n this.minuteTokens.set(window, current + cost)\r\n } else {\r\n const current = this.hourTokens.get(window) || 0\r\n this.hourTokens.set(window, current + cost)\r\n }\r\n }\r\n\r\n /**\r\n * Get reset time for current minute window\r\n */\r\n private getMinuteResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes() + 1, 0, 0)\r\n }\r\n\r\n /**\r\n * Get reset time for current hour window\r\n */\r\n private getHourResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0)\r\n }\r\n\r\n /**\r\n * Get current rate limit info\r\n */\r\n getRateLimitInfo(): RateLimitInfo {\r\n const limits = TIER_LIMITS[this.tier]\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const minuteUsed = this.minuteTokens.get(minuteWindow) || 0\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n \r\n return {\r\n tier: this.tier,\r\n minute: {\r\n limit: limits.tokensPerMinute || 0,\r\n used: minuteUsed,\r\n remaining: limits.tokensPerMinute \r\n ? Math.max(0, limits.tokensPerMinute - minuteUsed)\r\n : Infinity,\r\n resetAt: this.getMinuteResetTime()\r\n },\r\n hour: {\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime()\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup expired windows (older than 2 hours)\r\n */\r\n private cleanup(): void {\r\n const now = Date.now()\r\n const twoHoursAgo = now - 2 * 60 * 60 * 1000\r\n \r\n // Parse and remove old minute windows\r\n for (const [key] of this.minuteTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.minuteTokens.delete(key)\r\n }\r\n }\r\n \r\n // Parse and remove old hour windows\r\n for (const [key] of this.hourTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.hourTokens.delete(key)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Parse timestamp from window key\r\n */\r\n private parseWindowTimestamp(windowKey: string): number {\r\n const parts = windowKey.split('_')[1].split('-')\r\n const year = parseInt(parts[0])\r\n const month = parseInt(parts[1]) - 1\r\n const day = parseInt(parts[2])\r\n const hour = parseInt(parts[3])\r\n const minute = windowKey.startsWith('minute') ? parseInt(parts[4]) : 0\r\n \r\n return new Date(year, month, day, hour, minute).getTime()\r\n }\r\n\r\n /**\r\n * Destroy the rate limiter (cleanup interval)\r\n */\r\n destroy(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval as NodeJS.Timeout)\r\n }\r\n }\r\n}\r\n\r\n","/**\r\n * Pins API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Pin,\r\n CreatePinRequest,\r\n UpdatePinRequest,\r\n SharePinRequest,\r\n ListPinsOptions,\r\n PaginatedResponse\r\n} from '../../types/api'\r\n\r\nexport class PinsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new pin\r\n */\r\n async create(request: CreatePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('POST', '/pins', request)\r\n }\r\n\r\n /**\r\n * Get a pin by ID\r\n */\r\n async get(pinId: string): Promise<Pin> {\r\n return this.client.request<Pin>('GET', `/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * List all pins\r\n */\r\n async list(options?: ListPinsOptions): Promise<PaginatedResponse<Pin>> {\r\n const params = new URLSearchParams()\r\n if (options?.limit) params.append('limit', options.limit.toString())\r\n if (options?.offset) params.append('offset', options.offset.toString())\r\n\r\n const query = params.toString()\r\n const endpoint = query ? `/pins?${query}` : '/pins'\r\n\r\n return this.client.request<PaginatedResponse<Pin>>('GET', endpoint)\r\n }\r\n\r\n /**\r\n * Update a pin\r\n */\r\n async update(pinId: string, request: UpdatePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('PUT', `/pins/${pinId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a pin\r\n */\r\n async delete(pinId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * Update pin sharing settings\r\n */\r\n async share(pinId: string, request: SharePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('POST', `/pins/${pinId}/share`, request)\r\n }\r\n\r\n // ============================================\r\n // Helper methods for common pin types\r\n // ============================================\r\n\r\n /**\r\n * Create a markdown pin\r\n */\r\n async createMarkdown(content: string, metadata?: CreatePinRequest['metadata']): Promise<Pin> {\r\n return this.create({\r\n data_type: 'markdown',\r\n content,\r\n metadata\r\n })\r\n }\r\n\r\n /**\r\n * Create a stat card pin\r\n */\r\n async createStatCard(data: {\r\n title: string\r\n value: string | number\r\n change?: string\r\n icon?: string\r\n }, metadata?: CreatePinRequest['metadata']): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n pin_card_type: 'stat-cards',\r\n content: [data],\r\n metadata\r\n })\r\n }\r\n\r\n /**\r\n * Create a flexible table pin\r\n */\r\n async createTable(data: {\r\n columns: Array<{ id: string; label: string; type?: string }>\r\n rows: Array<Record<string, any>>\r\n }, metadata?: CreatePinRequest['metadata']): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n pin_card_type: 'flexible-table',\r\n content: data,\r\n metadata\r\n })\r\n }\r\n\r\n /**\r\n * Create an embed pin (YouTube, Figma, etc.)\r\n */\r\n async createEmbed(url: string, metadata?: CreatePinRequest['metadata']): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n pin_card_type: 'embed',\r\n content: { url },\r\n metadata\r\n })\r\n }\r\n}\r\n\r\n","/**\r\n * Pinboards API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Pinboard,\r\n CreatePinboardRequest,\r\n UpdatePinboardRequest,\r\n AddPinToPinboardRequest,\r\n UpdatePinboardLayoutRequest\r\n} from '../../types/api'\r\n\r\nexport class PinboardsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new pinboard\r\n */\r\n async create(request: CreatePinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', '/pinboards', request)\r\n }\r\n\r\n /**\r\n * Get a pinboard by ID\r\n */\r\n async get(boardId: string): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('GET', `/pinboards/${boardId}`)\r\n }\r\n\r\n /**\r\n * List all pinboards\r\n */\r\n async list(): Promise<Pinboard[]> {\r\n return this.client.request<Pinboard[]>('GET', '/pinboards')\r\n }\r\n\r\n /**\r\n * Update a pinboard\r\n */\r\n async update(boardId: string, request: UpdatePinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a pinboard\r\n */\r\n async delete(boardId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pinboards/${boardId}`)\r\n }\r\n\r\n /**\r\n * Add a pin to a pinboard\r\n */\r\n async addPin(boardId: string, request: AddPinToPinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/pins`, request)\r\n }\r\n\r\n /**\r\n * Remove a pin from a pinboard\r\n */\r\n async removePin(boardId: string, pinId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pinboards/${boardId}/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * Update pinboard layout\r\n */\r\n async updateLayout(boardId: string, request: UpdatePinboardLayoutRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}/layout`, request)\r\n }\r\n\r\n /**\r\n * Update pinboard sharing settings\r\n */\r\n async share(boardId: string, request: {\r\n is_public?: boolean\r\n require_sign_in?: boolean\r\n allow_comments?: boolean\r\n }): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/share`, request)\r\n }\r\n}\r\n\r\n","/**\r\n * Datasets API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Dataset,\r\n CreateDatasetRequest,\r\n UpdateDatasetRequest\r\n} from '../../types/api'\r\n\r\nexport class DatasetsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new dataset\r\n */\r\n async create(request: CreateDatasetRequest): Promise<Dataset> {\r\n return this.client.request<Dataset>('POST', '/datasets', request)\r\n }\r\n\r\n /**\r\n * Get a dataset by ID\r\n */\r\n async get(datasetId: string): Promise<Dataset> {\r\n return this.client.request<Dataset>('GET', `/datasets/${datasetId}`)\r\n }\r\n\r\n /**\r\n * List all datasets\r\n */\r\n async list(): Promise<Dataset[]> {\r\n return this.client.request<Dataset[]>('GET', '/datasets')\r\n }\r\n\r\n /**\r\n * Update a dataset\r\n */\r\n async update(datasetId: string, request: UpdateDatasetRequest): Promise<Dataset> {\r\n return this.client.request<Dataset>('PUT', `/datasets/${datasetId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a dataset\r\n */\r\n async delete(datasetId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/datasets/${datasetId}`)\r\n }\r\n}\r\n\r\n","/**\r\n * Blocks API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Block,\r\n CreateBlockRequest,\r\n UpdateBlockRequest\r\n} from '../../types/api'\r\n\r\nexport class BlocksMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new block for a pin\r\n */\r\n async create(pinId: string, request: CreateBlockRequest): Promise<Block> {\r\n return this.client.request<Block>('POST', `/pins/${pinId}/blocks`, request)\r\n }\r\n\r\n /**\r\n * Get a block by ID\r\n */\r\n async get(pinId: string, blockId: string): Promise<Block> {\r\n return this.client.request<Block>('GET', `/pins/${pinId}/blocks/${blockId}`)\r\n }\r\n\r\n /**\r\n * List all blocks in a pin\r\n */\r\n async list(pinId: string): Promise<Block[]> {\r\n return this.client.request<Block[]>('GET', `/pins/${pinId}/blocks`)\r\n }\r\n\r\n /**\r\n * Update a block\r\n */\r\n async update(pinId: string, blockId: string, request: UpdateBlockRequest): Promise<Block> {\r\n return this.client.request<Block>('PUT', `/pins/${pinId}/blocks/${blockId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a block\r\n */\r\n async delete(pinId: string, blockId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pins/${pinId}/blocks/${blockId}`)\r\n }\r\n}\r\n\r\n","/**\r\n * Collaborators API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Collaborator,\r\n InviteCollaboratorRequest,\r\n UpdateCollaboratorRoleRequest,\r\n Permissions\r\n} from '../../types/api'\r\n\r\nexport class CollaboratorsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n // ============================================\r\n // Pin Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pin\r\n */\r\n async listForPin(pinId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pins/${pinId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pin\r\n */\r\n async inviteToPin(pinId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pins/${pinId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pin collaborator's role\r\n */\r\n async updatePinRole(pinId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pins/${pinId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pin\r\n */\r\n async removeFromPin(pinId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pins/${pinId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pin\r\n */\r\n async getPinPermissions(pinId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pins/${pinId}/permissions`)\r\n }\r\n\r\n // ============================================\r\n // Pinboard Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pinboard\r\n */\r\n async listForPinboard(boardId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pinboards/${boardId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pinboard\r\n */\r\n async inviteToPinboard(boardId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pinboards/${boardId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pinboard collaborator's role\r\n */\r\n async updatePinboardRole(boardId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pinboards/${boardId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pinboard\r\n */\r\n async removeFromPinboard(boardId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pinboards/${boardId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pinboard\r\n */\r\n async getPinboardPermissions(boardId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pinboards/${boardId}/permissions`)\r\n }\r\n}\r\n\r\n","/**\r\n * Pindown API Client\r\n */\r\n\r\nimport { RateLimiter } from '../utils/RateLimiter'\r\nimport { PinsMethods } from './pins'\r\nimport { PinboardsMethods } from './pinboards'\r\nimport { DatasetsMethods } from './datasets'\r\nimport { BlocksMethods } from './blocks'\r\nimport { CollaboratorsMethods } from './collaborators'\r\nimport type { PindownConfig, Tier } from '../types/config'\r\nimport type { RateLimitInfo } from '../types/api'\r\nimport {\r\n AuthenticationError,\r\n ForbiddenError,\r\n NotFoundError,\r\n ValidationError,\r\n ServerError,\r\n NetworkError\r\n} from '../errors'\r\n\r\nexport class PindownClient {\r\n private config: Omit<Required<PindownConfig>, 'tier'> & { tier?: Tier }\r\n private rateLimiter?: RateLimiter\r\n private tierDetected: boolean = false\r\n\r\n public readonly pins: PinsMethods\r\n public readonly pinboards: PinboardsMethods\r\n public readonly datasets: DatasetsMethods\r\n public readonly blocks: BlocksMethods\r\n public readonly collaborators: CollaboratorsMethods\r\n\r\n constructor(config: PindownConfig) {\r\n // Validate required config\r\n if (!config.apiKey) {\r\n throw new Error('API key is required')\r\n }\r\n\r\n // Set defaults\r\n this.config = {\r\n apiKey: config.apiKey,\r\n tier: config.tier, // Optional - will be auto-detected\r\n baseURL: config.baseURL || 'https://api.pindown.ai/api/v1',\r\n enableRateLimitTracking: config.enableRateLimitTracking ?? true,\r\n maxRetries: config.maxRetries ?? 3,\r\n timeout: config.timeout ?? 30000\r\n }\r\n\r\n // Initialize rate limiter if tier is provided\r\n if (this.config.tier) {\r\n this.rateLimiter = new RateLimiter(this.config.tier)\r\n this.tierDetected = true\r\n }\r\n\r\n // Initialize API methods\r\n this.pins = new PinsMethods(this)\r\n this.pinboards = new PinboardsMethods(this)\r\n this.datasets = new DatasetsMethods(this)\r\n this.blocks = new BlocksMethods(this)\r\n this.collaborators = new CollaboratorsMethods(this)\r\n }\r\n\r\n /**\r\n * Core request method\r\n */\r\n async request<T = any>(\r\n method: string,\r\n endpoint: string,\r\n data?: any\r\n ): Promise<T> {\r\n // Check rate limit BEFORE making request (if tier is detected)\r\n if (this.config.enableRateLimitTracking && this.rateLimiter) {\r\n this.rateLimiter.checkLimit(method, endpoint, data)\r\n }\r\n\r\n const url = `${this.config.baseURL}${endpoint}`\r\n const headers: Record<string, string> = {\r\n 'Authorization': `Bearer ${this.config.apiKey}`,\r\n 'Content-Type': 'application/json'\r\n }\r\n\r\n const requestOptions: RequestInit = {\r\n method,\r\n headers,\r\n signal: AbortSignal.timeout(this.config.timeout)\r\n }\r\n\r\n if (data && (method === 'POST' || method === 'PUT')) {\r\n requestOptions.body = JSON.stringify(data)\r\n }\r\n\r\n try {\r\n const response = await fetch(url, requestOptions)\r\n\r\n // Auto-detect tier from response headers (if not already detected)\r\n if (!this.tierDetected && this.config.enableRateLimitTracking) {\r\n this.detectTierFromHeaders(response.headers)\r\n }\r\n\r\n // Handle error responses\r\n if (!response.ok) {\r\n await this.handleErrorResponse(response)\r\n }\r\n\r\n // Parse JSON response\r\n const result = await response.json()\r\n return result.data as T\r\n } catch (error: any) {\r\n // Re-throw our custom errors\r\n if (\r\n error instanceof AuthenticationError ||\r\n error instanceof ForbiddenError ||\r\n error instanceof NotFoundError ||\r\n error instanceof ValidationError ||\r\n error instanceof ServerError\r\n ) {\r\n throw error\r\n }\r\n\r\n // Network or timeout errors\r\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\r\n throw new NetworkError('Request timeout')\r\n }\r\n\r\n throw new NetworkError(error.message || 'Network request failed')\r\n }\r\n }\r\n\r\n /**\r\n * Handle error responses from API\r\n */\r\n private async handleErrorResponse(response: Response): Promise<never> {\r\n let errorData: any\r\n\r\n try {\r\n errorData = await response.json()\r\n } catch {\r\n errorData = { message: response.statusText }\r\n }\r\n\r\n const message = errorData.error?.message || errorData.message || 'Unknown error'\r\n\r\n switch (response.status) {\r\n case 401:\r\n throw new AuthenticationError(message)\r\n case 403:\r\n throw new ForbiddenError(message)\r\n case 404:\r\n throw new NotFoundError(message)\r\n case 400:\r\n case 422:\r\n throw new ValidationError(message, errorData.error?.details)\r\n case 429:\r\n // Rate limit error from server (should rarely happen with client-side limiting)\r\n throw new ValidationError('Rate limit exceeded (server)', errorData)\r\n case 500:\r\n case 502:\r\n case 503:\r\n throw new ServerError(message, response.status)\r\n default:\r\n throw new ServerError(message, response.status)\r\n }\r\n }\r\n\r\n /**\r\n * Detect tier from response headers\r\n */\r\n private detectTierFromHeaders(headers: Headers): void {\r\n const tierHeader = headers.get('X-RateLimit-Tier')\r\n if (tierHeader && !this.rateLimiter) {\r\n const tier = tierHeader.toLowerCase() as Tier\r\n console.log(`[Pindown Client] Auto-detected tier: ${tier}`)\r\n this.config.tier = tier\r\n this.rateLimiter = new RateLimiter(tier)\r\n this.tierDetected = true\r\n }\r\n }\r\n\r\n /**\r\n * Get current rate limit info\r\n */\r\n getRateLimitInfo(): RateLimitInfo | null {\r\n if (!this.rateLimiter) {\r\n return null\r\n }\r\n return this.rateLimiter.getRateLimitInfo()\r\n }\r\n\r\n /**\r\n * Get current tier\r\n */\r\n getTier(): Tier | null {\r\n return this.config.tier || null\r\n }\r\n\r\n /**\r\n * Destroy the client (cleanup resources)\r\n */\r\n destroy(): void {\r\n if (this.rateLimiter) {\r\n this.rateLimiter.destroy()\r\n }\r\n }\r\n}\r\n\r\n"]}
1
+ {"version":3,"sources":["../src/config/tier-limits.json","../src/config/token-costs.json","../src/errors/index.ts","../src/utils/RateLimiter.ts","../src/client/pins/index.ts","../src/client/pinboards/index.ts","../src/client/datasets/index.ts","../src/client/blocks/index.ts","../src/client/collaborators/index.ts","../src/client/PindownClient.ts"],"names":["tier_limits_default","token_costs_default","PindownError","message","AuthenticationError","ForbiddenError","NotFoundError","resource","ValidationError","details","RateLimitError","params","ServerError","statusCode","NetworkError","TIER_LIMITS","TOKEN_COSTS","RateLimiter","tier","method","endpoint","body","cost","minuteWindow","hourWindow","limits","used","hourUsed","ops","pins","now","window","current","minuteUsed","twoHoursAgo","key","windowKey","parts","year","month","day","hour","minute","PinsMethods","client","request","pinId","options","query","title","additionalMetadata","data","url","PinboardsMethods","boardId","DatasetsMethods","datasetId","BlocksMethods","blockId","CollaboratorsMethods","userId","PindownClient","config","headers","requestOptions","response","error","errorData","tierHeader"],"mappings":"aAAA,IAAAA,CAAAA,CAAA,CACE,OAAA,CAAW,CACT,aAAA,CAAiB,EAAA,CACjB,eAAA,CAAmB,IACrB,CAAA,CACA,KAAA,CAAS,CACP,aAAA,CAAiB,GAAA,CACjB,eAAA,CAAmB,GACrB,CAAA,CACA,GAAA,CAAO,CACL,aAAA,CAAiB,IAAA,CACjB,eAAA,CAAmB,GACrB,CAAA,CACA,KAAA,CAAS,CACP,aAAA,CAAiB,GAAA,CACjB,eAAA,CAAmB,GACrB,EACA,MAAA,CAAU,CACR,aAAA,CAAiB,IAAA,CACjB,eAAA,CAAmB,GACrB,CACF,CAAA,CCrBA,IAAAC,CAAAA,CAAA,CACE,GAAA,CAAO,CAAA,CACP,IAAA,CAAQ,CAAA,CACR,GAAA,CAAO,CAAA,CACP,MAAA,CAAU,CAAA,CACV,MAAA,CAAU,CAAA,CACV,KAAA,CAAS,CAAA,CACT,UAAA,CAAc,CAAA,CACd,WAAA,CAAe,CAAA,CACf,WAAA,CAAe,EACjB,CAAA,KCJaC,CAAAA,CAAN,cAA2B,KAAM,CACtC,WAAA,CAAYC,CAAAA,CAAiB,CAC3B,KAAA,CAAMA,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,eACd,CACF,CAAA,CAEaC,CAAAA,CAAN,cAAkCF,CAAa,CACpD,WAAA,CAAYC,CAAAA,CAAkB,uBAAA,CAAyB,CACrD,KAAA,CAAMA,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,sBACd,CACF,EAEaE,CAAAA,CAAN,cAA6BH,CAAa,CAC/C,WAAA,CAAYC,CAAAA,CAAkB,kBAAA,CAAoB,CAChD,KAAA,CAAMA,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,iBACd,CACF,CAAA,CAEaG,CAAAA,CAAN,cAA4BJ,CAAa,CAC9C,WAAA,CAAYK,CAAAA,CAAkB,CAC5B,KAAA,CAAM,CAAA,EAAGA,CAAQ,CAAA,UAAA,CAAY,CAAA,CAC7B,IAAA,CAAK,IAAA,CAAO,gBACd,CACF,CAAA,CAEaC,CAAAA,CAAN,cAA8BN,CAAa,CAGhD,WAAA,CAAYC,CAAAA,CAAiBM,CAAAA,CAAe,CAC1C,KAAA,CAAMN,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,iBAAA,CACZ,IAAA,CAAK,OAAA,CAAUM,EACjB,CACF,CAAA,CAEaC,CAAAA,CAAN,cAA6BR,CAAa,CAQ/C,WAAA,CAAYS,CAAAA,CAOT,CACD,KAAA,CACE,CAAA,qBAAA,EAAwBA,EAAO,IAAI,CAAA,CAAA,EAAIA,CAAAA,CAAO,KAAK,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,MAAM,CAAA,mBAAA,EACtEA,CAAAA,CAAO,OAAA,CAAQ,WAAA,EAAa,CAAA,CAC3C,CAAA,CACA,IAAA,CAAK,IAAA,CAAO,gBAAA,CACZ,IAAA,CAAK,MAAA,CAASA,CAAAA,CAAO,MAAA,CACrB,IAAA,CAAK,KAAA,CAAQA,CAAAA,CAAO,KAAA,CACpB,IAAA,CAAK,IAAA,CAAOA,CAAAA,CAAO,IAAA,CACnB,IAAA,CAAK,UAAYA,CAAAA,CAAO,SAAA,CACxB,IAAA,CAAK,OAAA,CAAUA,CAAAA,CAAO,OAAA,CACtB,IAAA,CAAK,IAAA,CAAOA,CAAAA,CAAO,KACrB,CACF,CAAA,CAEaC,CAAAA,CAAN,cAA0BV,CAAa,CAG5C,WAAA,CAAYC,CAAAA,CAAiBU,CAAAA,CAAqB,GAAA,CAAK,CACrD,KAAA,CAAMV,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,aAAA,CACZ,IAAA,CAAK,UAAA,CAAaU,EACpB,CACF,CAAA,CAEaC,CAAAA,CAAN,cAA2BZ,CAAa,CAC7C,WAAA,CAAYC,CAAAA,CAAkB,wBAAA,CAA0B,CACtD,KAAA,CAAMA,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,eACd,CACF,EC/EA,IAAMY,CAAAA,CAAcf,CAAAA,CACdgB,CAAAA,CAAcf,CAAAA,CAEPgB,CAAAA,CAAN,KAAkB,CAMvB,WAAA,CAAYC,CAAAA,CAAY,CAJxB,IAAA,CAAQ,YAAA,CAAe,IAAI,GAAA,CAC3B,IAAA,CAAQ,UAAA,CAAa,IAAI,GAAA,CAIvB,IAAA,CAAK,IAAA,CAAOA,CAAAA,CAGZ,IAAA,CAAK,eAAA,CAAkB,WAAA,CAAY,IAAM,IAAA,CAAK,OAAA,EAAQ,CAAG,GAAA,CAAS,GAAI,EACxE,CAKA,UAAA,CAAWC,CAAAA,CAAgBC,CAAAA,CAAkBC,CAAAA,CAAkB,CAC7D,IAAMC,CAAAA,CAAO,IAAA,CAAK,kBAAA,CAAmBH,CAAAA,CAAQC,CAAAA,CAAUC,CAAI,CAAA,CACrDE,CAAAA,CAAe,IAAA,CAAK,eAAA,EAAgB,CACpCC,CAAAA,CAAa,IAAA,CAAK,aAAA,EAAc,CAEhCC,CAAAA,CAASV,CAAAA,CAAY,IAAA,CAAK,IAAI,CAAA,CAGpC,GAAIU,CAAAA,CAAO,eAAA,GAAoB,IAAA,CAAM,CACnC,IAAMC,CAAAA,CAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAIH,CAAY,CAAA,EAAK,CAAA,CACpD,GAAIG,CAAAA,CAAOJ,CAAAA,CAAOG,EAAO,eAAA,CACvB,MAAM,IAAIf,CAAAA,CAAe,CACvB,MAAA,CAAQ,QAAA,CACR,KAAA,CAAOe,CAAAA,CAAO,eAAA,CACd,IAAA,CAAAC,CAAAA,CACA,SAAA,CAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAGD,CAAAA,CAAO,eAAA,CAAkBC,CAAI,CAAA,CACpD,OAAA,CAAS,IAAA,CAAK,kBAAA,EAAmB,CACjC,IAAA,CAAM,IAAA,CAAK,IACb,CAAC,CAEL,CAGA,IAAMC,CAAAA,CAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAIH,CAAU,CAAA,EAAK,CAAA,CACpD,GAAIG,CAAAA,CAAWL,CAAAA,CAAOG,CAAAA,CAAO,aAAA,CAC3B,MAAM,IAAIf,CAAAA,CAAe,CACvB,MAAA,CAAQ,MAAA,CACR,KAAA,CAAOe,CAAAA,CAAO,aAAA,CACd,IAAA,CAAME,CAAAA,CACN,SAAA,CAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAGF,CAAAA,CAAO,aAAA,CAAgBE,CAAQ,EACtD,OAAA,CAAS,IAAA,CAAK,gBAAA,EAAiB,CAC/B,IAAA,CAAM,IAAA,CAAK,IACb,CAAC,CAAA,CAIH,IAAA,CAAK,cAAA,CAAeJ,CAAAA,CAAcD,CAAI,CAAA,CACtC,IAAA,CAAK,cAAA,CAAeE,CAAAA,CAAYF,CAAI,EACtC,CAKQ,kBAAA,CAAmBH,CAAAA,CAAgBC,CAAAA,CAAkBC,CAAAA,CAAoB,CAE/E,GAAID,CAAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAKA,EAAS,QAAA,CAAS,OAAO,CAAA,CAAG,CAC7D,GAAIC,CAAAA,EAAM,UAAA,CAAY,CACpB,IAAMO,CAAAA,CAAM,KAAA,CAAM,OAAA,CAAQP,CAAAA,CAAK,UAAU,CAAA,CAAIA,CAAAA,CAAK,UAAA,CAAW,MAAA,CAAS,CAAA,CACtE,OAAIO,CAAAA,EAAO,EAAA,CAAWZ,CAAAA,CAAY,UAAA,CAC9BY,CAAAA,EAAO,EAAA,CAAWZ,CAAAA,CAAY,WAAA,EACZA,EAAY,WAAA,CAEpC,CAEA,GAAIK,CAAAA,EAAM,IAAA,CAAM,CACd,IAAMQ,CAAAA,CAAO,KAAA,CAAM,OAAA,CAAQR,CAAAA,CAAK,IAAI,CAAA,CAAIA,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAS,CAAA,CAC3D,OAAIQ,CAAAA,EAAQ,EAAA,CAAW,CAAA,EACA,CAAA,CAEzB,CACF,CAGA,OAAIT,CAAAA,CAAS,QAAA,CAAS,gBAAgB,GAAKA,CAAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAKA,CAAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,CAC5FJ,CAAAA,CAAY,MAAA,CAIdA,CAAAA,CAAYG,CAAM,CAAA,EAAK,CAChC,CAKQ,eAAA,EAA0B,CAChC,IAAMW,CAAAA,CAAM,IAAI,IAAA,CAChB,OAAO,CAAA,OAAA,EAAUA,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,QAAA,GAAa,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,OAAA,EAAS,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,QAAA,EAAU,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CACrN,CAKQ,aAAA,EAAwB,CAC9B,IAAMA,CAAAA,CAAM,IAAI,IAAA,CAChB,OAAO,CAAA,KAAA,EAAQA,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,QAAA,EAAS,CAAI,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CAAA,EAAI,OAAOA,CAAAA,CAAI,OAAA,EAAS,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAOA,CAAAA,CAAI,QAAA,EAAU,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAC,CAAA,CACtK,CAKQ,cAAA,CAAeC,CAAAA,CAAgBT,CAAAA,CAAoB,CACzD,GAAIS,CAAAA,CAAO,UAAA,CAAW,QAAQ,CAAA,CAAG,CAC/B,IAAMC,CAAAA,CAAU,IAAA,CAAK,YAAA,CAAa,GAAA,CAAID,CAAM,CAAA,EAAK,CAAA,CACjD,IAAA,CAAK,YAAA,CAAa,GAAA,CAAIA,CAAAA,CAAQC,CAAAA,CAAUV,CAAI,EAC9C,CAAA,KAAO,CACL,IAAMU,CAAAA,CAAU,IAAA,CAAK,UAAA,CAAW,GAAA,CAAID,CAAM,CAAA,EAAK,CAAA,CAC/C,IAAA,CAAK,UAAA,CAAW,GAAA,CAAIA,CAAAA,CAAQC,CAAAA,CAAUV,CAAI,EAC5C,CACF,CAKQ,kBAAA,EAA2B,CACjC,IAAMQ,CAAAA,CAAM,IAAI,IAAA,CAChB,OAAO,IAAI,IAAA,CAAKA,CAAAA,CAAI,WAAA,EAAY,CAAGA,CAAAA,CAAI,QAAA,EAAS,CAAGA,CAAAA,CAAI,OAAA,EAAQ,CAAGA,CAAAA,CAAI,QAAA,EAAS,CAAGA,CAAAA,CAAI,UAAA,EAAW,CAAI,CAAA,CAAG,CAAA,CAAG,CAAC,CAC9G,CAKQ,gBAAA,EAAyB,CAC/B,IAAMA,CAAAA,CAAM,IAAI,IAAA,CAChB,OAAO,IAAI,IAAA,CAAKA,CAAAA,CAAI,WAAA,EAAY,CAAGA,CAAAA,CAAI,QAAA,EAAS,CAAGA,CAAAA,CAAI,OAAA,EAAQ,CAAGA,CAAAA,CAAI,QAAA,EAAS,CAAI,CAAA,CAAG,CAAA,CAAG,CAAA,CAAG,CAAC,CAC/F,CAKA,gBAAA,EAAkC,CAChC,IAAML,EAASV,CAAAA,CAAY,IAAA,CAAK,IAAI,CAAA,CAC9BQ,CAAAA,CAAe,IAAA,CAAK,eAAA,EAAgB,CACpCC,CAAAA,CAAa,IAAA,CAAK,aAAA,EAAc,CAEhCS,CAAAA,CAAa,IAAA,CAAK,YAAA,CAAa,GAAA,CAAIV,CAAY,CAAA,EAAK,CAAA,CACpDI,CAAAA,CAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAIH,CAAU,CAAA,EAAK,CAAA,CAEpD,OAAO,CACL,IAAA,CAAM,IAAA,CAAK,KACX,MAAA,CAAQ,CACN,KAAA,CAAOC,CAAAA,CAAO,eAAA,EAAmB,CAAA,CACjC,IAAA,CAAMQ,CAAAA,CACN,SAAA,CAAWR,CAAAA,CAAO,eAAA,CACd,IAAA,CAAK,GAAA,CAAI,CAAA,CAAGA,CAAAA,CAAO,eAAA,CAAkBQ,CAAU,CAAA,CAC/C,CAAA,CAAA,CAAA,CACJ,OAAA,CAAS,IAAA,CAAK,kBAAA,EAChB,CAAA,CACA,IAAA,CAAM,CACJ,KAAA,CAAOR,CAAAA,CAAO,aAAA,CACd,IAAA,CAAME,EACN,SAAA,CAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAGF,CAAAA,CAAO,aAAA,CAAgBE,CAAQ,CAAA,CACtD,OAAA,CAAS,IAAA,CAAK,gBAAA,EAChB,CACF,CACF,CAKQ,OAAA,EAAgB,CAEtB,IAAMO,CAAAA,CADM,IAAA,CAAK,GAAA,EAAI,CACK,IAAA,CAAc,GAAA,CAGxC,IAAA,GAAW,CAACC,CAAG,CAAA,GAAK,IAAA,CAAK,YAAA,CACnB,KAAK,oBAAA,CAAqBA,CAAG,CAAA,CAAID,CAAAA,EACnC,IAAA,CAAK,YAAA,CAAa,MAAA,CAAOC,CAAG,CAAA,CAKhC,IAAA,GAAW,CAACA,CAAG,CAAA,GAAK,IAAA,CAAK,UAAA,CACnB,IAAA,CAAK,oBAAA,CAAqBA,CAAG,CAAA,CAAID,CAAAA,EACnC,IAAA,CAAK,UAAA,CAAW,MAAA,CAAOC,CAAG,EAGhC,CAKQ,oBAAA,CAAqBC,CAAAA,CAA2B,CACtD,IAAMC,EAAQD,CAAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CACzCE,CAAAA,CAAO,QAAA,CAASD,CAAAA,CAAM,CAAC,CAAC,CAAA,CACxBE,CAAAA,CAAQ,QAAA,CAASF,CAAAA,CAAM,CAAC,CAAC,CAAA,CAAI,CAAA,CAC7BG,CAAAA,CAAM,QAAA,CAASH,CAAAA,CAAM,CAAC,CAAC,CAAA,CACvBI,CAAAA,CAAO,QAAA,CAASJ,EAAM,CAAC,CAAC,CAAA,CACxBK,CAAAA,CAASN,CAAAA,CAAU,UAAA,CAAW,QAAQ,CAAA,CAAI,QAAA,CAASC,CAAAA,CAAM,CAAC,CAAC,CAAA,CAAI,CAAA,CAErE,OAAO,IAAI,IAAA,CAAKC,CAAAA,CAAMC,CAAAA,CAAOC,CAAAA,CAAKC,CAAAA,CAAMC,CAAM,CAAA,CAAE,OAAA,EAClD,CAKA,OAAA,EAAgB,CACV,IAAA,CAAK,eAAA,EACP,cAAc,IAAA,CAAK,eAAiC,EAExD,CACF,CAAA,CC7MO,IAAMC,CAAAA,CAAN,KAAkB,CACvB,WAAA,CAAoBC,CAAAA,CAAuB,CAAvB,IAAA,CAAA,MAAA,CAAAA,EAAwB,CAK5C,MAAM,MAAA,CAAOC,CAAAA,CAAyC,CACpD,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAa,MAAA,CAAQ,OAAA,CAASA,CAAO,CAC1D,CAKA,MAAM,GAAA,CAAIC,EAA6B,CACrC,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAa,KAAA,CAAO,CAAA,MAAA,EAASA,CAAK,CAAA,CAAE,CACzD,CAKA,MAAM,IAAA,CAAKC,CAAAA,CAA4D,CACrE,IAAMpC,CAAAA,CAAS,IAAI,eAAA,CACfoC,CAAAA,EAAS,KAAA,EAAOpC,CAAAA,CAAO,MAAA,CAAO,OAAA,CAASoC,CAAAA,CAAQ,KAAA,CAAM,QAAA,EAAU,CAAA,CAC/DA,CAAAA,EAAS,QAAQpC,CAAAA,CAAO,MAAA,CAAO,QAAA,CAAUoC,CAAAA,CAAQ,MAAA,CAAO,QAAA,EAAU,CAAA,CAEtE,IAAMC,CAAAA,CAAQrC,CAAAA,CAAO,QAAA,EAAS,CACxBS,CAAAA,CAAW4B,CAAAA,CAAQ,CAAA,MAAA,EAASA,CAAK,CAAA,CAAA,CAAK,OAAA,CAE5C,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAgC,KAAA,CAAO5B,CAAQ,CACpE,CAKA,MAAM,MAAA,CAAO0B,CAAAA,CAAeD,EAAyC,CACnE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAa,KAAA,CAAO,CAAA,MAAA,EAASC,CAAK,CAAA,CAAA,CAAID,CAAO,CAClE,CAKA,MAAM,MAAA,CAAOC,CAAAA,CAA8B,CACzC,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAc,QAAA,CAAU,CAAA,MAAA,EAASA,CAAK,CAAA,CAAE,CAC7D,CAKA,MAAM,KAAA,CAAMA,CAAAA,CAAeD,CAAAA,CAAwC,CACjE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAa,MAAA,CAAQ,CAAA,MAAA,EAASC,CAAK,CAAA,MAAA,CAAA,CAAUD,CAAO,CACzE,CASA,MAAM,cAAA,CAAeI,CAAAA,CAAeC,CAAAA,CAA0E,CAC5G,OAAO,IAAA,CAAK,MAAA,CAAO,CACjB,SAAA,CAAW,UAAA,CACX,QAAA,CAAU,CACR,KAAA,CAAAD,CAAAA,CACA,GAAGC,CACL,CACF,CAAC,CACH,CAKA,MAAM,cAAA,CAAeC,CAAAA,CAKlBF,CAAAA,CAAeC,CAAAA,CAA0E,CAC1F,OAAO,IAAA,CAAK,MAAA,CAAO,CACjB,SAAA,CAAW,UAAA,CACX,QAAA,CAAU,CACR,KAAA,CAAAD,CAAAA,CACA,aAAA,CAAe,YAAA,CACf,eAAA,CAAiB,CAACE,CAAI,CAAA,CACtB,GAAGD,CACL,CACF,CAAC,CACH,CAKA,MAAM,YAAYC,CAAAA,CAGfF,CAAAA,CAAeC,CAAAA,CAA0E,CAC1F,OAAO,IAAA,CAAK,MAAA,CAAO,CACjB,SAAA,CAAW,UAAA,CACX,QAAA,CAAU,CACR,KAAA,CAAAD,CAAAA,CACA,aAAA,CAAe,gBAAA,CACf,eAAA,CAAiBE,CAAAA,CACjB,GAAGD,CACL,CACF,CAAC,CACH,CAKA,MAAM,WAAA,CAAYE,CAAAA,CAAaH,CAAAA,CAAeC,CAAAA,CAA0E,CACtH,OAAO,IAAA,CAAK,MAAA,CAAO,CACjB,SAAA,CAAW,UAAA,CACX,QAAA,CAAU,CACR,KAAA,CAAAD,CAAAA,CACA,aAAA,CAAe,OAAA,CACf,eAAA,CAAiB,CAAE,GAAA,CAAAG,CAAI,CAAA,CACvB,GAAGF,CACL,CACF,CAAC,CACH,CACF,CAAA,CC1HO,IAAMG,CAAAA,CAAN,KAAuB,CAC5B,WAAA,CAAoBT,CAAAA,CAAuB,CAAvB,YAAAA,EAAwB,CAK5C,MAAM,MAAA,CAAOC,CAAAA,CAAmD,CAC9D,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,MAAA,CAAQ,YAAA,CAAcA,CAAO,CACpE,CAKA,MAAM,GAAA,CAAIS,CAAAA,CAAoC,CAC5C,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,KAAA,CAAO,CAAA,WAAA,EAAcA,CAAO,CAAA,CAAE,CACrE,CAKA,MAAM,MAA4B,CAChC,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAoB,KAAA,CAAO,YAAY,CAC5D,CAKA,MAAM,MAAA,CAAOA,CAAAA,CAAiBT,CAAAA,CAAmD,CAC/E,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,KAAA,CAAO,CAAA,WAAA,EAAcS,CAAO,CAAA,CAAA,CAAIT,CAAO,CAC9E,CAKA,MAAM,MAAA,CAAOS,CAAAA,CAAgC,CAC3C,OAAO,KAAK,MAAA,CAAO,OAAA,CAAc,QAAA,CAAU,CAAA,WAAA,EAAcA,CAAO,CAAA,CAAE,CACpE,CAKA,MAAM,MAAA,CAAOA,CAAAA,CAAiBT,CAAAA,CAAqD,CACjF,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,MAAA,CAAQ,CAAA,WAAA,EAAcS,CAAO,CAAA,KAAA,CAAA,CAAST,CAAO,CACpF,CAKA,MAAM,SAAA,CAAUS,CAAAA,CAAiBR,CAAAA,CAA8B,CAC7D,OAAO,KAAK,MAAA,CAAO,OAAA,CAAc,QAAA,CAAU,CAAA,WAAA,EAAcQ,CAAO,CAAA,MAAA,EAASR,CAAK,CAAA,CAAE,CAClF,CAKA,MAAM,YAAA,CAAaQ,CAAAA,CAAiBT,CAAAA,CAAyD,CAC3F,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,KAAA,CAAO,CAAA,WAAA,EAAcS,CAAO,CAAA,OAAA,CAAA,CAAWT,CAAO,CACrF,CAKA,MAAM,KAAA,CAAMS,CAAAA,CAAiBT,CAAAA,CAIP,CACpB,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAkB,MAAA,CAAQ,CAAA,WAAA,EAAcS,CAAO,CAAA,MAAA,CAAA,CAAUT,CAAO,CACrF,CACF,CAAA,CCvEO,IAAMU,CAAAA,CAAN,KAAsB,CAC3B,WAAA,CAAoBX,CAAAA,CAAuB,CAAvB,IAAA,CAAA,MAAA,CAAAA,EAAwB,CAK5C,MAAM,MAAA,CAAOC,CAAAA,CAAiD,CAC5D,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAiB,OAAQ,WAAA,CAAaA,CAAO,CAClE,CAKA,MAAM,GAAA,CAAIW,CAAAA,CAAqC,CAC7C,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAiB,KAAA,CAAO,CAAA,UAAA,EAAaA,CAAS,CAAA,CAAE,CACrE,CAKA,MAAM,IAAA,EAA2B,CAC/B,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAmB,KAAA,CAAO,WAAW,CAC1D,CAKA,MAAM,OAAOA,CAAAA,CAAmBX,CAAAA,CAAiD,CAC/E,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAiB,KAAA,CAAO,CAAA,UAAA,EAAaW,CAAS,CAAA,CAAA,CAAIX,CAAO,CAC9E,CAKA,MAAM,MAAA,CAAOW,CAAAA,CAAkC,CAC7C,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAc,QAAA,CAAU,CAAA,UAAA,EAAaA,CAAS,CAAA,CAAE,CACrE,CACF,CAAA,CCrCO,IAAMC,EAAN,KAAoB,CACzB,WAAA,CAAoBb,CAAAA,CAAuB,CAAvB,IAAA,CAAA,MAAA,CAAAA,EAAwB,CAK5C,MAAM,MAAA,CAAOE,CAAAA,CAAeD,CAAAA,CAA6C,CACvE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAe,MAAA,CAAQ,CAAA,MAAA,EAASC,CAAK,CAAA,OAAA,CAAA,CAAWD,CAAO,CAC5E,CAKA,MAAM,GAAA,CAAIC,CAAAA,CAAeY,CAAAA,CAAiC,CACxD,OAAO,KAAK,MAAA,CAAO,OAAA,CAAe,KAAA,CAAO,CAAA,MAAA,EAASZ,CAAK,CAAA,QAAA,EAAWY,CAAO,CAAA,CAAE,CAC7E,CAKA,MAAM,IAAA,CAAKZ,CAAAA,CAAiC,CAC1C,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAiB,KAAA,CAAO,CAAA,MAAA,EAASA,CAAK,CAAA,OAAA,CAAS,CACpE,CAKA,MAAM,MAAA,CAAOA,CAAAA,CAAeY,CAAAA,CAAiBb,CAAAA,CAA6C,CACxF,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAe,KAAA,CAAO,CAAA,MAAA,EAASC,CAAK,CAAA,QAAA,EAAWY,CAAO,CAAA,CAAA,CAAIb,CAAO,CACtF,CAKA,MAAM,MAAA,CAAOC,CAAAA,CAAeY,CAAAA,CAAgC,CAC1D,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAc,QAAA,CAAU,CAAA,MAAA,EAASZ,CAAK,CAAA,QAAA,EAAWY,CAAO,CAAA,CAAE,CAC/E,CACF,CAAA,CCpCO,IAAMC,CAAAA,CAAN,KAA2B,CAChC,WAAA,CAAoBf,CAAAA,CAAuB,CAAvB,IAAA,CAAA,MAAA,CAAAA,EAAwB,CAS5C,MAAM,UAAA,CAAWE,CAAAA,CAId,CACD,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,MAAA,EAASA,CAAK,CAAA,cAAA,CAAgB,CAClE,CAKA,MAAM,WAAA,CAAYA,CAAAA,CAAeD,CAAAA,CAAmD,CAClF,OAAO,IAAA,CAAK,OAAO,OAAA,CAAQ,MAAA,CAAQ,CAAA,MAAA,EAASC,CAAK,CAAA,cAAA,CAAA,CAAkBD,CAAO,CAC5E,CAKA,MAAM,aAAA,CAAcC,CAAAA,CAAec,CAAAA,CAAgBf,CAAAA,CAAuD,CACxG,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,MAAA,EAASC,CAAK,CAAA,eAAA,EAAkBc,CAAM,CAAA,CAAA,CAAIf,CAAO,CACrF,CAKA,MAAM,aAAA,CAAcC,CAAAA,CAAec,EAA+B,CAChE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAU,CAAA,MAAA,EAASd,CAAK,CAAA,eAAA,EAAkBc,CAAM,CAAA,CAAE,CAC/E,CAKA,MAAM,iBAAA,CAAkBd,CAAAA,CAAqC,CAC3D,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,MAAA,EAASA,CAAK,CAAA,YAAA,CAAc,CAChE,CASA,MAAM,eAAA,CAAgBQ,CAAAA,CAInB,CACD,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,WAAA,EAAcA,CAAO,CAAA,cAAA,CAAgB,CACzE,CAKA,MAAM,gBAAA,CAAiBA,CAAAA,CAAiBT,CAAAA,CAAmD,CACzF,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAQ,CAAA,WAAA,EAAcS,CAAO,CAAA,cAAA,CAAA,CAAkBT,CAAO,CACnF,CAKA,MAAM,kBAAA,CAAmBS,CAAAA,CAAiBM,CAAAA,CAAgBf,EAAuD,CAC/G,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,WAAA,EAAcS,CAAO,CAAA,eAAA,EAAkBM,CAAM,CAAA,CAAA,CAAIf,CAAO,CAC5F,CAKA,MAAM,kBAAA,CAAmBS,CAAAA,CAAiBM,CAAAA,CAA+B,CACvE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAU,CAAA,WAAA,EAAcN,CAAO,CAAA,eAAA,EAAkBM,CAAM,CAAA,CAAE,CACtF,CAKA,MAAM,sBAAA,CAAuBN,CAAAA,CAAuC,CAClE,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAO,CAAA,WAAA,EAAcA,CAAO,CAAA,YAAA,CAAc,CACvE,CACF,CAAA,CC/EO,IAAMO,CAAAA,CAAN,KAAoB,CAWzB,WAAA,CAAYC,CAAAA,CAAuB,CARnC,IAAA,CAAQ,YAAA,CAAwB,KAAA,CAU9B,GAAI,CAACA,CAAAA,CAAO,MAAA,CACV,MAAM,IAAI,KAAA,CAAM,qBAAqB,CAAA,CAIvC,IAAA,CAAK,MAAA,CAAS,CACZ,MAAA,CAAQA,CAAAA,CAAO,MAAA,CACf,IAAA,CAAMA,CAAAA,CAAO,IAAA,CACb,OAAA,CAASA,CAAAA,CAAO,OAAA,EAAW,2BAAA,CAC3B,uBAAA,CAAyBA,CAAAA,CAAO,uBAAA,EAA2B,IAAA,CAC3D,UAAA,CAAYA,CAAAA,CAAO,UAAA,EAAc,CAAA,CACjC,OAAA,CAASA,CAAAA,CAAO,OAAA,EAAW,GAC7B,CAAA,CAGI,IAAA,CAAK,OAAO,IAAA,GACd,IAAA,CAAK,WAAA,CAAc,IAAI7C,CAAAA,CAAY,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,CACnD,IAAA,CAAK,YAAA,CAAe,IAAA,CAAA,CAItB,IAAA,CAAK,IAAA,CAAO,IAAI0B,CAAAA,CAAY,IAAI,CAAA,CAChC,IAAA,CAAK,SAAA,CAAY,IAAIU,CAAAA,CAAiB,IAAI,CAAA,CAC1C,IAAA,CAAK,QAAA,CAAW,IAAIE,CAAAA,CAAgB,IAAI,CAAA,CACxC,KAAK,MAAA,CAAS,IAAIE,CAAAA,CAAc,IAAI,CAAA,CACpC,IAAA,CAAK,aAAA,CAAgB,IAAIE,CAAAA,CAAqB,IAAI,EACpD,CAKA,MAAM,OAAA,CACJxC,CAAAA,CACAC,CAAAA,CACA+B,CAAAA,CACY,CAER,IAAA,CAAK,MAAA,CAAO,uBAAA,EAA2B,IAAA,CAAK,WAAA,EAC9C,IAAA,CAAK,WAAA,CAAY,UAAA,CAAWhC,CAAAA,CAAQC,CAAAA,CAAU+B,CAAI,CAAA,CAGpD,IAAMC,CAAAA,CAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAGhC,CAAQ,CAAA,CAAA,CACvC2C,CAAAA,CAAkC,CACtC,aAAA,CAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA,CAC7C,cAAA,CAAgB,kBAClB,CAAA,CAEMC,CAAAA,CAA8B,CAClC,MAAA,CAAA7C,CAAAA,CACA,OAAA,CAAA4C,CAAAA,CACA,MAAA,CAAQ,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,OAAO,CACjD,CAAA,CAEIZ,CAAAA,GAAShC,CAAAA,GAAW,MAAA,EAAUA,CAAAA,GAAW,KAAA,CAAA,GAC3C6C,CAAAA,CAAe,IAAA,CAAO,IAAA,CAAK,SAAA,CAAUb,CAAI,CAAA,CAAA,CAG3C,GAAI,CACF,IAAMc,CAAAA,CAAW,MAAM,KAAA,CAAMb,CAAAA,CAAKY,CAAc,CAAA,CAGhD,OAAI,CAAC,IAAA,CAAK,YAAA,EAAgB,IAAA,CAAK,MAAA,CAAO,uBAAA,EACpC,IAAA,CAAK,sBAAsBC,CAAAA,CAAS,OAAO,CAAA,CAIxCA,CAAAA,CAAS,EAAA,EACZ,MAAM,IAAA,CAAK,mBAAA,CAAoBA,CAAQ,CAAA,CAAA,CAI1B,MAAMA,CAAAA,CAAS,IAAA,EAAK,EACrB,IAChB,CAAA,MAASC,CAAAA,CAAY,CAEnB,MACEA,CAAAA,YAAiB9D,CAAAA,EACjB8D,CAAAA,YAAiB7D,CAAAA,EACjB6D,CAAAA,YAAiB5D,CAAAA,EACjB4D,CAAAA,YAAiB1D,CAAAA,EACjB0D,CAAAA,YAAiBtD,CAAAA,CAEXsD,CAAAA,CAIJA,EAAM,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAM,IAAA,GAAS,cAAA,CAC1C,IAAIpD,CAAAA,CAAa,iBAAiB,CAAA,CAGpC,IAAIA,CAAAA,CAAaoD,CAAAA,CAAM,OAAA,EAAW,wBAAwB,CAClE,CACF,CAKA,MAAc,mBAAA,CAAoBD,CAAAA,CAAoC,CACpE,IAAIE,CAAAA,CAEJ,GAAI,CACFA,CAAAA,CAAY,MAAMF,CAAAA,CAAS,IAAA,GAC7B,MAAQ,CACNE,CAAAA,CAAY,CAAE,OAAA,CAASF,CAAAA,CAAS,UAAW,EAC7C,CAEA,IAAM9D,CAAAA,CAAUgE,CAAAA,CAAU,KAAA,EAAO,OAAA,EAAWA,CAAAA,CAAU,OAAA,EAAW,eAAA,CAEjE,OAAQF,CAAAA,CAAS,MAAA,EACf,KAAK,GAAA,CACH,MAAM,IAAI7D,CAAAA,CAAoBD,CAAO,CAAA,CACvC,KAAK,GAAA,CACH,MAAM,IAAIE,CAAAA,CAAeF,CAAO,CAAA,CAClC,KAAK,GAAA,CACH,MAAM,IAAIG,CAAAA,CAAcH,CAAO,CAAA,CACjC,KAAK,GAAA,CACL,KAAK,GAAA,CACH,MAAM,IAAIK,CAAAA,CAAgBL,CAAAA,CAASgE,CAAAA,CAAU,KAAA,EAAO,OAAO,CAAA,CAC7D,KAAK,GAAA,CAEH,MAAM,IAAI3D,CAAAA,CAAgB,8BAAA,CAAgC2D,CAAS,CAAA,CACrE,KAAK,GAAA,CACL,KAAK,GAAA,CACL,KAAK,GAAA,CACH,MAAM,IAAIvD,CAAAA,CAAYT,CAAAA,CAAS8D,CAAAA,CAAS,MAAM,CAAA,CAChD,QACE,MAAM,IAAIrD,CAAAA,CAAYT,CAAAA,CAAS8D,CAAAA,CAAS,MAAM,CAClD,CACF,CAKQ,qBAAA,CAAsBF,CAAAA,CAAwB,CACpD,IAAMK,CAAAA,CAAaL,CAAAA,CAAQ,GAAA,CAAI,kBAAkB,EACjD,GAAIK,CAAAA,EAAc,CAAC,IAAA,CAAK,WAAA,CAAa,CACnC,IAAMlD,CAAAA,CAAOkD,CAAAA,CAAW,WAAA,EAAY,CACpC,OAAA,CAAQ,GAAA,CAAI,CAAA,qCAAA,EAAwClD,CAAI,CAAA,CAAE,CAAA,CAC1D,IAAA,CAAK,MAAA,CAAO,IAAA,CAAOA,CAAAA,CACnB,IAAA,CAAK,WAAA,CAAc,IAAID,CAAAA,CAAYC,CAAI,CAAA,CACvC,IAAA,CAAK,YAAA,CAAe,KACtB,CACF,CAKA,gBAAA,EAAyC,CACvC,OAAK,IAAA,CAAK,WAAA,CAGH,IAAA,CAAK,WAAA,CAAY,gBAAA,EAAiB,CAFhC,IAGX,CAKA,OAAA,EAAuB,CACrB,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,EAAQ,IAC7B,CAKA,OAAA,EAAgB,CACV,IAAA,CAAK,WAAA,EACP,IAAA,CAAK,WAAA,CAAY,OAAA,GAErB,CACF","file":"index.cjs","sourcesContent":["{\r\n \"starter\": {\r\n \"tokensPerHour\": 16,\r\n \"tokensPerMinute\": null\r\n },\r\n \"hobby\": {\r\n \"tokensPerHour\": 6000,\r\n \"tokensPerMinute\": 100\r\n },\r\n \"pro\": {\r\n \"tokensPerHour\": 24000,\r\n \"tokensPerMinute\": 400\r\n },\r\n \"teams\": {\r\n \"tokensPerHour\": 60000,\r\n \"tokensPerMinute\": 1000\r\n },\r\n \"agency\": {\r\n \"tokensPerHour\": 240000,\r\n \"tokensPerMinute\": 4000\r\n }\r\n}\r\n\r\n","{\r\n \"GET\": 1,\r\n \"POST\": 1,\r\n \"PUT\": 1,\r\n \"DELETE\": 1,\r\n \"INVITE\": 3,\r\n \"SHARE\": 3,\r\n \"BATCH_1_10\": 3,\r\n \"BATCH_11_25\": 5,\r\n \"BATCH_26_50\": 10\r\n}\r\n","/**\r\n * Error classes for Pindown API Client\r\n */\r\n\r\nimport type { Tier } from '../types/config'\r\n\r\nexport class PindownError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'PindownError'\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PindownError {\r\n constructor(message: string = 'Authentication failed') {\r\n super(message)\r\n this.name = 'AuthenticationError'\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends PindownError {\r\n constructor(message: string = 'Access forbidden') {\r\n super(message)\r\n this.name = 'ForbiddenError'\r\n }\r\n}\r\n\r\nexport class NotFoundError extends PindownError {\r\n constructor(resource: string) {\r\n super(`${resource} not found`)\r\n this.name = 'NotFoundError'\r\n }\r\n}\r\n\r\nexport class ValidationError extends PindownError {\r\n public details?: any\r\n\r\n constructor(message: string, details?: any) {\r\n super(message)\r\n this.name = 'ValidationError'\r\n this.details = details\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PindownError {\r\n public window: 'minute' | 'hour'\r\n public limit: number\r\n public used: number\r\n public remaining: number\r\n public resetAt: Date\r\n public tier: Tier\r\n\r\n constructor(params: {\r\n window: 'minute' | 'hour'\r\n limit: number\r\n used: number\r\n remaining: number\r\n resetAt: Date\r\n tier: Tier\r\n }) {\r\n super(\r\n `Rate limit exceeded: ${params.used}/${params.limit} tokens used in ${params.window} window. ` +\r\n `Resets at ${params.resetAt.toISOString()}`\r\n )\r\n this.name = 'RateLimitError'\r\n this.window = params.window\r\n this.limit = params.limit\r\n this.used = params.used\r\n this.remaining = params.remaining\r\n this.resetAt = params.resetAt\r\n this.tier = params.tier\r\n }\r\n}\r\n\r\nexport class ServerError extends PindownError {\r\n public statusCode: number\r\n\r\n constructor(message: string, statusCode: number = 500) {\r\n super(message)\r\n this.name = 'ServerError'\r\n this.statusCode = statusCode\r\n }\r\n}\r\n\r\nexport class NetworkError extends PindownError {\r\n constructor(message: string = 'Network request failed') {\r\n super(message)\r\n this.name = 'NetworkError'\r\n }\r\n}\r\n\r\n","/**\r\n * Rate Limiter - Client-side rate limiting with in-memory counters\r\n */\r\n\r\nimport tierLimitsJson from '../config/tier-limits.json'\r\nimport tokenCostsJson from '../config/token-costs.json'\r\nimport { RateLimitError } from '../errors'\r\nimport type { Tier } from '../types/config'\r\nimport type { RateLimitInfo } from '../types/api'\r\n\r\nconst TIER_LIMITS = tierLimitsJson as Record<Tier, { tokensPerHour: number; tokensPerMinute: number | null }>\r\nconst TOKEN_COSTS = tokenCostsJson as Record<string, number>\r\n\r\nexport class RateLimiter {\r\n private tier: Tier\r\n private minuteTokens = new Map<string, number>()\r\n private hourTokens = new Map<string, number>()\r\n private cleanupInterval: NodeJS.Timeout | number\r\n\r\n constructor(tier: Tier) {\r\n this.tier = tier\r\n \r\n // Auto-cleanup expired windows every 5 minutes\r\n this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000)\r\n }\r\n\r\n /**\r\n * Check if request is allowed, throw RateLimitError if limit reached\r\n */\r\n checkLimit(method: string, endpoint: string, body?: any): void {\r\n const cost = this.calculateTokenCost(method, endpoint, body)\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const limits = TIER_LIMITS[this.tier]\r\n \r\n // Check minute limit (if exists)\r\n if (limits.tokensPerMinute !== null) {\r\n const used = this.minuteTokens.get(minuteWindow) || 0\r\n if (used + cost > limits.tokensPerMinute) {\r\n throw new RateLimitError({\r\n window: 'minute',\r\n limit: limits.tokensPerMinute,\r\n used,\r\n remaining: Math.max(0, limits.tokensPerMinute - used),\r\n resetAt: this.getMinuteResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n }\r\n \r\n // Check hour limit\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n if (hourUsed + cost > limits.tokensPerHour) {\r\n throw new RateLimitError({\r\n window: 'hour',\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime(),\r\n tier: this.tier\r\n })\r\n }\r\n \r\n // Increment counters\r\n this.incrementToken(minuteWindow, cost)\r\n this.incrementToken(hourWindow, cost)\r\n }\r\n\r\n /**\r\n * Calculate token cost for a request\r\n */\r\n private calculateTokenCost(method: string, endpoint: string, body?: any): number {\r\n // Check for batch endpoints\r\n if (endpoint.includes('/batch') || endpoint.includes('/sync')) {\r\n if (body?.operations) {\r\n const ops = Array.isArray(body.operations) ? body.operations.length : 0\r\n if (ops <= 10) return TOKEN_COSTS.BATCH_1_10\r\n if (ops <= 25) return TOKEN_COSTS.BATCH_11_25\r\n if (ops <= 50) return TOKEN_COSTS.BATCH_26_50\r\n return TOKEN_COSTS.BATCH_26_50 // Cap at 50\r\n }\r\n // For /sync endpoints, check pins array\r\n if (body?.pins) {\r\n const pins = Array.isArray(body.pins) ? body.pins.length : 0\r\n if (pins <= 16) return 5 // As per RATE_LIMITING_STRATEGY.md\r\n if (pins <= 32) return 8\r\n return 8 // Cap at 32\r\n }\r\n }\r\n \r\n // Check for invite/share endpoints\r\n if (endpoint.includes('/collaborators') || endpoint.includes('/invite') || endpoint.includes('/share')) {\r\n return TOKEN_COSTS.INVITE\r\n }\r\n \r\n // Standard methods (all cost 1 token)\r\n return TOKEN_COSTS[method] || 1\r\n }\r\n\r\n /**\r\n * Get current minute window key\r\n */\r\n private getMinuteWindow(): string {\r\n const now = new Date()\r\n return `minute_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}-${String(now.getMinutes()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Get current hour window key\r\n */\r\n private getHourWindow(): string {\r\n const now = new Date()\r\n return `hour_${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}`\r\n }\r\n\r\n /**\r\n * Increment token count for a window\r\n */\r\n private incrementToken(window: string, cost: number): void {\r\n if (window.startsWith('minute')) {\r\n const current = this.minuteTokens.get(window) || 0\r\n this.minuteTokens.set(window, current + cost)\r\n } else {\r\n const current = this.hourTokens.get(window) || 0\r\n this.hourTokens.set(window, current + cost)\r\n }\r\n }\r\n\r\n /**\r\n * Get reset time for current minute window\r\n */\r\n private getMinuteResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes() + 1, 0, 0)\r\n }\r\n\r\n /**\r\n * Get reset time for current hour window\r\n */\r\n private getHourResetTime(): Date {\r\n const now = new Date()\r\n return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0)\r\n }\r\n\r\n /**\r\n * Get current rate limit info\r\n */\r\n getRateLimitInfo(): RateLimitInfo {\r\n const limits = TIER_LIMITS[this.tier]\r\n const minuteWindow = this.getMinuteWindow()\r\n const hourWindow = this.getHourWindow()\r\n \r\n const minuteUsed = this.minuteTokens.get(minuteWindow) || 0\r\n const hourUsed = this.hourTokens.get(hourWindow) || 0\r\n \r\n return {\r\n tier: this.tier,\r\n minute: {\r\n limit: limits.tokensPerMinute || 0,\r\n used: minuteUsed,\r\n remaining: limits.tokensPerMinute \r\n ? Math.max(0, limits.tokensPerMinute - minuteUsed)\r\n : Infinity,\r\n resetAt: this.getMinuteResetTime()\r\n },\r\n hour: {\r\n limit: limits.tokensPerHour,\r\n used: hourUsed,\r\n remaining: Math.max(0, limits.tokensPerHour - hourUsed),\r\n resetAt: this.getHourResetTime()\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup expired windows (older than 2 hours)\r\n */\r\n private cleanup(): void {\r\n const now = Date.now()\r\n const twoHoursAgo = now - 2 * 60 * 60 * 1000\r\n \r\n // Parse and remove old minute windows\r\n for (const [key] of this.minuteTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.minuteTokens.delete(key)\r\n }\r\n }\r\n \r\n // Parse and remove old hour windows\r\n for (const [key] of this.hourTokens) {\r\n if (this.parseWindowTimestamp(key) < twoHoursAgo) {\r\n this.hourTokens.delete(key)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Parse timestamp from window key\r\n */\r\n private parseWindowTimestamp(windowKey: string): number {\r\n const parts = windowKey.split('_')[1].split('-')\r\n const year = parseInt(parts[0])\r\n const month = parseInt(parts[1]) - 1\r\n const day = parseInt(parts[2])\r\n const hour = parseInt(parts[3])\r\n const minute = windowKey.startsWith('minute') ? parseInt(parts[4]) : 0\r\n \r\n return new Date(year, month, day, hour, minute).getTime()\r\n }\r\n\r\n /**\r\n * Destroy the rate limiter (cleanup interval)\r\n */\r\n destroy(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval as NodeJS.Timeout)\r\n }\r\n }\r\n}\r\n\r\n","/**\r\n * Pins API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Pin,\r\n CreatePinRequest,\r\n UpdatePinRequest,\r\n SharePinRequest,\r\n ListPinsOptions,\r\n PaginatedResponse\r\n} from '../../types/api'\r\n\r\nexport class PinsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new pin\r\n */\r\n async create(request: CreatePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('POST', '/pins', request)\r\n }\r\n\r\n /**\r\n * Get a pin by ID\r\n */\r\n async get(pinId: string): Promise<Pin> {\r\n return this.client.request<Pin>('GET', `/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * List all pins\r\n */\r\n async list(options?: ListPinsOptions): Promise<PaginatedResponse<Pin>> {\r\n const params = new URLSearchParams()\r\n if (options?.limit) params.append('limit', options.limit.toString())\r\n if (options?.offset) params.append('offset', options.offset.toString())\r\n\r\n const query = params.toString()\r\n const endpoint = query ? `/pins?${query}` : '/pins'\r\n\r\n return this.client.request<PaginatedResponse<Pin>>('GET', endpoint)\r\n }\r\n\r\n /**\r\n * Update a pin\r\n */\r\n async update(pinId: string, request: UpdatePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('PUT', `/pins/${pinId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a pin\r\n */\r\n async delete(pinId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * Update pin sharing settings\r\n */\r\n async share(pinId: string, request: SharePinRequest): Promise<Pin> {\r\n return this.client.request<Pin>('POST', `/pins/${pinId}/share`, request)\r\n }\r\n\r\n // ============================================\r\n // Helper methods for common pin types\r\n // ============================================\r\n\r\n /**\r\n * Create a markdown pin (content comes from blocks)\r\n */\r\n async createMarkdown(title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin> {\r\n return this.create({\r\n data_type: 'markdown',\r\n metadata: {\r\n title,\r\n ...additionalMetadata\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Create a stat card pin\r\n */\r\n async createStatCard(data: {\r\n title: string\r\n value: string | number\r\n change?: string\r\n icon?: string\r\n }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n metadata: {\r\n title,\r\n pin_card_type: 'stat-cards',\r\n pin_card_config: [data],\r\n ...additionalMetadata\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Create a flexible table pin\r\n */\r\n async createTable(data: {\r\n columns: Array<{ id: string; label: string; type?: string }>\r\n rows: Array<Record<string, any>>\r\n }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n metadata: {\r\n title,\r\n pin_card_type: 'flexible-table',\r\n pin_card_config: data,\r\n ...additionalMetadata\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Create an embed pin (YouTube, Figma, etc.)\r\n */\r\n async createEmbed(url: string, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin> {\r\n return this.create({\r\n data_type: 'pin-card',\r\n metadata: {\r\n title,\r\n pin_card_type: 'embed',\r\n pin_card_config: { url },\r\n ...additionalMetadata\r\n }\r\n })\r\n }\r\n}\r\n\r\n","/**\r\n * Pinboards API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Pinboard,\r\n CreatePinboardRequest,\r\n UpdatePinboardRequest,\r\n AddPinToPinboardRequest,\r\n UpdatePinboardLayoutRequest\r\n} from '../../types/api'\r\n\r\nexport class PinboardsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new pinboard\r\n */\r\n async create(request: CreatePinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', '/pinboards', request)\r\n }\r\n\r\n /**\r\n * Get a pinboard by ID\r\n */\r\n async get(boardId: string): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('GET', `/pinboards/${boardId}`)\r\n }\r\n\r\n /**\r\n * List all pinboards\r\n */\r\n async list(): Promise<Pinboard[]> {\r\n return this.client.request<Pinboard[]>('GET', '/pinboards')\r\n }\r\n\r\n /**\r\n * Update a pinboard\r\n */\r\n async update(boardId: string, request: UpdatePinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a pinboard\r\n */\r\n async delete(boardId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pinboards/${boardId}`)\r\n }\r\n\r\n /**\r\n * Add a pin to a pinboard\r\n */\r\n async addPin(boardId: string, request: AddPinToPinboardRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/pins`, request)\r\n }\r\n\r\n /**\r\n * Remove a pin from a pinboard\r\n */\r\n async removePin(boardId: string, pinId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pinboards/${boardId}/pins/${pinId}`)\r\n }\r\n\r\n /**\r\n * Update pinboard layout\r\n */\r\n async updateLayout(boardId: string, request: UpdatePinboardLayoutRequest): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('PUT', `/pinboards/${boardId}/layout`, request)\r\n }\r\n\r\n /**\r\n * Update pinboard sharing settings\r\n */\r\n async share(boardId: string, request: {\r\n is_public?: boolean\r\n require_sign_in?: boolean\r\n allow_comments?: boolean\r\n }): Promise<Pinboard> {\r\n return this.client.request<Pinboard>('POST', `/pinboards/${boardId}/share`, request)\r\n }\r\n}\r\n\r\n","/**\r\n * Datasets API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Dataset,\r\n CreateDatasetRequest,\r\n UpdateDatasetRequest\r\n} from '../../types/api'\r\n\r\nexport class DatasetsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new dataset\r\n */\r\n async create(request: CreateDatasetRequest): Promise<Dataset> {\r\n return this.client.request<Dataset>('POST', '/datasets', request)\r\n }\r\n\r\n /**\r\n * Get a dataset by ID\r\n */\r\n async get(datasetId: string): Promise<Dataset> {\r\n return this.client.request<Dataset>('GET', `/datasets/${datasetId}`)\r\n }\r\n\r\n /**\r\n * List all datasets\r\n */\r\n async list(): Promise<Dataset[]> {\r\n return this.client.request<Dataset[]>('GET', '/datasets')\r\n }\r\n\r\n /**\r\n * Update a dataset\r\n */\r\n async update(datasetId: string, request: UpdateDatasetRequest): Promise<Dataset> {\r\n return this.client.request<Dataset>('PUT', `/datasets/${datasetId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a dataset\r\n */\r\n async delete(datasetId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/datasets/${datasetId}`)\r\n }\r\n}\r\n\r\n","/**\r\n * Blocks API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Block,\r\n CreateBlockRequest,\r\n UpdateBlockRequest\r\n} from '../../types/api'\r\n\r\nexport class BlocksMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n /**\r\n * Create a new block for a pin\r\n */\r\n async create(pinId: string, request: CreateBlockRequest): Promise<Block> {\r\n return this.client.request<Block>('POST', `/pins/${pinId}/blocks`, request)\r\n }\r\n\r\n /**\r\n * Get a block by ID\r\n */\r\n async get(pinId: string, blockId: string): Promise<Block> {\r\n return this.client.request<Block>('GET', `/pins/${pinId}/blocks/${blockId}`)\r\n }\r\n\r\n /**\r\n * List all blocks in a pin\r\n */\r\n async list(pinId: string): Promise<Block[]> {\r\n return this.client.request<Block[]>('GET', `/pins/${pinId}/blocks`)\r\n }\r\n\r\n /**\r\n * Update a block\r\n */\r\n async update(pinId: string, blockId: string, request: UpdateBlockRequest): Promise<Block> {\r\n return this.client.request<Block>('PUT', `/pins/${pinId}/blocks/${blockId}`, request)\r\n }\r\n\r\n /**\r\n * Delete a block\r\n */\r\n async delete(pinId: string, blockId: string): Promise<void> {\r\n return this.client.request<void>('DELETE', `/pins/${pinId}/blocks/${blockId}`)\r\n }\r\n}\r\n\r\n","/**\r\n * Collaborators API Methods\r\n */\r\n\r\nimport type { PindownClient } from '../PindownClient'\r\nimport type {\r\n Collaborator,\r\n InviteCollaboratorRequest,\r\n UpdateCollaboratorRoleRequest,\r\n Permissions\r\n} from '../../types/api'\r\n\r\nexport class CollaboratorsMethods {\r\n constructor(private client: PindownClient) {}\r\n\r\n // ============================================\r\n // Pin Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pin\r\n */\r\n async listForPin(pinId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pins/${pinId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pin\r\n */\r\n async inviteToPin(pinId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pins/${pinId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pin collaborator's role\r\n */\r\n async updatePinRole(pinId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pins/${pinId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pin\r\n */\r\n async removeFromPin(pinId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pins/${pinId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pin\r\n */\r\n async getPinPermissions(pinId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pins/${pinId}/permissions`)\r\n }\r\n\r\n // ============================================\r\n // Pinboard Collaborators\r\n // ============================================\r\n\r\n /**\r\n * List collaborators for a pinboard\r\n */\r\n async listForPinboard(boardId: string): Promise<{\r\n owner: Collaborator\r\n collaborators: Collaborator[]\r\n pending_invites: Array<{ email: string; role: string; invited_at: string }>\r\n }> {\r\n return this.client.request('GET', `/pinboards/${boardId}/collaborators`)\r\n }\r\n\r\n /**\r\n * Invite a collaborator to a pinboard\r\n */\r\n async inviteToPinboard(boardId: string, request: InviteCollaboratorRequest): Promise<void> {\r\n return this.client.request('POST', `/pinboards/${boardId}/collaborators`, request)\r\n }\r\n\r\n /**\r\n * Update a pinboard collaborator's role\r\n */\r\n async updatePinboardRole(boardId: string, userId: string, request: UpdateCollaboratorRoleRequest): Promise<void> {\r\n return this.client.request('PUT', `/pinboards/${boardId}/collaborators/${userId}`, request)\r\n }\r\n\r\n /**\r\n * Remove a collaborator from a pinboard\r\n */\r\n async removeFromPinboard(boardId: string, userId: string): Promise<void> {\r\n return this.client.request('DELETE', `/pinboards/${boardId}/collaborators/${userId}`)\r\n }\r\n\r\n /**\r\n * Get current user's permissions for a pinboard\r\n */\r\n async getPinboardPermissions(boardId: string): Promise<Permissions> {\r\n return this.client.request('GET', `/pinboards/${boardId}/permissions`)\r\n }\r\n}\r\n\r\n","/**\n * Pindown API Client\n */\n\nimport { RateLimiter } from '../utils/RateLimiter'\nimport { PinsMethods } from './pins'\nimport { PinboardsMethods } from './pinboards'\nimport { DatasetsMethods } from './datasets'\nimport { BlocksMethods } from './blocks'\nimport { CollaboratorsMethods } from './collaborators'\nimport type { PindownConfig, Tier } from '../types/config'\nimport type { RateLimitInfo } from '../types/api'\nimport {\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n ServerError,\n NetworkError\n} from '../errors'\n\nexport class PindownClient {\n private config: Omit<Required<PindownConfig>, 'tier'> & { tier?: Tier }\n private rateLimiter?: RateLimiter\n private tierDetected: boolean = false\n\n public readonly pins: PinsMethods\n public readonly pinboards: PinboardsMethods\n public readonly datasets: DatasetsMethods\n public readonly blocks: BlocksMethods\n public readonly collaborators: CollaboratorsMethods\n\n constructor(config: PindownConfig) {\n // Validate required config\n if (!config.apiKey) {\n throw new Error('API key is required')\n }\n\n // Set defaults\n this.config = {\n apiKey: config.apiKey,\n tier: config.tier, // Optional - will be auto-detected\n baseURL: config.baseURL || 'https://api.pindown.ai/v1',\n enableRateLimitTracking: config.enableRateLimitTracking ?? true,\n maxRetries: config.maxRetries ?? 3,\n timeout: config.timeout ?? 30000\n }\n\n // Initialize rate limiter if tier is provided\n if (this.config.tier) {\n this.rateLimiter = new RateLimiter(this.config.tier)\n this.tierDetected = true\n }\n\n // Initialize API methods\n this.pins = new PinsMethods(this)\n this.pinboards = new PinboardsMethods(this)\n this.datasets = new DatasetsMethods(this)\n this.blocks = new BlocksMethods(this)\n this.collaborators = new CollaboratorsMethods(this)\n }\n\n /**\n * Core request method\n */\n async request<T = any>(\n method: string,\n endpoint: string,\n data?: any\n ): Promise<T> {\n // Check rate limit BEFORE making request (if tier is detected)\n if (this.config.enableRateLimitTracking && this.rateLimiter) {\n this.rateLimiter.checkLimit(method, endpoint, data)\n }\n\n const url = `${this.config.baseURL}${endpoint}`\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json'\n }\n\n const requestOptions: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.config.timeout)\n }\n\n if (data && (method === 'POST' || method === 'PUT')) {\n requestOptions.body = JSON.stringify(data)\n }\n\n try {\n const response = await fetch(url, requestOptions)\n\n // Auto-detect tier from response headers (if not already detected)\n if (!this.tierDetected && this.config.enableRateLimitTracking) {\n this.detectTierFromHeaders(response.headers)\n }\n\n // Handle error responses\n if (!response.ok) {\n await this.handleErrorResponse(response)\n }\n\n // Parse JSON response\n const result = await response.json()\n return result.data as T\n } catch (error: any) {\n // Re-throw our custom errors\n if (\n error instanceof AuthenticationError ||\n error instanceof ForbiddenError ||\n error instanceof NotFoundError ||\n error instanceof ValidationError ||\n error instanceof ServerError\n ) {\n throw error\n }\n\n // Network or timeout errors\n if (error.name === 'AbortError' || error.name === 'TimeoutError') {\n throw new NetworkError('Request timeout')\n }\n\n throw new NetworkError(error.message || 'Network request failed')\n }\n }\n\n /**\n * Handle error responses from API\n */\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorData: any\n\n try {\n errorData = await response.json()\n } catch {\n errorData = { message: response.statusText }\n }\n\n const message = errorData.error?.message || errorData.message || 'Unknown error'\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message)\n case 403:\n throw new ForbiddenError(message)\n case 404:\n throw new NotFoundError(message)\n case 400:\n case 422:\n throw new ValidationError(message, errorData.error?.details)\n case 429:\n // Rate limit error from server (should rarely happen with client-side limiting)\n throw new ValidationError('Rate limit exceeded (server)', errorData)\n case 500:\n case 502:\n case 503:\n throw new ServerError(message, response.status)\n default:\n throw new ServerError(message, response.status)\n }\n }\n\n /**\n * Detect tier from response headers\n */\n private detectTierFromHeaders(headers: Headers): void {\n const tierHeader = headers.get('X-RateLimit-Tier')\n if (tierHeader && !this.rateLimiter) {\n const tier = tierHeader.toLowerCase() as Tier\n console.log(`[Pindown Client] Auto-detected tier: ${tier}`)\n this.config.tier = tier\n this.rateLimiter = new RateLimiter(tier)\n this.tierDetected = true\n }\n }\n\n /**\n * Get current rate limit info\n */\n getRateLimitInfo(): RateLimitInfo | null {\n if (!this.rateLimiter) {\n return null\n }\n return this.rateLimiter.getRateLimitInfo()\n }\n\n /**\n * Get current tier\n */\n getTier(): Tier | null {\n return this.config.tier || null\n }\n\n /**\n * Destroy the client (cleanup resources)\n */\n destroy(): void {\n if (this.rateLimiter) {\n this.rateLimiter.destroy()\n }\n }\n}\n\n"]}
package/dist/index.d.cts CHANGED
@@ -27,10 +27,8 @@ interface Pin {
27
27
  owner_id: string;
28
28
  data_type: PinDataType;
29
29
  pin_card_type?: PinCardType;
30
- content: any;
31
30
  metadata?: {
32
31
  name?: string;
33
- description?: string;
34
32
  tags?: string[];
35
33
  [key: string]: any;
36
34
  };
@@ -42,13 +40,23 @@ interface Pin {
42
40
  updated_at: string;
43
41
  }
44
42
  interface CreatePinRequest {
45
- data_type: PinDataType;
43
+ data_type?: PinDataType;
46
44
  pin_card_type?: PinCardType;
47
- content: any;
48
- metadata?: Pin['metadata'];
45
+ is_public?: boolean;
46
+ metadata: {
47
+ title: string;
48
+ tags?: string[];
49
+ allow_edit?: boolean;
50
+ require_sign_in?: boolean;
51
+ allow_comments?: boolean;
52
+ pin_card_type?: PinCardType;
53
+ pin_card_layout?: string;
54
+ pin_card_config?: any;
55
+ [key: string]: any;
56
+ };
57
+ pending_invites?: Record<string, 'editor' | 'viewer'>;
49
58
  }
50
59
  interface UpdatePinRequest {
51
- content?: any;
52
60
  metadata?: Pin['metadata'];
53
61
  }
54
62
  interface SharePinRequest {
@@ -65,7 +73,6 @@ interface Pinboard {
65
73
  id: string;
66
74
  user_id: string;
67
75
  title: string;
68
- description?: string;
69
76
  tags?: string[];
70
77
  layout?: Record<string, any>;
71
78
  mobile_layout?: Record<string, any>;
@@ -78,14 +85,12 @@ interface Pinboard {
78
85
  }
79
86
  interface CreatePinboardRequest {
80
87
  title: string;
81
- description?: string;
82
88
  tags?: string[];
83
89
  layout?: Record<string, any>;
84
90
  mobile_layout?: Record<string, any>;
85
91
  }
86
92
  interface UpdatePinboardRequest {
87
93
  title?: string;
88
- description?: string;
89
94
  tags?: string[];
90
95
  is_public?: boolean;
91
96
  allow_comments?: boolean;
@@ -111,7 +116,6 @@ interface Dataset {
111
116
  name: string;
112
117
  type: DatasetType;
113
118
  data: any;
114
- description?: string;
115
119
  created_at: string;
116
120
  updated_at: string;
117
121
  }
@@ -119,13 +123,11 @@ interface CreateDatasetRequest {
119
123
  name: string;
120
124
  type: DatasetType;
121
125
  data: any;
122
- description?: string;
123
126
  }
124
127
  interface UpdateDatasetRequest {
125
128
  name?: string;
126
129
  type?: DatasetType;
127
130
  data?: any;
128
- description?: string;
129
131
  }
130
132
  type BlockType = 'markdown' | 'mermaid' | 'conditional' | 'image' | 'stat-cards' | 'line-chart' | 'flexible-table' | 'embed';
131
133
  interface Block {
@@ -220,9 +222,9 @@ declare class PinsMethods {
220
222
  */
221
223
  share(pinId: string, request: SharePinRequest): Promise<Pin>;
222
224
  /**
223
- * Create a markdown pin
225
+ * Create a markdown pin (content comes from blocks)
224
226
  */
225
- createMarkdown(content: string, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
227
+ createMarkdown(title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
226
228
  /**
227
229
  * Create a stat card pin
228
230
  */
@@ -231,7 +233,7 @@ declare class PinsMethods {
231
233
  value: string | number;
232
234
  change?: string;
233
235
  icon?: string;
234
- }, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
236
+ }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
235
237
  /**
236
238
  * Create a flexible table pin
237
239
  */
@@ -242,11 +244,11 @@ declare class PinsMethods {
242
244
  type?: string;
243
245
  }>;
244
246
  rows: Array<Record<string, any>>;
245
- }, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
247
+ }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
246
248
  /**
247
249
  * Create an embed pin (YouTube, Figma, etc.)
248
250
  */
249
- createEmbed(url: string, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
251
+ createEmbed(url: string, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
250
252
  }
251
253
 
252
254
  /**
@@ -437,7 +439,7 @@ interface PindownConfig {
437
439
  tier?: Tier;
438
440
  /**
439
441
  * Base URL for the API
440
- * @default 'https://api.pindown.ai/api/v1'
442
+ * @default 'https://api.pindown.ai/v1'
441
443
  */
442
444
  baseURL?: string;
443
445
  /**
package/dist/index.d.ts CHANGED
@@ -27,10 +27,8 @@ interface Pin {
27
27
  owner_id: string;
28
28
  data_type: PinDataType;
29
29
  pin_card_type?: PinCardType;
30
- content: any;
31
30
  metadata?: {
32
31
  name?: string;
33
- description?: string;
34
32
  tags?: string[];
35
33
  [key: string]: any;
36
34
  };
@@ -42,13 +40,23 @@ interface Pin {
42
40
  updated_at: string;
43
41
  }
44
42
  interface CreatePinRequest {
45
- data_type: PinDataType;
43
+ data_type?: PinDataType;
46
44
  pin_card_type?: PinCardType;
47
- content: any;
48
- metadata?: Pin['metadata'];
45
+ is_public?: boolean;
46
+ metadata: {
47
+ title: string;
48
+ tags?: string[];
49
+ allow_edit?: boolean;
50
+ require_sign_in?: boolean;
51
+ allow_comments?: boolean;
52
+ pin_card_type?: PinCardType;
53
+ pin_card_layout?: string;
54
+ pin_card_config?: any;
55
+ [key: string]: any;
56
+ };
57
+ pending_invites?: Record<string, 'editor' | 'viewer'>;
49
58
  }
50
59
  interface UpdatePinRequest {
51
- content?: any;
52
60
  metadata?: Pin['metadata'];
53
61
  }
54
62
  interface SharePinRequest {
@@ -65,7 +73,6 @@ interface Pinboard {
65
73
  id: string;
66
74
  user_id: string;
67
75
  title: string;
68
- description?: string;
69
76
  tags?: string[];
70
77
  layout?: Record<string, any>;
71
78
  mobile_layout?: Record<string, any>;
@@ -78,14 +85,12 @@ interface Pinboard {
78
85
  }
79
86
  interface CreatePinboardRequest {
80
87
  title: string;
81
- description?: string;
82
88
  tags?: string[];
83
89
  layout?: Record<string, any>;
84
90
  mobile_layout?: Record<string, any>;
85
91
  }
86
92
  interface UpdatePinboardRequest {
87
93
  title?: string;
88
- description?: string;
89
94
  tags?: string[];
90
95
  is_public?: boolean;
91
96
  allow_comments?: boolean;
@@ -111,7 +116,6 @@ interface Dataset {
111
116
  name: string;
112
117
  type: DatasetType;
113
118
  data: any;
114
- description?: string;
115
119
  created_at: string;
116
120
  updated_at: string;
117
121
  }
@@ -119,13 +123,11 @@ interface CreateDatasetRequest {
119
123
  name: string;
120
124
  type: DatasetType;
121
125
  data: any;
122
- description?: string;
123
126
  }
124
127
  interface UpdateDatasetRequest {
125
128
  name?: string;
126
129
  type?: DatasetType;
127
130
  data?: any;
128
- description?: string;
129
131
  }
130
132
  type BlockType = 'markdown' | 'mermaid' | 'conditional' | 'image' | 'stat-cards' | 'line-chart' | 'flexible-table' | 'embed';
131
133
  interface Block {
@@ -220,9 +222,9 @@ declare class PinsMethods {
220
222
  */
221
223
  share(pinId: string, request: SharePinRequest): Promise<Pin>;
222
224
  /**
223
- * Create a markdown pin
225
+ * Create a markdown pin (content comes from blocks)
224
226
  */
225
- createMarkdown(content: string, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
227
+ createMarkdown(title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
226
228
  /**
227
229
  * Create a stat card pin
228
230
  */
@@ -231,7 +233,7 @@ declare class PinsMethods {
231
233
  value: string | number;
232
234
  change?: string;
233
235
  icon?: string;
234
- }, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
236
+ }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
235
237
  /**
236
238
  * Create a flexible table pin
237
239
  */
@@ -242,11 +244,11 @@ declare class PinsMethods {
242
244
  type?: string;
243
245
  }>;
244
246
  rows: Array<Record<string, any>>;
245
- }, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
247
+ }, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
246
248
  /**
247
249
  * Create an embed pin (YouTube, Figma, etc.)
248
250
  */
249
- createEmbed(url: string, metadata?: CreatePinRequest['metadata']): Promise<Pin>;
251
+ createEmbed(url: string, title: string, additionalMetadata?: Partial<CreatePinRequest['metadata']>): Promise<Pin>;
250
252
  }
251
253
 
252
254
  /**
@@ -437,7 +439,7 @@ interface PindownConfig {
437
439
  tier?: Tier;
438
440
  /**
439
441
  * Base URL for the API
440
- * @default 'https://api.pindown.ai/api/v1'
442
+ * @default 'https://api.pindown.ai/v1'
441
443
  */
442
444
  baseURL?: string;
443
445
  /**
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var C={starter:{tokensPerHour:16,tokensPerMinute:null},hobby:{tokensPerHour:6e3,tokensPerMinute:100},pro:{tokensPerHour:24e3,tokensPerMinute:400},teams:{tokensPerHour:6e4,tokensPerMinute:1e3},agency:{tokensPerHour:24e4,tokensPerMinute:4e3}};var E={GET:1,POST:1,PUT:1,DELETE:1,INVITE:3,SHARE:3,BATCH_1_10:3,BATCH_11_25:5,BATCH_26_50:10};var o=class extends Error{constructor(e){super(e),this.name="PindownError";}},d=class extends o{constructor(e="Authentication failed"){super(e),this.name="AuthenticationError";}},p=class extends o{constructor(e="Access forbidden"){super(e),this.name="ForbiddenError";}},m=class extends o{constructor(e){super(`${e} not found`),this.name="NotFoundError";}},c=class extends o{constructor(e,t){super(e),this.name="ValidationError",this.details=t;}},P=class extends o{constructor(e){super(`Rate limit exceeded: ${e.used}/${e.limit} tokens used in ${e.window} window. Resets at ${e.resetAt.toISOString()}`),this.name="RateLimitError",this.window=e.window,this.limit=e.limit,this.used=e.used,this.remaining=e.remaining,this.resetAt=e.resetAt,this.tier=e.tier;}},l=class extends o{constructor(e,t=500){super(e),this.name="ServerError",this.statusCode=t;}},h=class extends o{constructor(e="Network request failed"){super(e),this.name="NetworkError";}};var $=C,g=E,b=class{constructor(e){this.minuteTokens=new Map;this.hourTokens=new Map;this.tier=e,this.cleanupInterval=setInterval(()=>this.cleanup(),300*1e3);}checkLimit(e,t,r){let n=this.calculateTokenCost(e,t,r),a=this.getMinuteWindow(),u=this.getHourWindow(),i=$[this.tier];if(i.tokensPerMinute!==null){let k=this.minuteTokens.get(a)||0;if(k+n>i.tokensPerMinute)throw new P({window:"minute",limit:i.tokensPerMinute,used:k,remaining:Math.max(0,i.tokensPerMinute-k),resetAt:this.getMinuteResetTime(),tier:this.tier})}let y=this.hourTokens.get(u)||0;if(y+n>i.tokensPerHour)throw new P({window:"hour",limit:i.tokensPerHour,used:y,remaining:Math.max(0,i.tokensPerHour-y),resetAt:this.getHourResetTime(),tier:this.tier});this.incrementToken(a,n),this.incrementToken(u,n);}calculateTokenCost(e,t,r){if(t.includes("/batch")||t.includes("/sync")){if(r?.operations){let n=Array.isArray(r.operations)?r.operations.length:0;return n<=10?g.BATCH_1_10:n<=25?g.BATCH_11_25:(g.BATCH_26_50)}if(r?.pins){let n=Array.isArray(r.pins)?r.pins.length:0;return n<=16?5:(8)}}return t.includes("/collaborators")||t.includes("/invite")||t.includes("/share")?g.INVITE:g[e]||1}getMinuteWindow(){let e=new Date;return `minute_${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}-${String(e.getHours()).padStart(2,"0")}-${String(e.getMinutes()).padStart(2,"0")}`}getHourWindow(){let e=new Date;return `hour_${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}-${String(e.getHours()).padStart(2,"0")}`}incrementToken(e,t){if(e.startsWith("minute")){let r=this.minuteTokens.get(e)||0;this.minuteTokens.set(e,r+t);}else {let r=this.hourTokens.get(e)||0;this.hourTokens.set(e,r+t);}}getMinuteResetTime(){let e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes()+1,0,0)}getHourResetTime(){let e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours()+1,0,0,0)}getRateLimitInfo(){let e=$[this.tier],t=this.getMinuteWindow(),r=this.getHourWindow(),n=this.minuteTokens.get(t)||0,a=this.hourTokens.get(r)||0;return {tier:this.tier,minute:{limit:e.tokensPerMinute||0,used:n,remaining:e.tokensPerMinute?Math.max(0,e.tokensPerMinute-n):1/0,resetAt:this.getMinuteResetTime()},hour:{limit:e.tokensPerHour,used:a,remaining:Math.max(0,e.tokensPerHour-a),resetAt:this.getHourResetTime()}}}cleanup(){let t=Date.now()-7200*1e3;for(let[r]of this.minuteTokens)this.parseWindowTimestamp(r)<t&&this.minuteTokens.delete(r);for(let[r]of this.hourTokens)this.parseWindowTimestamp(r)<t&&this.hourTokens.delete(r);}parseWindowTimestamp(e){let t=e.split("_")[1].split("-"),r=parseInt(t[0]),n=parseInt(t[1])-1,a=parseInt(t[2]),u=parseInt(t[3]),i=e.startsWith("minute")?parseInt(t[4]):0;return new Date(r,n,a,u,i).getTime()}destroy(){this.cleanupInterval&&clearInterval(this.cleanupInterval);}};var T=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pins",e)}async get(e){return this.client.request("GET",`/pins/${e}`)}async list(e){let t=new URLSearchParams;e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let r=t.toString(),n=r?`/pins?${r}`:"/pins";return this.client.request("GET",n)}async update(e,t){return this.client.request("PUT",`/pins/${e}`,t)}async delete(e){return this.client.request("DELETE",`/pins/${e}`)}async share(e,t){return this.client.request("POST",`/pins/${e}/share`,t)}async createMarkdown(e,t){return this.create({data_type:"markdown",content:e,metadata:t})}async createStatCard(e,t){return this.create({data_type:"pin-card",pin_card_type:"stat-cards",content:[e],metadata:t})}async createTable(e,t){return this.create({data_type:"pin-card",pin_card_type:"flexible-table",content:e,metadata:t})}async createEmbed(e,t){return this.create({data_type:"pin-card",pin_card_type:"embed",content:{url:e},metadata:t})}};var w=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/pinboards",e)}async get(e){return this.client.request("GET",`/pinboards/${e}`)}async list(){return this.client.request("GET","/pinboards")}async update(e,t){return this.client.request("PUT",`/pinboards/${e}`,t)}async delete(e){return this.client.request("DELETE",`/pinboards/${e}`)}async addPin(e,t){return this.client.request("POST",`/pinboards/${e}/pins`,t)}async removePin(e,t){return this.client.request("DELETE",`/pinboards/${e}/pins/${t}`)}async updateLayout(e,t){return this.client.request("PUT",`/pinboards/${e}/layout`,t)}async share(e,t){return this.client.request("POST",`/pinboards/${e}/share`,t)}};var f=class{constructor(e){this.client=e;}async create(e){return this.client.request("POST","/datasets",e)}async get(e){return this.client.request("GET",`/datasets/${e}`)}async list(){return this.client.request("GET","/datasets")}async update(e,t){return this.client.request("PUT",`/datasets/${e}`,t)}async delete(e){return this.client.request("DELETE",`/datasets/${e}`)}};var R=class{constructor(e){this.client=e;}async create(e,t){return this.client.request("POST",`/pins/${e}/blocks`,t)}async get(e,t){return this.client.request("GET",`/pins/${e}/blocks/${t}`)}async list(e){return this.client.request("GET",`/pins/${e}/blocks`)}async update(e,t,r){return this.client.request("PUT",`/pins/${e}/blocks/${t}`,r)}async delete(e,t){return this.client.request("DELETE",`/pins/${e}/blocks/${t}`)}};var q=class{constructor(e){this.client=e;}async listForPin(e){return this.client.request("GET",`/pins/${e}/collaborators`)}async inviteToPin(e,t){return this.client.request("POST",`/pins/${e}/collaborators`,t)}async updatePinRole(e,t,r){return this.client.request("PUT",`/pins/${e}/collaborators/${t}`,r)}async removeFromPin(e,t){return this.client.request("DELETE",`/pins/${e}/collaborators/${t}`)}async getPinPermissions(e){return this.client.request("GET",`/pins/${e}/permissions`)}async listForPinboard(e){return this.client.request("GET",`/pinboards/${e}/collaborators`)}async inviteToPinboard(e,t){return this.client.request("POST",`/pinboards/${e}/collaborators`,t)}async updatePinboardRole(e,t,r){return this.client.request("PUT",`/pinboards/${e}/collaborators/${t}`,r)}async removeFromPinboard(e,t){return this.client.request("DELETE",`/pinboards/${e}/collaborators/${t}`)}async getPinboardPermissions(e){return this.client.request("GET",`/pinboards/${e}/permissions`)}};var v=class{constructor(e){this.tierDetected=false;if(!e.apiKey)throw new Error("API key is required");this.config={apiKey:e.apiKey,tier:e.tier,baseURL:e.baseURL||"https://api.pindown.ai/api/v1",enableRateLimitTracking:e.enableRateLimitTracking??true,maxRetries:e.maxRetries??3,timeout:e.timeout??3e4},this.config.tier&&(this.rateLimiter=new b(this.config.tier),this.tierDetected=true),this.pins=new T(this),this.pinboards=new w(this),this.datasets=new f(this),this.blocks=new R(this),this.collaborators=new q(this);}async request(e,t,r){this.config.enableRateLimitTracking&&this.rateLimiter&&this.rateLimiter.checkLimit(e,t,r);let n=`${this.config.baseURL}${t}`,a={Authorization:`Bearer ${this.config.apiKey}`,"Content-Type":"application/json"},u={method:e,headers:a,signal:AbortSignal.timeout(this.config.timeout)};r&&(e==="POST"||e==="PUT")&&(u.body=JSON.stringify(r));try{let i=await fetch(n,u);return !this.tierDetected&&this.config.enableRateLimitTracking&&this.detectTierFromHeaders(i.headers),i.ok||await this.handleErrorResponse(i),(await i.json()).data}catch(i){throw i instanceof d||i instanceof p||i instanceof m||i instanceof c||i instanceof l?i:i.name==="AbortError"||i.name==="TimeoutError"?new h("Request timeout"):new h(i.message||"Network request failed")}}async handleErrorResponse(e){let t;try{t=await e.json();}catch{t={message:e.statusText};}let r=t.error?.message||t.message||"Unknown error";switch(e.status){case 401:throw new d(r);case 403:throw new p(r);case 404:throw new m(r);case 400:case 422:throw new c(r,t.error?.details);case 429:throw new c("Rate limit exceeded (server)",t);case 500:case 502:case 503:throw new l(r,e.status);default:throw new l(r,e.status)}}detectTierFromHeaders(e){let t=e.get("X-RateLimit-Tier");if(t&&!this.rateLimiter){let r=t.toLowerCase();console.log(`[Pindown Client] Auto-detected tier: ${r}`),this.config.tier=r,this.rateLimiter=new b(r),this.tierDetected=true;}}getRateLimitInfo(){return this.rateLimiter?this.rateLimiter.getRateLimitInfo():null}getTier(){return this.config.tier||null}destroy(){this.rateLimiter&&this.rateLimiter.destroy();}};/**
1
+ var C={starter:{tokensPerHour:16,tokensPerMinute:null},hobby:{tokensPerHour:6e3,tokensPerMinute:100},pro:{tokensPerHour:24e3,tokensPerMinute:400},teams:{tokensPerHour:6e4,tokensPerMinute:1e3},agency:{tokensPerHour:24e4,tokensPerMinute:4e3}};var E={GET:1,POST:1,PUT:1,DELETE:1,INVITE:3,SHARE:3,BATCH_1_10:3,BATCH_11_25:5,BATCH_26_50:10};var o=class extends Error{constructor(t){super(t),this.name="PindownError";}},d=class extends o{constructor(t="Authentication failed"){super(t),this.name="AuthenticationError";}},p=class extends o{constructor(t="Access forbidden"){super(t),this.name="ForbiddenError";}},m=class extends o{constructor(t){super(`${t} not found`),this.name="NotFoundError";}},c=class extends o{constructor(t,e){super(t),this.name="ValidationError",this.details=e;}},P=class extends o{constructor(t){super(`Rate limit exceeded: ${t.used}/${t.limit} tokens used in ${t.window} window. Resets at ${t.resetAt.toISOString()}`),this.name="RateLimitError",this.window=t.window,this.limit=t.limit,this.used=t.used,this.remaining=t.remaining,this.resetAt=t.resetAt,this.tier=t.tier;}},l=class extends o{constructor(t,e=500){super(t),this.name="ServerError",this.statusCode=e;}},h=class extends o{constructor(t="Network request failed"){super(t),this.name="NetworkError";}};var $=C,g=E,b=class{constructor(t){this.minuteTokens=new Map;this.hourTokens=new Map;this.tier=t,this.cleanupInterval=setInterval(()=>this.cleanup(),300*1e3);}checkLimit(t,e,r){let n=this.calculateTokenCost(t,e,r),a=this.getMinuteWindow(),u=this.getHourWindow(),i=$[this.tier];if(i.tokensPerMinute!==null){let k=this.minuteTokens.get(a)||0;if(k+n>i.tokensPerMinute)throw new P({window:"minute",limit:i.tokensPerMinute,used:k,remaining:Math.max(0,i.tokensPerMinute-k),resetAt:this.getMinuteResetTime(),tier:this.tier})}let y=this.hourTokens.get(u)||0;if(y+n>i.tokensPerHour)throw new P({window:"hour",limit:i.tokensPerHour,used:y,remaining:Math.max(0,i.tokensPerHour-y),resetAt:this.getHourResetTime(),tier:this.tier});this.incrementToken(a,n),this.incrementToken(u,n);}calculateTokenCost(t,e,r){if(e.includes("/batch")||e.includes("/sync")){if(r?.operations){let n=Array.isArray(r.operations)?r.operations.length:0;return n<=10?g.BATCH_1_10:n<=25?g.BATCH_11_25:(g.BATCH_26_50)}if(r?.pins){let n=Array.isArray(r.pins)?r.pins.length:0;return n<=16?5:(8)}}return e.includes("/collaborators")||e.includes("/invite")||e.includes("/share")?g.INVITE:g[t]||1}getMinuteWindow(){let t=new Date;return `minute_${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}-${String(t.getHours()).padStart(2,"0")}-${String(t.getMinutes()).padStart(2,"0")}`}getHourWindow(){let t=new Date;return `hour_${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}-${String(t.getHours()).padStart(2,"0")}`}incrementToken(t,e){if(t.startsWith("minute")){let r=this.minuteTokens.get(t)||0;this.minuteTokens.set(t,r+e);}else {let r=this.hourTokens.get(t)||0;this.hourTokens.set(t,r+e);}}getMinuteResetTime(){let t=new Date;return new Date(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes()+1,0,0)}getHourResetTime(){let t=new Date;return new Date(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours()+1,0,0,0)}getRateLimitInfo(){let t=$[this.tier],e=this.getMinuteWindow(),r=this.getHourWindow(),n=this.minuteTokens.get(e)||0,a=this.hourTokens.get(r)||0;return {tier:this.tier,minute:{limit:t.tokensPerMinute||0,used:n,remaining:t.tokensPerMinute?Math.max(0,t.tokensPerMinute-n):1/0,resetAt:this.getMinuteResetTime()},hour:{limit:t.tokensPerHour,used:a,remaining:Math.max(0,t.tokensPerHour-a),resetAt:this.getHourResetTime()}}}cleanup(){let e=Date.now()-7200*1e3;for(let[r]of this.minuteTokens)this.parseWindowTimestamp(r)<e&&this.minuteTokens.delete(r);for(let[r]of this.hourTokens)this.parseWindowTimestamp(r)<e&&this.hourTokens.delete(r);}parseWindowTimestamp(t){let e=t.split("_")[1].split("-"),r=parseInt(e[0]),n=parseInt(e[1])-1,a=parseInt(e[2]),u=parseInt(e[3]),i=t.startsWith("minute")?parseInt(e[4]):0;return new Date(r,n,a,u,i).getTime()}destroy(){this.cleanupInterval&&clearInterval(this.cleanupInterval);}};var T=class{constructor(t){this.client=t;}async create(t){return this.client.request("POST","/pins",t)}async get(t){return this.client.request("GET",`/pins/${t}`)}async list(t){let e=new URLSearchParams;t?.limit&&e.append("limit",t.limit.toString()),t?.offset&&e.append("offset",t.offset.toString());let r=e.toString(),n=r?`/pins?${r}`:"/pins";return this.client.request("GET",n)}async update(t,e){return this.client.request("PUT",`/pins/${t}`,e)}async delete(t){return this.client.request("DELETE",`/pins/${t}`)}async share(t,e){return this.client.request("POST",`/pins/${t}/share`,e)}async createMarkdown(t,e){return this.create({data_type:"markdown",metadata:{title:t,...e}})}async createStatCard(t,e,r){return this.create({data_type:"pin-card",metadata:{title:e,pin_card_type:"stat-cards",pin_card_config:[t],...r}})}async createTable(t,e,r){return this.create({data_type:"pin-card",metadata:{title:e,pin_card_type:"flexible-table",pin_card_config:t,...r}})}async createEmbed(t,e,r){return this.create({data_type:"pin-card",metadata:{title:e,pin_card_type:"embed",pin_card_config:{url:t},...r}})}};var f=class{constructor(t){this.client=t;}async create(t){return this.client.request("POST","/pinboards",t)}async get(t){return this.client.request("GET",`/pinboards/${t}`)}async list(){return this.client.request("GET","/pinboards")}async update(t,e){return this.client.request("PUT",`/pinboards/${t}`,e)}async delete(t){return this.client.request("DELETE",`/pinboards/${t}`)}async addPin(t,e){return this.client.request("POST",`/pinboards/${t}/pins`,e)}async removePin(t,e){return this.client.request("DELETE",`/pinboards/${t}/pins/${e}`)}async updateLayout(t,e){return this.client.request("PUT",`/pinboards/${t}/layout`,e)}async share(t,e){return this.client.request("POST",`/pinboards/${t}/share`,e)}};var w=class{constructor(t){this.client=t;}async create(t){return this.client.request("POST","/datasets",t)}async get(t){return this.client.request("GET",`/datasets/${t}`)}async list(){return this.client.request("GET","/datasets")}async update(t,e){return this.client.request("PUT",`/datasets/${t}`,e)}async delete(t){return this.client.request("DELETE",`/datasets/${t}`)}};var R=class{constructor(t){this.client=t;}async create(t,e){return this.client.request("POST",`/pins/${t}/blocks`,e)}async get(t,e){return this.client.request("GET",`/pins/${t}/blocks/${e}`)}async list(t){return this.client.request("GET",`/pins/${t}/blocks`)}async update(t,e,r){return this.client.request("PUT",`/pins/${t}/blocks/${e}`,r)}async delete(t,e){return this.client.request("DELETE",`/pins/${t}/blocks/${e}`)}};var q=class{constructor(t){this.client=t;}async listForPin(t){return this.client.request("GET",`/pins/${t}/collaborators`)}async inviteToPin(t,e){return this.client.request("POST",`/pins/${t}/collaborators`,e)}async updatePinRole(t,e,r){return this.client.request("PUT",`/pins/${t}/collaborators/${e}`,r)}async removeFromPin(t,e){return this.client.request("DELETE",`/pins/${t}/collaborators/${e}`)}async getPinPermissions(t){return this.client.request("GET",`/pins/${t}/permissions`)}async listForPinboard(t){return this.client.request("GET",`/pinboards/${t}/collaborators`)}async inviteToPinboard(t,e){return this.client.request("POST",`/pinboards/${t}/collaborators`,e)}async updatePinboardRole(t,e,r){return this.client.request("PUT",`/pinboards/${t}/collaborators/${e}`,r)}async removeFromPinboard(t,e){return this.client.request("DELETE",`/pinboards/${t}/collaborators/${e}`)}async getPinboardPermissions(t){return this.client.request("GET",`/pinboards/${t}/permissions`)}};var v=class{constructor(t){this.tierDetected=false;if(!t.apiKey)throw new Error("API key is required");this.config={apiKey:t.apiKey,tier:t.tier,baseURL:t.baseURL||"https://api.pindown.ai/v1",enableRateLimitTracking:t.enableRateLimitTracking??true,maxRetries:t.maxRetries??3,timeout:t.timeout??3e4},this.config.tier&&(this.rateLimiter=new b(this.config.tier),this.tierDetected=true),this.pins=new T(this),this.pinboards=new f(this),this.datasets=new w(this),this.blocks=new R(this),this.collaborators=new q(this);}async request(t,e,r){this.config.enableRateLimitTracking&&this.rateLimiter&&this.rateLimiter.checkLimit(t,e,r);let n=`${this.config.baseURL}${e}`,a={Authorization:`Bearer ${this.config.apiKey}`,"Content-Type":"application/json"},u={method:t,headers:a,signal:AbortSignal.timeout(this.config.timeout)};r&&(t==="POST"||t==="PUT")&&(u.body=JSON.stringify(r));try{let i=await fetch(n,u);return !this.tierDetected&&this.config.enableRateLimitTracking&&this.detectTierFromHeaders(i.headers),i.ok||await this.handleErrorResponse(i),(await i.json()).data}catch(i){throw i instanceof d||i instanceof p||i instanceof m||i instanceof c||i instanceof l?i:i.name==="AbortError"||i.name==="TimeoutError"?new h("Request timeout"):new h(i.message||"Network request failed")}}async handleErrorResponse(t){let e;try{e=await t.json();}catch{e={message:t.statusText};}let r=e.error?.message||e.message||"Unknown error";switch(t.status){case 401:throw new d(r);case 403:throw new p(r);case 404:throw new m(r);case 400:case 422:throw new c(r,e.error?.details);case 429:throw new c("Rate limit exceeded (server)",e);case 500:case 502:case 503:throw new l(r,t.status);default:throw new l(r,t.status)}}detectTierFromHeaders(t){let e=t.get("X-RateLimit-Tier");if(e&&!this.rateLimiter){let r=e.toLowerCase();console.log(`[Pindown Client] Auto-detected tier: ${r}`),this.config.tier=r,this.rateLimiter=new b(r),this.tierDetected=true;}}getRateLimitInfo(){return this.rateLimiter?this.rateLimiter.getRateLimitInfo():null}getTier(){return this.config.tier||null}destroy(){this.rateLimiter&&this.rateLimiter.destroy();}};/**
2
2
  * @pindownai/client-js
3
3
  *
4
4
  * Official TypeScript/JavaScript client for Pindown.ai API