/** * Dribbble Integration for WORKWAY * * Enables design portfolio automation: sync shots to Notion, * showcase work on websites, track design engagement, and inspire teams. * * Key use cases: * - New Shot Published → Notion portfolio + Slack announcement * - Design Inspiration → Curate trending shots for team * - Portfolio Sync → Auto-update website with latest work * * @example * ```typescript * import { Dribbble } from '@workwayco/integrations/dribbble'; * * const dribbble = new Dribbble({ accessToken: tokens.dribbble.access_token }); * * // Get current user * const user = await dribbble.getCurrentUser(); * * // List shots * const shots = await dribbble.listShots({ perPage: 10 }); * * // Get a specific shot * const shot = await dribbble.getShot('12345678'); * ``` */ import { ActionResult } from '@workwayco/sdk'; import { BaseAPIClient } from '../core/index.js'; /** * Dribbble integration configuration */ export interface DribbbleConfig { /** OAuth access token */ accessToken: string; /** Optional: Override API endpoint */ apiUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; } /** * Shot image URLs in different sizes */ export interface DribbbleImages { /** High DPI image (if available) */ hidpi: string | null; /** Normal resolution image */ normal: string; /** Teaser/thumbnail image */ teaser: string; } /** * Video information (for animated shots) */ export interface DribbbleVideo { /** Video ID */ id: number; /** Video duration in seconds */ duration: number; /** Video dimensions */ width: number; height: number; /** Silent video (no audio) */ silent: boolean; /** Preview frame URLs */ previews: { p480: string; }; /** Video URL */ url: string; } /** * File attachment on a shot */ export interface DribbbleAttachment { /** Attachment ID */ id: number; /** Direct URL to the attachment file */ url: string; /** Thumbnail URL */ thumbnail_url: string; /** File size in bytes */ size: number; /** MIME type */ content_type: string; /** When the attachment was created */ created_at: string; } /** * Social/web links for a user */ export interface DribbbleLinks { /** Personal website URL */ web: string | null; /** Twitter handle */ twitter: string | null; } /** * Team that a user belongs to */ export interface DribbbleTeam { /** Team ID */ id: number; /** Team display name */ name: string; /** Team username/handle */ login: string; /** Team profile URL */ html_url: string; /** Team avatar URL */ avatar_url: string; /** Team bio (HTML) */ bio: string; /** Team location */ location: string | null; /** Team links */ links: DribbbleLinks; /** Resource type (always "Team") */ type: 'Team'; /** When the team was created */ created_at: string; /** When the team was last updated */ updated_at: string; } /** * Dribbble user */ export interface DribbbleUser { /** User ID */ id: number; /** Full display name */ name: string; /** Username/handle */ login: string; /** Profile URL */ html_url: string; /** Avatar image URL */ avatar_url: string; /** Bio/description (HTML) */ bio: string; /** Location */ location: string | null; /** Social/web links */ links: DribbbleLinks; /** Whether user can upload shots */ can_upload_shot: boolean; /** Pro account status */ pro: boolean; /** Number of followers */ followers_count: number; /** When the account was created */ created_at: string; /** Resource type (always "User") */ type: 'User'; /** Teams the user belongs to */ teams: DribbbleTeam[]; } /** * Project that groups related shots */ export interface DribbbleProject { /** Project ID */ id: number; /** Project name */ name: string; /** Project description */ description: string; /** Number of shots in project */ shots_count: number; /** When the project was created */ created_at: string; /** When the project was last updated */ updated_at: string; } /** * A Dribbble shot (design post) */ export interface DribbbleShot { /** Shot ID */ id: number; /** Shot title */ title: string; /** Shot description (HTML) */ description: string | null; /** Image width in pixels */ width: number; /** Image height in pixels */ height: number; /** Image URLs in different sizes */ images: DribbbleImages; /** When the shot was published */ published_at: string; /** When the shot was last updated */ updated_at: string; /** URL to the shot page */ html_url: string; /** Whether the shot is animated */ animated: boolean; /** Tags associated with the shot */ tags: string[]; /** File attachments */ attachments: DribbbleAttachment[]; /** Projects this shot belongs to */ projects: DribbbleProject[]; /** Team that owns this shot (if any) */ team: DribbbleTeam | null; /** Video information (for animated shots) */ video: DribbbleVideo | null; /** Low profile mode (limited comments/likes) */ low_profile: boolean; } /** * Shot data for creating a new shot */ export interface CreateShotData { /** Shot title (required) */ title: string; /** Shot description (HTML supported) */ description?: string; /** Tags (max 12) */ tags?: string[]; /** Low profile mode */ low_profile?: boolean; /** Team ID to post under */ team_id?: number; /** Schedule publish time (ISO 8601) */ scheduled_for?: string; /** Image file - must be 400x300 or 800x600, max 8MB */ image: File | Blob; } /** * Shot data for updating an existing shot */ export interface UpdateShotData { /** Shot title */ title?: string; /** Shot description (HTML supported) */ description?: string; /** Tags (max 12) */ tags?: string[]; /** Low profile mode */ low_profile?: boolean; /** Team ID */ team_id?: number; /** Schedule publish time (ISO 8601) */ scheduled_for?: string; } /** * Options for listing shots */ export interface ListShotsOptions { /** Page number (default: 1) */ page?: number; /** Results per page (default: 30, max: 100) */ perPage?: number; } /** * Dribbble Integration * * Weniger, aber besser: Design portfolio data for compound workflows. */ export declare class Dribbble extends BaseAPIClient { constructor(config: DribbbleConfig); /** * Get the current authenticated user */ getCurrentUser(): Promise>; /** * List the authenticated user's shots */ listShots(options?: ListShotsOptions): Promise>; /** * Get a specific shot by ID */ getShot(shotId: string | number): Promise>; /** * Create a new shot * * Note: Requires the 'upload' OAuth scope. * Image must be exactly 400x300 or 800x600, and no larger than 8MB. */ createShot(data: CreateShotData): Promise>; /** * Update an existing shot * * Note: Requires the 'upload' OAuth scope and ownership of the shot. */ updateShot(shotId: string | number, data: UpdateShotData): Promise>; /** * Delete a shot * * Note: Requires the 'upload' OAuth scope and ownership of the shot. */ deleteShot(shotId: string | number): Promise>; /** * Extract shot details for easy consumption in workflows * * Zuhandenheit: Developer thinks "get shot details" * not "navigate nested shot object structure" */ static extractShotDetails(shot: DribbbleShot): { id: number; title: string; description: string; imageUrl: string; thumbnailUrl: string; hdImageUrl: string | null; isAnimated: boolean; tags: string[]; publishedAt: Date; webUrl: string; dimensions: { width: number; height: number; }; hasVideo: boolean; videoUrl: string | null; }; /** * Format shot for Notion-style display */ static formatShotForDisplay(shot: DribbbleShot): { title: string; description: string; image: { url: string; alt: string; }; metadata: Array<{ label: string; value: string; }>; }; /** * Check if user is a Pro member (for premium features) */ static isPro(user: DribbbleUser): boolean; /** * Get user's display info for profiles */ static getUserDisplayInfo(user: DribbbleUser): { name: string; username: string; avatar: string; bio: string; location: string; isPro: boolean; followersCount: number; profileUrl: string; website: string | null; twitter: string | null; teams: Array<{ name: string; url: string; }>; }; /** * POST with FormData (for file uploads) */ private postFormData; /** * Get capabilities for Dribbble actions */ private getCapabilities; } //# sourceMappingURL=index.d.ts.map