{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { DesignTokens } from '@tokiforge/core';\nimport { TokenParser } from '@tokiforge/core';\nimport axios from 'axios';\nimport type { AxiosInstance } from 'axios';\n\nexport interface FigmaConfig {\n  /**\n   * Figma Personal Access Token\n   */\n  accessToken: string;\n  /**\n   * Figma File Key\n   */\n  fileKey: string;\n  /**\n   * Optional: Node ID to sync from/to\n   */\n  nodeId?: string;\n}\n\nexport interface FigmaColor {\n  r: number;\n  g: number;\n  b: number;\n  a: number;\n}\n\nexport interface FigmaStyle {\n  key: string;\n  name: string;\n  description?: string;\n  styleType: 'FILL' | 'TEXT' | 'EFFECT' | 'GRID';\n}\n\n/**\n * Figma API client for syncing design tokens\n */\nexport class FigmaSync {\n  private api: AxiosInstance;\n  private config: FigmaConfig;\n\n  constructor(config: FigmaConfig) {\n    this.config = config;\n    this.api = axios.create({\n      baseURL: 'https://api.figma.com/v1',\n      headers: {\n        'X-Figma-Token': config.accessToken,\n      },\n    });\n  }\n\n  /**\n   * Pull tokens from Figma\n   */\n  async pullTokens(): Promise<DesignTokens> {\n    try {\n      const stylesResponse = await this.api.get(`/files/${this.config.fileKey}/styles`);\n      const styles = stylesResponse.data.meta.styles;\n\n      const tokens: DesignTokens = {\n        color: {},\n      };\n\n      for (const style of styles) {\n        if (style.styleType === 'FILL') {\n          const styleDetails = await this.getStyleDetails(style.key);\n          if (styleDetails && styleDetails.fills && styleDetails.fills[0]) {\n            const fill = styleDetails.fills[0];\n            if (fill.type === 'SOLID' && fill.color) {\n              const color = this.figmaColorToHex(fill.color);\n              const tokenName = this.styleNameToTokenPath(style.name);\n              this.setNestedValue(tokens, tokenName, {\n                value: color,\n                type: 'color',\n                description: style.description,\n              });\n            }\n          }\n        }\n      }\n\n      return tokens;\n    } catch (error: any) {\n      throw new Error(`Failed to pull tokens from Figma: ${error.message}`);\n    }\n  }\n\n  /**\n   * Push tokens to Figma\n   */\n  async pushTokens(tokensPath: string): Promise<void> {\n    try {\n      const tokens = TokenParser.parse(tokensPath, { expandReferences: true });\n      \n      const colors = this.extractColors(tokens);\n      \n      for (const [path, color] of Object.entries(colors)) {\n        const styleName = this.tokenPathToStyleName(path);\n        await this.createOrUpdateStyle(styleName, color);\n      }\n    } catch (error: any) {\n      throw new Error(`Failed to push tokens to Figma: ${error.message}`);\n    }\n  }\n\n  /**\n   * Get style details from Figma\n   */\n  private async getStyleDetails(styleKey: string): Promise<any> {\n    try {\n      const response = await this.api.get(`/styles/${styleKey}`);\n      return response.data;\n    } catch (error) {\n      return null;\n    }\n  }\n\n  /**\n   * Create or update a Figma style\n   */\n  private async createOrUpdateStyle(\n    _name: string,\n    _color: string\n  ): Promise<void> {\n    // Creating styles via Figma API requires plugin context\n    // This functionality is limited by Figma API restrictions\n    throw new Error('Creating styles via API requires a Figma plugin context. Please use the Figma plugin for this feature.');\n  }\n\n  /**\n   * Convert Figma color to hex\n   */\n  private figmaColorToHex(color: FigmaColor): string {\n    const r = Math.round(color.r * 255);\n    const g = Math.round(color.g * 255);\n    const b = Math.round(color.b * 255);\n    return `#${[r, g, b].map(x => x.toString(16).padStart(2, '0')).join('')}`;\n  }\n\n\n  /**\n   * Extract colors from tokens\n   */\n  private extractColors(tokens: DesignTokens): Record<string, string> {\n    const colors: Record<string, string> = {};\n\n    const traverse = (obj: DesignTokens, path: string = ''): void => {\n      for (const key in obj) {\n        const currentPath = path ? `${path}.${key}` : key;\n        const value = obj[key];\n\n        if (value && typeof value === 'object' && !Array.isArray(value)) {\n          if ('value' in value || '$value' in value) {\n            const token = value as any;\n            const tokenValue = 'value' in token ? token.value : ('$value' in token ? token.$value : null);\n            if (typeof tokenValue === 'string' && tokenValue.startsWith('#')) {\n              colors[currentPath] = tokenValue;\n            }\n          } else {\n            traverse(value as DesignTokens, currentPath);\n          }\n        }\n      }\n    };\n\n    traverse(tokens);\n    return colors;\n  }\n\n  /**\n   * Convert style name to token path\n   */\n  private styleNameToTokenPath(name: string): string {\n    return name.toLowerCase().replace(/\\s+/g, '.').replace(/[^a-z0-9.]/g, '');\n  }\n\n  /**\n   * Convert token path to style name\n   */\n  private tokenPathToStyleName(path: string): string {\n    return path\n      .split('.')\n      .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n      .join(' ');\n  }\n\n  /**\n   * Set nested value in object\n   */\n  private setNestedValue(obj: any, path: string, value: any): void {\n    const parts = path.split('.');\n    let current = obj;\n\n    for (let i = 0; i < parts.length - 1; i++) {\n      const part = parts[i];\n      if (!current[part]) {\n        current[part] = {};\n      }\n      current = current[part];\n    }\n\n    current[parts[parts.length - 1]] = value;\n  }\n}\n\n/**\n * Pull tokens from Figma\n */\nexport async function pullFromFigma(config: FigmaConfig): Promise<DesignTokens> {\n  const sync = new FigmaSync(config);\n  return sync.pullTokens();\n}\n\n/**\n * Push tokens to Figma\n */\nexport async function pushToFigma(tokensPath: string, config: FigmaConfig): Promise<void> {\n  const sync = new FigmaSync(config);\n  return sync.pushTokens(tokensPath);\n}\n\n"],"mappings":"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","names":["axios"]}