@frontfriend/tailwind 4.0.10 → 4.0.11

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,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../lib/core/constants.js", "../../../lib/core/errors.js", "../../../lib/core/file-utils.js", "../../../lib/core/path-utils.js", "../../../lib/core/local-token-reader.js", "../../../lib/core/credentials.js", "../../../lib/core/api-client.js", "../../../lib/core/component-downloader.js"],
4
- "sourcesContent": ["/**\n * Configuration constants for FrontFriend Tailwind v2\n */\n\n// API Configuration\nconst DEFAULT_API_URL = 'https://app.frontfriend.dev';\nconst LEGACY_API_URL = 'https://registry-legacy.frontfriend.dev';\n\n// Cache Configuration\nconst CACHE_DIR_NAME = '.cache/frontfriend';\nconst CACHE_TTL_DAYS = 7;\nconst CACHE_TTL_MS = CACHE_TTL_DAYS * 24 * 60 * 60 * 1000;\n\n// File names\nconst CACHE_FILES = {\n JS: [\n 'tokens.js',\n 'variables.js',\n 'semanticVariables.js',\n 'semanticDarkVariables.js',\n 'safelist.js',\n 'custom.js'\n ],\n JSON: [\n 'fonts.json',\n 'icons.json',\n 'components-config.json',\n 'version.json',\n 'metadata.json'\n ]\n};\n\n// Environment variables\nconst ENV_VARS = {\n FF_ID: 'FF_ID',\n FF_API_URL: 'FF_API_URL',\n FF_USE_LOCAL: 'FF_USE_LOCAL',\n FF_AUTH_TOKEN: 'FF_AUTH_TOKEN'\n};\n\nmodule.exports = {\n DEFAULT_API_URL,\n LEGACY_API_URL,\n CACHE_DIR_NAME,\n CACHE_TTL_DAYS,\n CACHE_TTL_MS,\n CACHE_FILES,\n ENV_VARS\n};", "class APIError extends Error {\n constructor(message, statusCode, url) {\n super(message);\n this.name = 'APIError';\n this.statusCode = statusCode;\n this.url = url;\n this.code = `API_${statusCode}`;\n }\n}\n\nclass CacheError extends Error {\n constructor(message, operation) {\n super(message);\n this.name = 'CacheError';\n this.operation = operation;\n this.code = `CACHE_${operation.toUpperCase()}`;\n }\n}\n\nclass ConfigError extends Error {\n constructor(message, field) {\n super(message);\n this.name = 'ConfigError';\n this.field = field;\n // `field` is optional; guard so a missing field never crashes (and masks)\n // the real error with `Cannot read properties of undefined (toUpperCase)`.\n this.code = field ? `CONFIG_${String(field).toUpperCase()}` : 'CONFIG_ERROR';\n }\n}\n\nclass ProcessingError extends Error {\n constructor(message, token) {\n super(message);\n this.name = 'ProcessingError';\n this.token = token;\n this.code = 'PROCESSING_ERROR';\n }\n}\n\nmodule.exports = {\n APIError,\n CacheError,\n ConfigError,\n ProcessingError\n};", "const fs = require('fs');\n\n/**\n * Read a JSON file safely, returning null if file doesn't exist\n * @param {string} filepath - Path to the JSON file\n * @returns {Object|null} Parsed JSON or null if file not found\n * @throws {Error} If JSON is invalid\n */\nfunction readJsonFileSafe(filepath) {\n try {\n const content = fs.readFileSync(filepath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n if (error.code === 'ENOENT') {\n return null; // File not found, return null like API would return 404\n }\n throw error;\n }\n}\n\n/**\n * Read a file safely, returning null if file doesn't exist\n * Strips UTF-8 BOM if present (fixes Windows compatibility)\n * @param {string} filepath - Path to the file\n * @returns {string|null} File content or null if file not found\n * @throws {Error} For other file system errors\n */\nfunction readFileSafe(filepath) {\n try {\n const content = fs.readFileSync(filepath, 'utf8');\n // Strip UTF-8 BOM if present (Windows compatibility)\n return content.replace(/^\\uFEFF/, '');\n } catch (error) {\n if (error.code === 'ENOENT') {\n return null; // File not found\n }\n throw error;\n }\n}\n\n/**\n * Write JSON data to a file with proper formatting\n * @param {string} filepath - Path to write the file\n * @param {Object} data - Data to write\n * @param {number} indent - Indentation level (default: 2)\n */\nfunction writeJsonFile(filepath, data, indent = 2) {\n const content = JSON.stringify(data, null, indent);\n fs.writeFileSync(filepath, content, 'utf8');\n}\n\n/**\n * Write plain text content to a file\n * @param {string} filepath - Path to write the file\n * @param {string} content - Text content to write\n */\nfunction writeTextFile(filepath, content) {\n fs.writeFileSync(filepath, content, 'utf8');\n}\n\n/**\n * Write module.exports file with JSON data\n * @param {string} filepath - Path to write the file\n * @param {Object} data - Data to export\n */\nfunction writeModuleExportsFile(filepath, data) {\n // Handle empty data cases\n if (data === null || data === undefined || \n (typeof data === 'object' && Object.keys(data).length === 0) ||\n (Array.isArray(data) && data.length === 0)) {\n const emptyContent = Array.isArray(data) ? '[]' : '{}';\n const content = `module.exports = ${emptyContent};`;\n fs.writeFileSync(filepath, content, 'utf8');\n } else {\n const content = `module.exports = ${JSON.stringify(data, null, 2)};`;\n fs.writeFileSync(filepath, content, 'utf8');\n }\n}\n\n/**\n * Check if a file exists\n * @param {string} filepath - Path to check\n * @returns {boolean} True if file exists\n */\nfunction fileExists(filepath) {\n return fs.existsSync(filepath);\n}\n\n/**\n * Create directory recursively\n * @param {string} dirpath - Directory path to create\n */\nfunction ensureDirectoryExists(dirpath) {\n fs.mkdirSync(dirpath, { recursive: true });\n}\n\n/**\n * Remove directory recursively\n * @param {string} dirpath - Directory path to remove\n */\nfunction removeDirectory(dirpath) {\n fs.rmSync(dirpath, { recursive: true, force: true });\n}\n\nmodule.exports = {\n readJsonFileSafe,\n readFileSafe,\n writeJsonFile,\n writeTextFile,\n writeModuleExportsFile,\n fileExists,\n ensureDirectoryExists,\n removeDirectory\n};\n", "const path = require('path');\nconst { fileExists } = require('./file-utils');\n\n/**\n * Find a file by traversing up the directory tree\n * @param {string} filename - Name of the file to find\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @returns {string|null} Full path to the file or null if not found\n */\nfunction findFileUpward(filename, startDir = process.cwd()) {\n let currentDir = startDir;\n \n while (currentDir !== path.parse(currentDir).root) {\n const filePath = path.join(currentDir, filename);\n \n if (fileExists(filePath)) {\n return filePath;\n }\n \n currentDir = path.dirname(currentDir);\n }\n \n return null;\n}\n\n/**\n * Find a directory by traversing up and checking multiple possible paths\n * @param {string} dirname - Name of the directory to find\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @param {Function} validator - Optional function to validate the directory\n * @returns {string|null} Full path to the directory or null if not found\n */\nfunction findDirectoryUpward(dirname, startDir = process.cwd(), validator = null) {\n const possiblePaths = [];\n let currentDir = startDir;\n const maxLevels = 10; // Prevent infinite loop\n \n // Build list of possible paths\n for (let i = 0; i < maxLevels; i++) {\n // Direct path\n possiblePaths.push(path.join(currentDir, dirname));\n \n // Relative paths up to 3 levels\n if (i < 3) {\n possiblePaths.push(path.join(currentDir, '../'.repeat(i + 1) + dirname));\n }\n \n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n \n // Also check from module directory (for when running from node_modules)\n possiblePaths.push(path.join(__dirname, '../../../', dirname));\n \n // Find first existing directory that passes validation\n for (const dirPath of possiblePaths) {\n if (fileExists(dirPath)) {\n if (!validator || validator(dirPath)) {\n return dirPath;\n }\n }\n }\n \n return null;\n}\n\n/**\n * Find a directory with multiple possible relative paths\n * @param {string[]} possiblePaths - Array of possible paths to check\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @returns {string|null} Full path to the directory or null if not found\n */\nfunction findDirectoryWithPaths(possiblePaths, startDir = process.cwd()) {\n // Build absolute paths from the start directory\n const absolutePaths = possiblePaths.map(p => {\n if (path.isAbsolute(p)) {\n return p;\n }\n return path.join(startDir, p);\n });\n \n // Find first existing path\n for (const dirPath of absolutePaths) {\n if (fileExists(dirPath)) {\n return dirPath;\n }\n }\n \n return null;\n}\n\nmodule.exports = {\n findFileUpward,\n findDirectoryUpward,\n findDirectoryWithPaths\n};", "const path = require('path');\nconst { findDirectoryUpward } = require('./path-utils');\nconst { readJsonFileSafe, readFileSafe, fileExists } = require('./file-utils');\n\n/**\n * LocalTokenReader - Reads tokens directly from the local file system\n * Mimics the APIClient interface but reads from apps/tokens directory\n */\nclass LocalTokenReader {\n constructor(ffId, options = {}) {\n this.ffId = ffId;\n this.tokensBasePath = options.tokensBasePath || this.findTokensPath();\n this.folderMap = this.loadFolderMap();\n this.projectFolder = this.folderMap[ffId];\n \n if (!this.projectFolder) {\n throw new Error(`No folder mapping found for ff-id: ${ffId}`);\n }\n \n this.projectPath = path.join(this.tokensBasePath, this.projectFolder);\n }\n\n /**\n * Find the tokens directory by looking for apps/tokens in parent directories\n */\n findTokensPath() {\n // Try to find apps/tokens first\n let tokensPath = findDirectoryUpward('apps/tokens', process.cwd(), (dir) => {\n return fileExists(path.join(dir, 'folderMap.json'));\n });\n \n // If not found, try just 'tokens'\n if (!tokensPath) {\n tokensPath = findDirectoryUpward('tokens', process.cwd(), (dir) => {\n return fileExists(path.join(dir, 'folderMap.json'));\n });\n }\n \n if (!tokensPath) {\n throw new Error('Could not find tokens directory with folderMap.json');\n }\n \n return tokensPath;\n }\n\n /**\n * Load the folder mapping from folderMap.json\n */\n loadFolderMap() {\n const folderMapPath = path.join(this.tokensBasePath, 'folderMap.json');\n const folderMap = readJsonFileSafe(folderMapPath);\n \n if (!folderMap) {\n throw new Error(`Failed to load folderMap.json: File not found`);\n }\n \n return folderMap;\n }\n\n /**\n * Fetch all token files (global, colors, semantic)\n * Mimics the APIClient.fetchTokens() method\n */\n async fetchTokens() {\n const figmaPath = path.join(this.projectPath, 'figma');\n \n // Try different possible paths for tokens\n const tokenPaths = {\n global: [\n path.join(figmaPath, 'Global Tokens', 'Default.json'),\n path.join(figmaPath, 'global.json')\n ],\n colors: [\n path.join(figmaPath, 'Global Colors', 'Default.json'),\n path.join(figmaPath, 'Global Colors', 'Light.json')\n ],\n semantic: [\n path.join(figmaPath, 'Semantic', 'Light.json'),\n path.join(figmaPath, 'Semantic', 'Default.json')\n ],\n semanticDark: [\n path.join(figmaPath, 'Semantic', 'Dark.json')\n ]\n };\n\n const results = {};\n \n // Try each possible path for each token type\n for (const [key, paths] of Object.entries(tokenPaths)) {\n for (const tokenPath of paths) {\n const content = readJsonFileSafe(tokenPath);\n if (content !== null) {\n results[key] = content;\n break; // Found it, no need to try other paths\n }\n }\n // If not found in any path, set to null\n if (!results[key]) {\n results[key] = null;\n }\n }\n\n return results;\n }\n\n /**\n * Fetch pre-processed tokens (if available in cache folder)\n */\n async fetchProcessedTokens() {\n const cachePath = path.join(this.projectPath, 'cache');\n \n if (!fileExists(cachePath)) {\n return null;\n }\n\n const parseModuleExports = (content) => {\n if (content === null) return null;\n\n const moduleExports = {};\n const fakeModule = { exports: moduleExports };\n const evalFunc = new Function('module', 'exports', content);\n evalFunc(fakeModule, moduleExports);\n return fakeModule.exports;\n };\n\n // Read all local cache files and normalize them to CacheManager.save() keys.\n const cacheFiles = {\n tokens: { fileName: 'hashedTokens.js', type: 'module' },\n variables: { fileName: 'hashedVariables.js', type: 'module' },\n semanticVariables: { fileName: 'hashedSemanticVariables.js', type: 'module' },\n semanticDarkVariables: { fileName: 'hashedSemanticDarkVariables.js', type: 'module' },\n safelist: { fileName: 'safelist.js', type: 'module' },\n custom: { fileName: 'custom.js', type: 'module' },\n fonts: { fileName: 'fonts.json', type: 'json' },\n icons: { fileName: 'icons.json', type: 'json' },\n componentsConfig: { fileName: 'encoded-config.json', type: 'json' },\n version: { fileName: 'version.json', type: 'json' }\n };\n\n const processedData = {};\n \n for (const [key, { fileName, type }] of Object.entries(cacheFiles)) {\n const filePath = path.join(cachePath, fileName);\n const value = type === 'module'\n ? parseModuleExports(readFileSafe(filePath))\n : readJsonFileSafe(filePath);\n\n if (value !== null) {\n processedData[key] = value;\n }\n }\n\n // Only return if we have at least some data\n const hasData = Object.values(processedData).some(val => val !== null);\n return hasData ? processedData : null;\n }\n\n /**\n * Fetch components configuration\n */\n async fetchComponentsConfig() {\n return readJsonFileSafe(path.join(this.projectPath, 'components-config.json'));\n }\n\n /**\n * Fetch fonts configuration\n */\n async fetchFonts() {\n return readJsonFileSafe(path.join(this.projectPath, 'font.json'));\n }\n\n /**\n * Fetch icons configuration\n */\n async fetchIcons() {\n return readJsonFileSafe(path.join(this.projectPath, 'icons.json'));\n }\n\n /**\n * Fetch version information\n */\n async fetchVersion() {\n return readJsonFileSafe(path.join(this.projectPath, 'version.json'));\n }\n\n /**\n * Fetch custom CSS\n */\n async fetchCustomCss() {\n return readFileSafe(path.join(this.projectPath, 'custom.css'));\n }\n\n /**\n * Fetch plan metadata\n */\n async fetchPlanMetadata() {\n const metadata = readJsonFileSafe(path.join(this.projectPath, 'metadata.json'));\n \n // Default to full plan if no metadata exists\n return metadata || {\n planType: 'full',\n allowedComponents: null\n };\n }\n\n // Compatibility methods to match APIClient interface\n fetchJson() {\n throw new Error('fetchJson is not implemented in LocalTokenReader. Use specific fetch methods.');\n }\n\n fetchRaw() {\n throw new Error('fetchRaw is not implemented in LocalTokenReader. Use specific fetch methods.');\n }\n}\n\nmodule.exports = { LocalTokenReader };\n", "const fs = require('fs');\nconst path = require('path');\nconst os = require('os');\nconst https = require('https');\nconst http = require('http');\nconst { URL } = require('url');\nconst { DEFAULT_API_URL } = require('./constants');\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), '.frontfriend');\nconst CREDENTIALS_PATH = path.join(CREDENTIALS_DIR, 'credentials');\n\nfunction getCredentialsPath() {\n return CREDENTIALS_PATH;\n}\n\nfunction readCredentials() {\n try {\n if (!fs.existsSync(CREDENTIALS_PATH)) return null;\n return JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf8'));\n } catch {\n return null;\n }\n}\n\nfunction writeCredentials(credentials) {\n fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });\n fs.writeFileSync(CREDENTIALS_PATH, `${JSON.stringify(credentials, null, 2)}\\n`, { mode: 0o600 });\n try {\n fs.chmodSync(CREDENTIALS_PATH, 0o600);\n } catch {\n // Best effort on platforms that do not support chmod.\n }\n}\n\nfunction deleteCredentials() {\n if (fs.existsSync(CREDENTIALS_PATH)) {\n fs.unlinkSync(CREDENTIALS_PATH);\n return true;\n }\n return false;\n}\n\nfunction isExpired(credentials, skewMs = 60 * 1000) {\n return !credentials?.accessToken || !credentials.expiresAt || Date.now() + skewMs >= credentials.expiresAt;\n}\n\nfunction createAuthRefreshError(message) {\n const error = new Error(`${message}. Run \\`frontfriend login\\` to re-authenticate.`);\n error.code = 'FF_AUTH_REFRESH_FAILED';\n return error;\n}\n\nfunction postJson(url, body, authToken) {\n return new Promise((resolve, reject) => {\n const parsedUrl = new URL(url);\n const protocol = parsedUrl.protocol === 'https:' ? https : http;\n const payload = JSON.stringify(body || {});\n const request = protocol.request({\n hostname: parsedUrl.hostname,\n port: parsedUrl.port,\n path: `${parsedUrl.pathname}${parsedUrl.search}`,\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n ...(authToken ? { authorization: `Bearer ${authToken}` } : {}),\n },\n }, response => {\n let data = '';\n response.on('data', chunk => { data += chunk; });\n response.on('end', () => {\n if (response.statusCode >= 300 && response.statusCode < 400) {\n const redirectUrl = response.headers.location ? ` to ${response.headers.location}` : '';\n const error = new Error(`HTTP ${response.statusCode}: redirected${redirectUrl}`);\n error.statusCode = response.statusCode;\n error.body = data;\n reject(error);\n return;\n }\n\n let parsed = null;\n try {\n parsed = data ? JSON.parse(data) : null;\n } catch (error) {\n if (response.statusCode >= 400) {\n const httpError = new Error(`HTTP ${response.statusCode}: ${response.statusMessage || 'Non-JSON response'}`);\n httpError.statusCode = response.statusCode;\n httpError.body = data;\n reject(httpError);\n return;\n }\n reject(error);\n return;\n }\n if (response.statusCode >= 400) {\n const error = new Error(parsed?.error_description || parsed?.error || `HTTP ${response.statusCode}`);\n error.statusCode = response.statusCode;\n error.body = parsed;\n reject(error);\n return;\n }\n resolve(parsed);\n });\n });\n request.on('error', reject);\n request.write(payload);\n request.end();\n });\n}\n\nasync function refreshCredentials(credentials, baseURL = DEFAULT_API_URL) {\n if (!credentials?.refreshToken || !credentials?.deviceId) {\n throw createAuthRefreshError('FrontFriend session expired');\n }\n\n let response;\n try {\n response = await postJson(`${baseURL}/api/plugin/token`, {\n grant_type: 'refresh_token',\n refresh_token: credentials.refreshToken,\n device_id: credentials.deviceId,\n });\n } catch (error) {\n throw createAuthRefreshError(error?.message || 'Could not refresh FrontFriend session');\n }\n\n if (!response?.access_token || !response?.refresh_token) {\n throw createAuthRefreshError('Could not refresh FrontFriend session');\n }\n\n const refreshed = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token,\n deviceId: response.device_id || credentials.deviceId,\n expiresAt: Date.now() + (response.expires_in || 900) * 1000,\n refreshExpiresAt: Date.now() + (response.refresh_expires_in || 604800) * 1000,\n ffApiUrl: baseURL,\n };\n writeCredentials(refreshed);\n return refreshed;\n}\n\nasync function resolveAuthToken(options = {}) {\n if (!options.skipCredentials) {\n const credentials = readCredentials();\n if (credentials?.accessToken || credentials?.refreshToken) {\n const baseURL = options.baseURL || credentials.ffApiUrl || DEFAULT_API_URL;\n if (credentials.accessToken && !isExpired(credentials)) {\n return credentials.accessToken;\n }\n const refreshed = await refreshCredentials(credentials, baseURL);\n return refreshed.accessToken;\n }\n }\n\n if (options.envToken) return options.envToken;\n if (options.legacyToken) {\n if (!options.silent) {\n console.warn('\u26A0\uFE0F auth-token in frontfriend.config.js is deprecated. Run `frontfriend login` to store credentials outside the repo.');\n }\n return options.legacyToken;\n }\n return null;\n}\n\nmodule.exports = {\n getCredentialsPath,\n readCredentials,\n writeCredentials,\n deleteCredentials,\n isExpired,\n postJson,\n refreshCredentials,\n resolveAuthToken,\n createAuthRefreshError,\n};\n", "const https = require('https');\nconst http = require('http');\nconst { URL } = require('url');\nconst { DEFAULT_API_URL, LEGACY_API_URL, ENV_VARS } = require('./constants');\nconst { APIError } = require('./errors');\nconst { LocalTokenReader } = require('./local-token-reader');\nconst { resolveAuthToken } = require('./credentials');\n\nconst AUTH_REQUIRED_MESSAGE = 'Authentication required. Run `frontfriend login` to re-authenticate.';\n\nfunction getWithOptionalAuth(protocol, url, authToken, callback) {\n if (authToken) {\n return protocol.get(new URL(url), {\n headers: { authorization: `Bearer ${authToken}` },\n }, callback);\n }\n\n return protocol.get(url, callback);\n}\n\nfunction isAuthRedirect(response, body = '') {\n const location = response.headers?.location || '';\n return (\n response.statusCode === 401 ||\n response.statusCode === 403 ||\n (response.statusCode >= 300 && response.statusCode < 400 && location.includes('/sign-in')) ||\n String(body).trim().startsWith('/sign-in')\n );\n}\n\nfunction createHttpError(response, url, body = '') {\n if (isAuthRedirect(response, body)) {\n return new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url);\n }\n return new APIError(\n `HTTP ${response.statusCode}: ${response.statusMessage}`,\n response.statusCode,\n url\n );\n}\n\nclass APIClient {\n constructor(ffId, options = {}) {\n this.ffId = ffId;\n this.baseURL = options.baseURL || process.env[ENV_VARS.FF_API_URL] || DEFAULT_API_URL;\n this.legacyAuthToken = options.authToken || null;\n this.authToken = null;\n this.skipCredentials = options.skipCredentials || false;\n \n // Check if we should use local token reader\n if (process.env[ENV_VARS.FF_USE_LOCAL] === 'true') {\n console.log(' \uD83C\uDFE0 Using local token reader');\n this.localReader = new LocalTokenReader(ffId, options);\n }\n }\n\n /**\n * Fetch JSON data from a URL using native https module\n * @param {string} url - The URL to fetch\n * @param {Object} options - Fetch options\n * @param {boolean} options.returnHeaders - If true, return {data, headers} object\n * @returns {Promise<any>} Parsed JSON data or {data, headers} if returnHeaders is true\n */\n async getAuthToken() {\n this.authToken = await resolveAuthToken({\n baseURL: this.baseURL,\n envToken: process.env[ENV_VARS.FF_AUTH_TOKEN],\n legacyToken: this.legacyAuthToken,\n skipCredentials: this.skipCredentials,\n });\n return this.authToken;\n }\n\n async fetchJson(url, options = {}) {\n const authToken = await this.getAuthToken();\n return new Promise((resolve, reject) => {\n // Determine if we should use http or https\n const protocol = url.startsWith('https') ? https : http;\n\n getWithOptionalAuth(protocol, url, authToken, (response) => {\n let data = '';\n\n // Check for HTTP errors and redirects before waiting for a body. Some\n // tests and intermediaries do not send one.\n if (response.statusCode >= 300) {\n reject(createHttpError(response, url));\n return;\n }\n\n // Collect response chunks\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n // Parse JSON when complete\n response.on('end', () => {\n try {\n const parsed = JSON.parse(data);\n\n // Return headers if requested\n if (options.returnHeaders) {\n resolve({\n data: parsed,\n headers: response.headers\n });\n } else {\n resolve(parsed);\n }\n } catch (error) {\n if (isAuthRedirect(response, data)) {\n reject(new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url));\n return;\n }\n reject(new APIError(\n `Invalid JSON response: ${error.message}`,\n response.statusCode,\n url\n ));\n }\n });\n\n // Handle response errors\n response.on('error', (error) => {\n reject(new APIError(\n `Response error: ${error.message}`,\n response.statusCode,\n url\n ));\n });\n }).on('error', (error) => {\n // Handle network errors\n reject(new APIError(\n `Network error: ${error.message}`,\n 0,\n url\n ));\n });\n });\n }\n\n /**\n * Fetch raw content from a URL\n * @param {string} url - The URL to fetch\n * @returns {Promise<string>} Raw text content\n */\n async fetchRaw(url) {\n const authToken = await this.getAuthToken();\n return new Promise((resolve, reject) => {\n // Determine if we should use http or https\n const protocol = url.startsWith('https') ? https : http;\n \n getWithOptionalAuth(protocol, url, authToken, (response) => {\n let data = '';\n \n // Check for HTTP errors\n if (response.statusCode >= 400) {\n reject(new APIError(\n `HTTP ${response.statusCode}: ${response.statusMessage}`,\n response.statusCode,\n url\n ));\n return;\n }\n\n // Collect response chunks\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n // Return raw data when complete\n response.on('end', () => {\n resolve(data);\n });\n\n // Handle response errors\n response.on('error', (error) => {\n reject(new APIError(\n `Response error: ${error.message}`,\n response.statusCode,\n url\n ));\n });\n }).on('error', (error) => {\n // Handle network errors\n reject(new APIError(\n `Network error: ${error.message}`,\n 0,\n url\n ));\n });\n });\n }\n\n /**\n * Fetch all token files (global, colors, semantic)\n * @returns {Promise<Object>} Object with all token data\n */\n async fetchTokens() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchTokens();\n }\n \n // First try the new design system endpoint\n try {\n const designSystemUrl = `${this.baseURL}/api/design-systems/${this.ffId}/tokens`;\n const tokensData = await this.fetchJson(designSystemUrl);\n \n // If we have the new format, parse it\n if (tokensData && tokensData.tokens) {\n const tokens = tokensData.tokens;\n \n // Extract specific token sets from the new format\n return {\n global: tokens['Global Tokens/Default'] || tokens['global'] || null,\n colors: tokens['Global Colors/Default'] || tokens['colors'] || null,\n semantic: tokens['Semantic/Light'] || tokens['semantic/light'] || null,\n semanticDark: tokens['Semantic/Dark'] || tokens['semantic/dark'] || null\n };\n }\n } catch (err) {\n // If design system is not synced (400 error), throw with clear message\n if (err.statusCode === 400) {\n throw new APIError(\n 'Design system not synced with Figma. Please sync tokens from Figma before using this design system.',\n 400,\n `${this.baseURL}/api/design-systems/${this.ffId}/tokens`\n );\n }\n // Failed to fetch from design system endpoint, falling back to legacy URLs\n }\n \n // Fall back to legacy token URLs\n // Use legacy API URL for backward compatibility\n const legacyBaseURL = LEGACY_API_URL;\n const urls = {\n global: `${legacyBaseURL}/${this.ffId}/global-tokens/default.json`,\n colors: `${legacyBaseURL}/${this.ffId}/global-colors/default.json`,\n semantic: `${legacyBaseURL}/${this.ffId}/semantic/light.json`,\n semanticDark: `${legacyBaseURL}/${this.ffId}/semantic/dark.json`\n };\n\n const results = await Promise.all([\n this.fetchJson(urls.global).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.colors).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.semantic).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.semanticDark).catch(err => err.statusCode === 404 ? null : Promise.reject(err))\n ]);\n\n return {\n global: results[0],\n colors: results[1],\n semantic: results[2],\n semanticDark: results[3]\n };\n }\n\n /**\n * Fetch pre-processed tokens from the design system endpoint\n * @param {Object} options - Fetch options\n * @param {string} options.tag - Tag name (e.g., 'dev', 'next', 'latest')\n * @param {string} options.version - Version label (e.g., 'v1.0.0')\n * @param {boolean} options.tailwindV4 - Request OKLCH/v4 color encoding so\n * generated utilities reference variables without an hsl() wrapper (#421)\n * @returns {Promise<Object|null>} Processed tokens ready for caching with metadata or null if not found\n */\n async fetchProcessedTokens(options = {}) {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchProcessedTokens();\n }\n\n // Build URL with optional query parameters\n const url = new URL(`${this.baseURL}/api/design-systems/${this.ffId}/processed-tokens`);\n if (options.tag) {\n url.searchParams.append('tag', options.tag);\n }\n if (options.version) {\n url.searchParams.append('version', options.version);\n }\n if (options.tailwindV4) {\n // Tailwind v4 consumers need OKLCH-encoded variables so the generated\n // @utility rules can reference them directly. See issue #421.\n url.searchParams.append('tailwind', 'v4');\n }\n\n const processedUrl = url.toString();\n\n try {\n const result = await this.fetchJson(processedUrl, { returnHeaders: true });\n\n // Attach version metadata from response headers\n if (result.headers) {\n result.data.versionMetadata = {\n version: result.headers['x-frontfriend-version'],\n tag: result.headers['x-frontfriend-tag'],\n cached: result.headers['x-frontfriend-cached'] === 'true'\n };\n }\n\n return result.data;\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n // If design system is not synced (400 error), throw with clear message\n if (error.statusCode === 400) {\n throw new APIError(\n 'Design system not synced with Figma. Please sync tokens from Figma before using this design system.',\n 400,\n processedUrl\n );\n }\n throw error;\n }\n }\n\n\n\n /**\n * Send JSON data to a URL using native http/https modules.\n * @param {string} url - The URL to send to\n * @param {string} method - HTTP method\n * @param {Object} body - JSON body\n * @returns {Promise<any>} Parsed JSON response or null for empty response\n */\n async sendJson(url, method, body) {\n const authToken = await this.getAuthToken();\n if (!authToken) {\n throw new APIError(AUTH_REQUIRED_MESSAGE, 401, url);\n }\n\n return new Promise((resolve, reject) => {\n const parsedUrl = new URL(url);\n const protocol = url.startsWith('https') ? https : http;\n const payload = JSON.stringify(body || {});\n const request = protocol.request({\n hostname: parsedUrl.hostname,\n port: parsedUrl.port,\n path: `${parsedUrl.pathname}${parsedUrl.search}`,\n method,\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n ...(authToken ? { authorization: `Bearer ${authToken}` } : {}),\n },\n }, (response) => {\n let data = '';\n if (response.statusCode >= 300) {\n reject(createHttpError(response, url));\n return;\n }\n\n response.on('data', chunk => { data += chunk; });\n response.on('end', () => {\n if (!data) {\n resolve(null);\n return;\n }\n try {\n resolve(JSON.parse(data));\n } catch (error) {\n if (isAuthRedirect(response, data)) {\n reject(new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url));\n return;\n }\n reject(new APIError(\n `Invalid JSON response: ${error.message}`,\n response.statusCode,\n url\n ));\n }\n });\n });\n request.on('error', error => {\n reject(new APIError(`Network error: ${error.message}`, 0, url));\n });\n request.write(payload);\n request.end();\n });\n }\n\n /**\n * Push migrated component config to the cloud as a user override.\n * @param {Object} componentsConfig - FF-canonical component config\n * @returns {Promise<any>}\n */\n async pushComponentsConfig(componentsConfig) {\n const url = `${this.baseURL}/api/design-systems/${this.ffId}/components-config`;\n return this.sendJson(url, 'PUT', { componentsConfig });\n }\n\n\n /**\n * Fetch components configuration\n * @returns {Promise<Object|null>} Components config or null if not found\n */\n async fetchComponentsConfig() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchComponentsConfig();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/components-config.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch fonts configuration\n * @returns {Promise<Object|null>} Fonts object with font1, font2, etc. URLs or null\n */\n async fetchFonts() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchFonts();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/font.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch icons configuration\n * @returns {Promise<Object|null>} Icons data or null if not found\n */\n async fetchIcons() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchIcons();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/icons.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch version information\n * @returns {Promise<Object|null>} Version data or null if not found\n */\n async fetchVersion() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchVersion();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/version.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch custom CSS\n * @returns {Promise<string|null>} Custom CSS string or null if not found\n */\n async fetchCustomCss() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchCustomCss();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/custom.css`;\n try {\n return await this.fetchRaw(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch plan metadata (plan type and allowed components)\n * @returns {Promise<Object|null>} Plan metadata or null if not found\n */\n async fetchPlanMetadata() {\n // Use local reader if available\n if (this.localReader) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 Using local reader for plan metadata');\n }\n return this.localReader.fetchPlanMetadata();\n }\n \n // First try the saas app (processed-tokens endpoint) - this is the authoritative source\n const processedUrl = `${this.baseURL}/api/design-systems/${this.ffId}/processed-tokens`;\n try {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching plan metadata from saas app: ${processedUrl}`);\n }\n \n const processedData = await this.fetchJson(processedUrl);\n \n // Extract metadata from processed tokens response\n if (processedData && processedData.metadata) {\n const metadata = {\n planType: processedData.metadata.planType || 'full',\n allowedComponents: processedData.metadata.allowedComponents || null\n };\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found plan metadata in saas app: ${metadata.planType}, allowed: ${metadata.allowedComponents ? metadata.allowedComponents.length + ' components' : 'all'}`);\n }\n \n return metadata;\n }\n } catch (saasError) {\n // If not found in saas app, try legacy server\n if (saasError.statusCode === 404) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 ff-id not found in saas app, trying legacy server');\n }\n \n // Try legacy tokens server (these are always full plan - no trial concept)\n const tokensUrl = `${LEGACY_API_URL}/${this.ffId}/metadata`;\n try {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching from legacy server: ${tokensUrl}`);\n }\n const legacyMetadata = await this.fetchJson(tokensUrl);\n \n // Use the plan metadata from legacy server if available\n const metadata = {\n planType: legacyMetadata.planType || 'full',\n allowedComponents: legacyMetadata.allowedComponents || null\n };\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found in legacy server: ${metadata.planType}, allowed: ${metadata.allowedComponents ? metadata.allowedComponents.length + ' components' : 'all'}`);\n }\n \n return metadata;\n } catch (legacyError) {\n if (legacyError.statusCode === 404) {\n // Not found in either place - DENY access\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 ff-id not found in any server - access denied');\n }\n \n // Return a denied plan type instead of defaulting to full\n return {\n planType: 'denied',\n allowedComponents: [],\n error: 'Design system not found. Please ensure your ff-id is valid.'\n };\n }\n throw legacyError;\n }\n }\n throw saasError;\n }\n }\n}\n\nmodule.exports = { APIClient };\n", "const https = require('https');\nconst http = require('http');\nconst fs = require('fs');\nconst path = require('path');\nconst { URL } = require('url');\nconst os = require('os');\n\nconst DEFAULT_REGISTRY_URL = 'https://registry.frontfriend.dev';\nconst SUPPORTED_REGISTRY_GENERATIONS = ['legacy', 'v4'];\n\nclass ComponentDownloader {\n constructor(options = {}) {\n this.appRoot = options.appRoot || process.cwd();\n this.framework = options.framework || this.detectFramework();\n this.config = options.config || {};\n this.registryGeneration = this.resolveRegistryGeneration(options.registryGeneration);\n this.outputPath = options.outputPath || this.getDefaultOutputPath();\n this.overwrite = options.overwrite || false;\n this.downloadedComponents = new Set();\n this.downloadingComponents = new Set();\n this.ffId = this.config.ffId || this.config['ff-id'] || null;\n this.registryUrl = this.resolveRegistryUrl(options.registryUrl);\n this.planMetadata = null; // Will be populated when needed\n }\n\n resolveRegistryUrl(override) {\n const registryConfig = this.config.registry;\n const configuredUrl =\n this.config.registryUrl ||\n this.config.registryBaseUrl ||\n (typeof registryConfig === 'object' ? registryConfig.url || registryConfig.baseUrl : undefined);\n\n return (override || configuredUrl || process.env.FF_REGISTRY_URL || DEFAULT_REGISTRY_URL).replace(/\\/+$/, '');\n }\n\n /**\n * Resolve registry generation with precedence:\n * CLI option > frontfriend config > Tailwind version auto-detection > legacy.\n */\n resolveRegistryGeneration(cliGeneration) {\n const registryConfig = this.config.registry;\n const configuredGeneration =\n this.config.registryGeneration ||\n this.config.registryVersion ||\n (typeof registryConfig === 'string' ? registryConfig : registryConfig?.generation || registryConfig?.version);\n\n return this.normalizeRegistryGeneration(\n cliGeneration || configuredGeneration || (this.detectTailwindV4() ? 'v4' : 'legacy')\n );\n }\n\n normalizeRegistryGeneration(value) {\n if (value === undefined || value === null || value === '') {\n return 'legacy';\n }\n\n if (value === 'v4' || value === 4 || value === '4') {\n return 'v4';\n }\n\n if (value === 'legacy') {\n return 'legacy';\n }\n\n throw new Error(\n `Unsupported registry generation \"${value}\". Supported generations: ${SUPPORTED_REGISTRY_GENERATIONS.join(', ')}.`\n );\n }\n\n readPackageJson() {\n const packageJsonPath = path.join(this.appRoot, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n } catch (error) {\n return null;\n }\n }\n\n getDependencyVersion(packageName) {\n const packageJson = this.readPackageJson();\n\n return (\n packageJson?.dependencies?.[packageName] ||\n packageJson?.devDependencies?.[packageName] ||\n packageJson?.peerDependencies?.[packageName] ||\n null\n );\n }\n\n getDependencyMajorVersion(packageName) {\n const version = this.getDependencyVersion(packageName);\n const majorVersion = version?.match(/(\\d+)/)?.[1];\n\n return majorVersion ? Number(majorVersion) : null;\n }\n\n validateRuntimeCompatibility() {\n if (this.framework !== 'react') {\n return;\n }\n\n const reactVersion = this.getDependencyVersion('react');\n const reactMajorVersion = this.getDependencyMajorVersion('react');\n\n if (!reactVersion || !reactMajorVersion) {\n return;\n }\n\n if (this.registryGeneration === 'v4' && reactMajorVersion < 19) {\n throw new Error(`Tailwind v4 React registry requires React 19; found react ${reactVersion}`);\n }\n\n if (this.registryGeneration === 'legacy' && reactMajorVersion >= 19) {\n throw new Error(\n `Legacy React registry targets React 18; found react ${reactVersion}. Use --registry v4 for React 19 projects.`\n );\n }\n }\n\n /**\n * Detect Tailwind v4 from the consuming app's package.json.\n */\n detectTailwindV4() {\n const tailwindMajorVersion = this.getDependencyMajorVersion('tailwindcss');\n\n return tailwindMajorVersion ? tailwindMajorVersion >= 4 : false;\n }\n\n /**\n * Build registry endpoint URLs for the selected generation.\n */\n getRegistryUrl(componentName, { custom = false, index = false } = {}) {\n const filename = index ? 'index.json' : `${componentName}.json`;\n\n if (custom) {\n if (this.registryGeneration === 'v4') {\n return `${this.registryUrl}/custom/v4/${this.ffId}/${this.framework}/${filename}`;\n }\n\n return `${this.registryUrl}/custom/${this.ffId}/${this.framework}/${filename}`;\n }\n\n if (this.registryGeneration === 'v4') {\n return `${this.registryUrl}/components/v4/${this.framework}/${filename}`;\n }\n\n return `${this.registryUrl}/components/${this.framework}/${filename}`;\n }\n\n /**\n * Normalize shadcn-compatible registry dependency URLs back to component\n * names for the Frontfriend downloader. Frontfriend dependency resolution\n * still uses same-generation custom-first fallback via downloadComponent().\n */\n getRegistryDependencyName(dependency) {\n if (typeof dependency !== 'string') {\n return dependency;\n }\n\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(dependency)) {\n return dependency;\n }\n\n try {\n const parsedUrl = new URL(dependency);\n const registryUrl = new URL(this.registryUrl);\n\n if (parsedUrl.origin !== registryUrl.origin) {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Only Frontfriend registry URLs are supported by this downloader.`\n );\n }\n\n const routeParts = parsedUrl.pathname\n .split('/')\n .filter(Boolean)\n .map(part => decodeURIComponent(part));\n let dependencyGeneration;\n let dependencyFramework;\n let dependencyFfId;\n let fileName;\n\n if (routeParts[0] !== 'r') {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Expected a Frontfriend /r/{generation}/{framework}/{component}.json route.`\n );\n }\n\n if (routeParts[2] === 'custom') {\n [, dependencyGeneration, , dependencyFfId, dependencyFramework, fileName] = routeParts;\n } else {\n [, dependencyGeneration, dependencyFramework, fileName] = routeParts;\n }\n\n if (!dependencyGeneration || !dependencyFramework || !fileName || !fileName.endsWith('.json')) {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Expected a Frontfriend /r/{generation}/{framework}/{component}.json route.`\n );\n }\n\n if (dependencyGeneration !== this.registryGeneration) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets generation \"${dependencyGeneration}\" but downloader is using \"${this.registryGeneration}\".`\n );\n }\n\n if (dependencyFramework !== this.framework) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets framework \"${dependencyFramework}\" but downloader is using \"${this.framework}\".`\n );\n }\n\n if (dependencyFfId && dependencyFfId !== this.ffId) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets ff-id \"${dependencyFfId}\" but downloader is using \"${this.ffId || 'none'}\".`\n );\n }\n\n return fileName.endsWith('.json')\n ? fileName.slice(0, -'.json'.length)\n : fileName;\n } catch (error) {\n if (\n error.message.startsWith('Unsupported registry dependency URL') ||\n error.message.startsWith('Registry dependency URL')\n ) {\n throw error;\n }\n\n return dependency;\n }\n }\n\n /**\n * Detect framework from package.json\n */\n detectFramework() {\n const packageJsonPath = path.join(this.appRoot, 'package.json');\n \n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (deps.vue) {\n return 'vue';\n } else if (deps.react) {\n return 'react';\n }\n }\n \n // Default to React if can't detect\n return 'react';\n }\n\n /**\n * Get default output path based on framework and config\n */\n getDefaultOutputPath() {\n // Check if config has ui alias\n if (this.config.aliases && this.config.aliases.ui) {\n const uiAlias = this.config.aliases.ui;\n // Convert alias to actual path (e.g., @/components/ui -> components/ui)\n const cleanPath = uiAlias.replace(/^@\\//, '');\n return path.join(this.appRoot, cleanPath);\n }\n \n // Fallback to default paths\n if (this.framework === 'vue') {\n return path.join(this.appRoot, 'src/components/ui');\n }\n return path.join(this.appRoot, 'components/ui');\n }\n\n /**\n * Fetch JSON from URL or local file\n */\n fetchJson(url) {\n // Check if using local mode at runtime\n // FF_USE_LOCAL: affects both tokens and components\n // FF_USE_LOCAL_REGISTRY: affects only components (for registry URLs)\n const USE_LOCAL = process.env.FF_USE_LOCAL === 'true';\n const USE_LOCAL_REGISTRY = process.env.FF_USE_LOCAL_REGISTRY === 'true';\n \n // Check if this is a registry URL\n const isRegistryUrl = url.includes(this.registryUrl);\n \n // Use local file system if:\n // 1. FF_USE_LOCAL is set (affects everything), OR\n // 2. FF_USE_LOCAL_REGISTRY is set AND this is a registry URL\n if (USE_LOCAL || (USE_LOCAL_REGISTRY && isRegistryUrl)) {\n if (process.env.FF_DEBUG && USE_LOCAL_REGISTRY && !USE_LOCAL) {\n console.log(' \u2192 Using local registry for components');\n }\n \n // Try multiple paths to find the registry\n const possiblePaths = [\n '../../packages/registry',\n '../../../packages/registry',\n '../../../../packages/registry',\n path.join(__dirname, '../../../registry'),\n 'packages/registry'\n ];\n \n let registryPath;\n for (const p of possiblePaths) {\n const fullPath = path.isAbsolute(p) ? p : path.join(process.cwd(), p);\n if (fs.existsSync(fullPath)) {\n registryPath = fullPath;\n break;\n }\n }\n \n if (!registryPath) {\n return Promise.reject(new Error(`Local registry not found. Tried paths: ${possiblePaths.join(', ')}`));\n }\n \n // Extract the path from the URL and construct proper local path\n const urlPath = url.replace(this.registryUrl, '').replace(/^\\//, '');\n const localPath = path.join(registryPath, ...urlPath.split('/'));\n \n try {\n const content = fs.readFileSync(localPath, 'utf8');\n return Promise.resolve(JSON.parse(content));\n } catch (error) {\n if (error.code === 'ENOENT') {\n return Promise.reject(new Error('HTTP 404: Not Found'));\n }\n return Promise.reject(error);\n }\n }\n\n return new Promise((resolve, reject) => {\n const client = new URL(url).protocol === 'http:' ? http : https;\n client.get(url, (response) => {\n let data = '';\n\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n response.on('end', () => {\n if (response.statusCode >= 400) {\n let errorMessage = response.statusMessage;\n\n try {\n const errorBody = JSON.parse(data);\n errorMessage = errorBody.error || errorBody.message || errorMessage;\n } catch (error) {\n // Keep the HTTP status text if the registry did not return JSON.\n }\n\n reject(new Error(`HTTP ${response.statusCode}: ${errorMessage}`));\n return;\n }\n\n try {\n resolve(JSON.parse(data));\n } catch (error) {\n reject(new Error(`Invalid JSON response: ${error.message}`));\n }\n });\n\n }).on('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Get all available components from registry\n */\n async getAllComponents() {\n this.validateRuntimeCompatibility();\n\n try {\n const url = this.getRegistryUrl(null, { index: true });\n const index = await this.fetchJson(url);\n let components = index.components || [];\n \n // Filter components based on plan\n if (this.ffId) {\n // Ensure plan metadata is loaded\n try {\n await this.isComponentAllowed('dummy'); // This will load metadata\n } catch (error) {\n // If access is denied, throw error\n if (this.planMetadata && this.planMetadata.planType === 'denied') {\n throw new Error(this.planMetadata.error || 'Access denied. Your ff-id was not found in any server.');\n }\n }\n \n if (this.planMetadata && this.planMetadata.planType === 'trial' && this.planMetadata.allowedComponents) {\n components = components.filter(comp => this.planMetadata.allowedComponents.includes(comp));\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Trial plan: filtering to ${components.length} allowed components`);\n }\n }\n }\n \n return components;\n } catch (error) {\n if (error.message.includes('404') && this.registryGeneration === 'v4') {\n throw new Error(`Tailwind v4 registry not available for ${this.framework}`);\n }\n\n if (this.planMetadata?.planType === 'denied' || error.message.startsWith('Access denied.')) {\n throw error;\n }\n\n throw new Error(`Failed to fetch component index: ${error.message}`);\n }\n }\n\n /**\n * Get all custom components for this ff-id\n */\n async getCustomComponents() {\n if (!this.ffId) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 No ff-id found, skipping custom components');\n }\n return [];\n }\n\n this.validateRuntimeCompatibility();\n \n try {\n const url = this.getRegistryUrl(null, { custom: true, index: true });\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching custom components from: ${url}`);\n }\n const index = await this.fetchJson(url);\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found custom components: ${JSON.stringify(index.components)}`);\n }\n return index.components || [];\n } catch (error) {\n // Custom components might not exist, that's ok\n if (!error.message.includes('404')) {\n throw new Error(`Failed to fetch custom component index: ${error.message}`);\n }\n\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 No custom components found: ${error.message}`);\n }\n return [];\n }\n }\n\n /**\n * Download multiple components\n */\n async downloadComponents(components) {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 ComponentDownloader initialized with ff-id: ${this.ffId}`);\n }\n \n const results = {\n successful: [],\n failed: [],\n dependencies: new Set()\n };\n\n for (const component of components) {\n try {\n const deps = await this.downloadComponent(component);\n results.successful.push(component);\n \n // Add dependencies\n deps.forEach(dep => results.dependencies.add(dep));\n } catch (error) {\n results.failed.push({\n component,\n error: error.message\n });\n }\n }\n\n return {\n successful: results.successful,\n failed: results.failed,\n dependencies: Array.from(results.dependencies)\n };\n }\n\n /**\n * Check if component is allowed based on plan\n */\n async isComponentAllowed(componentName) {\n // Fetch plan metadata if not already loaded\n if (!this.planMetadata && this.ffId) {\n const { APIClient } = require('./api-client');\n const apiClient = new APIClient(this.ffId, {\n baseURL: this.config['api-url'] || this.config.apiUrl\n });\n try {\n this.planMetadata = await apiClient.fetchPlanMetadata();\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetched plan metadata: ${this.planMetadata.planType}, allowed: ${this.planMetadata.allowedComponents ? this.planMetadata.allowedComponents.length + ' components' : 'all'}`);\n }\n } catch (error) {\n console.warn('Failed to fetch plan metadata:', error.message);\n // Default to full plan if we can't fetch metadata\n this.planMetadata = { planType: 'full', allowedComponents: null };\n }\n }\n\n // Handle denied plan (ff-id not found anywhere)\n if (this.planMetadata && this.planMetadata.planType === 'denied') {\n throw new Error(this.planMetadata.error || 'Access denied. Your ff-id was not found in any server.');\n }\n \n // If full plan or no metadata, allow all components\n if (!this.planMetadata || this.planMetadata.planType === 'full') {\n return true;\n }\n\n // For trial plan, check if component is in allowed list\n if (this.planMetadata.planType === 'trial' && this.planMetadata.allowedComponents) {\n return this.planMetadata.allowedComponents.includes(componentName);\n }\n\n // Default to denying if we can't determine (safer)\n return false;\n }\n\n /**\n * Download a single component and its registry dependencies\n */\n async downloadComponent(componentName) {\n this.validateRuntimeCompatibility();\n\n // Avoid downloading the same component twice\n if (this.downloadedComponents.has(componentName)) {\n return [];\n }\n\n if (this.downloadingComponents.has(componentName)) {\n throw new Error(`Circular registry dependency detected while downloading \"${componentName}\"`);\n }\n\n this.downloadingComponents.add(componentName);\n\n try {\n return await this.downloadComponentInternal(componentName);\n } finally {\n this.downloadingComponents.delete(componentName);\n }\n }\n\n async downloadComponentInternal(componentName) {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Checking if component \"${componentName}\" is allowed...`);\n console.log(` \u2192 FF-ID: ${this.ffId}`);\n }\n\n // Check if component is allowed based on plan\n const isAllowed = await this.isComponentAllowed(componentName);\n if (!isAllowed) {\n const errorMsg = `Component \"${componentName}\" is not available in your trial plan. Please upgrade to access all components.`;\n console.error(`\u274C ${errorMsg}`);\n throw new Error(errorMsg);\n }\n\n console.log(`\uD83D\uDCE5 Downloading ${componentName}...`);\n\n // Try to fetch from custom components first if ff-id is available\n let componentData;\n let isCustom = false;\n \n if (this.ffId) {\n const customUrl = this.getRegistryUrl(componentName, { custom: true });\n try {\n componentData = await this.fetchJson(customUrl);\n isCustom = true;\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found custom component for ${componentName}`);\n }\n } catch (error) {\n // Custom component not found, try standard registry in the same\n // generation. Other failures should be explicit: silently installing\n // the standard component on a registry/server error could hide a\n // customer-specific override problem.\n if (!error.message.includes('404')) {\n throw new Error(`Failed to fetch custom component \"${componentName}\": ${error.message}`);\n }\n\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 No custom component found for ${componentName}, trying standard`);\n }\n }\n }\n \n // If not found in custom, try standard registry\n if (!componentData) {\n const url = this.getRegistryUrl(componentName);\n \n try {\n componentData = await this.fetchJson(url);\n } catch (error) {\n // Check if it's a 404 (component not found)\n if (error.message.includes('404')) {\n if (this.registryGeneration === 'v4') {\n throw new Error(`Tailwind v4 component \"${componentName}\" not migrated for ${this.framework}`);\n }\n throw new Error(`Component \"${componentName}\" not found`);\n }\n throw new Error(`Failed to fetch ${componentName}: ${error.message}`);\n }\n }\n\n // Validate component data\n if (!componentData.files || !Array.isArray(componentData.files)) {\n throw new Error(`Invalid component data for ${componentName}`);\n }\n\n // Download registry dependencies. For v4, dependencies are required and\n // must be installed before writing the parent component to avoid partial\n // installs when the v4 registry slice is incomplete.\n const allDependencies = [...(componentData.dependencies || [])];\n const registryDependencies = (componentData.registryDependencies || []).map(dep => {\n try {\n return {\n dep,\n dependencyName: this.getRegistryDependencyName(dep)\n };\n } catch (error) {\n if (this.registryGeneration === 'v4') {\n throw new Error(\n `Failed to download required v4 registry dependency \"${dep}\" for \"${componentName}\": ${error.message}`\n );\n }\n\n throw error;\n }\n });\n const installRegistryDependencies = async () => {\n if (registryDependencies.length > 0) {\n console.log(` \uD83D\uDCE6 Installing registry dependencies: ${registryDependencies.map(({ dep }) => dep).join(', ')}`);\n\n for (const { dep, dependencyName } of registryDependencies) {\n try {\n const depDeps = await this.downloadComponent(dependencyName);\n depDeps.forEach(d => allDependencies.push(d));\n } catch (error) {\n if (this.registryGeneration === 'v4') {\n throw new Error(\n `Failed to download required v4 registry dependency \"${dep}\" for \"${componentName}\": ${error.message}`\n );\n }\n\n console.warn(` \u26A0\uFE0F Failed to download dependency ${dep}: ${error.message}`);\n }\n }\n }\n };\n\n if (this.registryGeneration === 'v4') {\n await installRegistryDependencies();\n }\n\n // Write component files\n for (const file of componentData.files) {\n await this.writeComponentFile(file);\n }\n\n this.downloadedComponents.add(componentName);\n console.log(` \u2713 ${componentName} downloaded${isCustom && process.env.FF_DEBUG ? ' (custom)' : ''}`);\n \n if (this.registryGeneration !== 'v4') {\n await installRegistryDependencies();\n }\n\n return allDependencies;\n }\n\n /**\n * Write component file to disk\n */\n async writeComponentFile(file) {\n const registryFilePath = file.target || file.name || file.path;\n if (!registryFilePath) {\n throw new Error('Invalid component file descriptor: missing name/path/target');\n }\n\n const normalizeRegistryPath = (registryPath) => registryPath.split('/').join(path.sep);\n const resolveInside = (baseDir, relativeFilePath, rootDescription) => {\n const resolvedBaseDir = path.resolve(baseDir);\n const resolvedFilePath = path.resolve(resolvedBaseDir, normalizeRegistryPath(relativeFilePath));\n const relativeToBase = path.relative(resolvedBaseDir, resolvedFilePath);\n\n if (\n relativeToBase === '' ||\n relativeToBase.startsWith('..') ||\n path.isAbsolute(relativeToBase)\n ) {\n throw new Error(\n `Unsafe component file path \"${registryFilePath}\": resolves outside ${rootDescription}`\n );\n }\n\n return resolvedFilePath;\n };\n\n let filePath;\n const targetAliasMatch = file.target?.match(/^@([^/]+)\\//);\n const resolveAliasBasePath = (aliasName) => {\n if (aliasName === 'ui') {\n return path.resolve(this.outputPath);\n }\n\n const configuredAlias = this.config.aliases?.[aliasName];\n const defaultAliasPaths = {\n components: 'components',\n hooks: 'hooks',\n lib: 'lib'\n };\n const aliasPath = configuredAlias || defaultAliasPaths[aliasName] || aliasName;\n const cleanAliasPath = aliasPath\n .replace(/^@\\//, '')\n .replace(/^~\\//, '');\n const resolvedAppRoot = path.resolve(this.appRoot);\n const resolvedAliasPath = path.isAbsolute(cleanAliasPath)\n ? path.resolve(cleanAliasPath)\n : path.resolve(resolvedAppRoot, normalizeRegistryPath(cleanAliasPath));\n const relativeToAppRoot = path.relative(resolvedAppRoot, resolvedAliasPath);\n\n if (\n relativeToAppRoot === '' ||\n relativeToAppRoot.startsWith('..') ||\n path.isAbsolute(relativeToAppRoot)\n ) {\n throw new Error(\n `Unsafe component file path \"${registryFilePath}\": alias @${aliasName} resolves outside app root`\n );\n }\n\n return resolvedAliasPath;\n };\n\n if (file.target?.startsWith('@ui/')) {\n filePath = resolveInside(this.outputPath, file.target.replace(/^@ui\\//, ''), 'output root');\n } else if (targetAliasMatch) {\n const aliasName = targetAliasMatch[1];\n const aliasBasePath = resolveAliasBasePath(aliasName);\n filePath = resolveInside(\n aliasBasePath,\n file.target.replace(new RegExp(`^@${aliasName}/`), ''),\n `@${aliasName} alias root`\n );\n } else if (file.target?.startsWith('~/')) {\n filePath = resolveInside(this.appRoot, file.target.replace(/^~\\//, ''), 'app root');\n } else if (file.target) {\n filePath = resolveInside(this.appRoot, file.target.replace(/^\\/+/, ''), 'app root');\n } else {\n // Normalize the file path for the current platform\n // Convert forward slashes to the platform-specific separator\n filePath = resolveInside(this.outputPath, registryFilePath, 'output root');\n }\n\n const dir = path.dirname(filePath);\n\n // Create directory if it doesn't exist\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Check if file exists and overwrite setting\n if (fs.existsSync(filePath) && !this.overwrite) {\n console.log(` \u26A0\uFE0F Skipping ${registryFilePath} (already exists)`);\n return;\n }\n\n // Normalize line endings to match the platform\n // This prevents git from showing every line as changed\n let normalizedContent = file.content;\n if (os.EOL !== '\\n') {\n // On Windows, replace LF with CRLF\n normalizedContent = file.content.replace(/\\n/g, os.EOL);\n }\n\n // Write file\n fs.writeFileSync(filePath, normalizedContent, 'utf8');\n }\n}\n\nmodule.exports = { ComponentDownloader };\n"],
5
- "mappings": "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",
6
- "names": ["require_constants", "__commonJSMin", "exports", "module", "DEFAULT_API_URL", "LEGACY_API_URL", "CACHE_DIR_NAME", "CACHE_FILES", "ENV_VARS", "require_errors", "__commonJSMin", "exports", "module", "APIError", "message", "statusCode", "url", "CacheError", "operation", "ConfigError", "field", "ProcessingError", "token", "require_file_utils", "__commonJSMin", "exports", "module", "fs", "readJsonFileSafe", "filepath", "content", "error", "readFileSafe", "writeJsonFile", "data", "indent", "writeTextFile", "writeModuleExportsFile", "fileExists", "ensureDirectoryExists", "dirpath", "removeDirectory", "require_path_utils", "__commonJSMin", "exports", "module", "path", "fileExists", "findFileUpward", "filename", "startDir", "currentDir", "filePath", "findDirectoryUpward", "dirname", "validator", "possiblePaths", "maxLevels", "i", "parentDir", "dirPath", "findDirectoryWithPaths", "absolutePaths", "p", "require_local_token_reader", "__commonJSMin", "exports", "module", "path", "findDirectoryUpward", "readJsonFileSafe", "readFileSafe", "fileExists", "LocalTokenReader", "ffId", "options", "tokensPath", "dir", "folderMapPath", "folderMap", "figmaPath", "tokenPaths", "results", "key", "paths", "tokenPath", "content", "cachePath", "parseModuleExports", "moduleExports", "fakeModule", "cacheFiles", "processedData", "fileName", "type", "filePath", "value", "val", "require_credentials", "__commonJSMin", "exports", "module", "fs", "path", "os", "https", "http", "URL", "DEFAULT_API_URL", "CREDENTIALS_DIR", "CREDENTIALS_PATH", "getCredentialsPath", "readCredentials", "writeCredentials", "credentials", "deleteCredentials", "isExpired", "skewMs", "createAuthRefreshError", "message", "error", "postJson", "url", "body", "authToken", "resolve", "reject", "parsedUrl", "protocol", "payload", "request", "response", "data", "chunk", "redirectUrl", "parsed", "httpError", "refreshCredentials", "baseURL", "refreshed", "resolveAuthToken", "options", "require_api_client", "__commonJSMin", "exports", "module", "https", "http", "URL", "DEFAULT_API_URL", "LEGACY_API_URL", "ENV_VARS", "APIError", "LocalTokenReader", "resolveAuthToken", "AUTH_REQUIRED_MESSAGE", "getWithOptionalAuth", "protocol", "url", "authToken", "callback", "isAuthRedirect", "response", "body", "_a", "location", "createHttpError", "APIClient", "ffId", "options", "resolve", "reject", "data", "chunk", "parsed", "error", "designSystemUrl", "tokensData", "tokens", "err", "legacyBaseURL", "urls", "results", "processedUrl", "result", "method", "parsedUrl", "payload", "request", "componentsConfig", "processedData", "metadata", "saasError", "tokensUrl", "legacyMetadata", "legacyError", "https", "http", "fs", "path", "URL", "os", "DEFAULT_REGISTRY_URL", "SUPPORTED_REGISTRY_GENERATIONS", "ComponentDownloader", "options", "override", "registryConfig", "configuredUrl", "cliGeneration", "configuredGeneration", "value", "packageJsonPath", "packageName", "_a", "_b", "_c", "packageJson", "version", "majorVersion", "reactVersion", "reactMajorVersion", "tailwindMajorVersion", "componentName", "custom", "index", "filename", "dependency", "parsedUrl", "registryUrl", "routeParts", "part", "dependencyGeneration", "dependencyFramework", "dependencyFfId", "fileName", "error", "deps", "cleanPath", "url", "USE_LOCAL", "USE_LOCAL_REGISTRY", "isRegistryUrl", "possiblePaths", "registryPath", "p", "fullPath", "urlPath", "localPath", "content", "resolve", "reject", "response", "data", "chunk", "errorMessage", "errorBody", "components", "comp", "results", "component", "dep", "APIClient", "apiClient", "errorMsg", "componentData", "isCustom", "customUrl", "allDependencies", "registryDependencies", "installRegistryDependencies", "dependencyName", "d", "file", "registryFilePath", "normalizeRegistryPath", "resolveInside", "baseDir", "relativeFilePath", "rootDescription", "resolvedBaseDir", "resolvedFilePath", "relativeToBase", "filePath", "targetAliasMatch", "resolveAliasBasePath", "aliasName", "cleanAliasPath", "resolvedAppRoot", "resolvedAliasPath", "relativeToAppRoot", "aliasBasePath", "dir", "normalizedContent"]
4
+ "sourcesContent": ["/**\n * Configuration constants for FrontFriend Tailwind v2\n */\n\n// API Configuration\nconst DEFAULT_API_URL = 'https://app.frontfriend.dev';\nconst LEGACY_API_URL = 'https://registry-legacy.frontfriend.dev';\n\n// Cache Configuration\nconst CACHE_DIR_NAME = '.cache/frontfriend';\nconst CACHE_TTL_DAYS = 7;\nconst CACHE_TTL_MS = CACHE_TTL_DAYS * 24 * 60 * 60 * 1000;\n\n// File names\nconst CACHE_FILES = {\n JS: [\n 'tokens.js',\n 'variables.js',\n 'semanticVariables.js',\n 'semanticDarkVariables.js',\n 'safelist.js',\n 'custom.js'\n ],\n JSON: [\n 'fonts.json',\n 'icons.json',\n 'components-config.json',\n 'version.json',\n 'metadata.json'\n ]\n};\n\n// Environment variables\nconst ENV_VARS = {\n FF_ID: 'FF_ID',\n FF_API_URL: 'FF_API_URL',\n FF_USE_LOCAL: 'FF_USE_LOCAL',\n FF_AUTH_TOKEN: 'FF_AUTH_TOKEN'\n};\n\nmodule.exports = {\n DEFAULT_API_URL,\n LEGACY_API_URL,\n CACHE_DIR_NAME,\n CACHE_TTL_DAYS,\n CACHE_TTL_MS,\n CACHE_FILES,\n ENV_VARS\n};", "class APIError extends Error {\n constructor(message, statusCode, url) {\n super(message);\n this.name = 'APIError';\n this.statusCode = statusCode;\n this.url = url;\n this.code = `API_${statusCode}`;\n }\n}\n\nclass CacheError extends Error {\n constructor(message, operation) {\n super(message);\n this.name = 'CacheError';\n this.operation = operation;\n this.code = `CACHE_${operation.toUpperCase()}`;\n }\n}\n\nclass ConfigError extends Error {\n constructor(message, field) {\n super(message);\n this.name = 'ConfigError';\n this.field = field;\n // `field` is optional; guard so a missing field never crashes (and masks)\n // the real error with `Cannot read properties of undefined (toUpperCase)`.\n this.code = field ? `CONFIG_${String(field).toUpperCase()}` : 'CONFIG_ERROR';\n }\n}\n\nclass ProcessingError extends Error {\n constructor(message, token) {\n super(message);\n this.name = 'ProcessingError';\n this.token = token;\n this.code = 'PROCESSING_ERROR';\n }\n}\n\nmodule.exports = {\n APIError,\n CacheError,\n ConfigError,\n ProcessingError\n};", "const fs = require('fs');\n\n/**\n * Read a JSON file safely, returning null if file doesn't exist\n * @param {string} filepath - Path to the JSON file\n * @returns {Object|null} Parsed JSON or null if file not found\n * @throws {Error} If JSON is invalid\n */\nfunction readJsonFileSafe(filepath) {\n try {\n const content = fs.readFileSync(filepath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n if (error.code === 'ENOENT') {\n return null; // File not found, return null like API would return 404\n }\n throw error;\n }\n}\n\n/**\n * Read a file safely, returning null if file doesn't exist\n * Strips UTF-8 BOM if present (fixes Windows compatibility)\n * @param {string} filepath - Path to the file\n * @returns {string|null} File content or null if file not found\n * @throws {Error} For other file system errors\n */\nfunction readFileSafe(filepath) {\n try {\n const content = fs.readFileSync(filepath, 'utf8');\n // Strip UTF-8 BOM if present (Windows compatibility)\n return content.replace(/^\\uFEFF/, '');\n } catch (error) {\n if (error.code === 'ENOENT') {\n return null; // File not found\n }\n throw error;\n }\n}\n\n/**\n * Write JSON data to a file with proper formatting\n * @param {string} filepath - Path to write the file\n * @param {Object} data - Data to write\n * @param {number} indent - Indentation level (default: 2)\n */\nfunction writeJsonFile(filepath, data, indent = 2) {\n const content = JSON.stringify(data, null, indent);\n fs.writeFileSync(filepath, content, 'utf8');\n}\n\n/**\n * Write plain text content to a file\n * @param {string} filepath - Path to write the file\n * @param {string} content - Text content to write\n */\nfunction writeTextFile(filepath, content) {\n fs.writeFileSync(filepath, content, 'utf8');\n}\n\n/**\n * Write module.exports file with JSON data\n * @param {string} filepath - Path to write the file\n * @param {Object} data - Data to export\n */\nfunction writeModuleExportsFile(filepath, data) {\n // Handle empty data cases\n if (data === null || data === undefined || \n (typeof data === 'object' && Object.keys(data).length === 0) ||\n (Array.isArray(data) && data.length === 0)) {\n const emptyContent = Array.isArray(data) ? '[]' : '{}';\n const content = `module.exports = ${emptyContent};`;\n fs.writeFileSync(filepath, content, 'utf8');\n } else {\n const content = `module.exports = ${JSON.stringify(data, null, 2)};`;\n fs.writeFileSync(filepath, content, 'utf8');\n }\n}\n\n/**\n * Check if a file exists\n * @param {string} filepath - Path to check\n * @returns {boolean} True if file exists\n */\nfunction fileExists(filepath) {\n return fs.existsSync(filepath);\n}\n\n/**\n * Create directory recursively\n * @param {string} dirpath - Directory path to create\n */\nfunction ensureDirectoryExists(dirpath) {\n fs.mkdirSync(dirpath, { recursive: true });\n}\n\n/**\n * Remove directory recursively\n * @param {string} dirpath - Directory path to remove\n */\nfunction removeDirectory(dirpath) {\n fs.rmSync(dirpath, { recursive: true, force: true });\n}\n\nmodule.exports = {\n readJsonFileSafe,\n readFileSafe,\n writeJsonFile,\n writeTextFile,\n writeModuleExportsFile,\n fileExists,\n ensureDirectoryExists,\n removeDirectory\n};\n", "const path = require('path');\nconst { fileExists } = require('./file-utils');\n\n/**\n * Find a file by traversing up the directory tree\n * @param {string} filename - Name of the file to find\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @returns {string|null} Full path to the file or null if not found\n */\nfunction findFileUpward(filename, startDir = process.cwd()) {\n let currentDir = startDir;\n \n while (currentDir !== path.parse(currentDir).root) {\n const filePath = path.join(currentDir, filename);\n \n if (fileExists(filePath)) {\n return filePath;\n }\n \n currentDir = path.dirname(currentDir);\n }\n \n return null;\n}\n\n/**\n * Find a directory by traversing up and checking multiple possible paths\n * @param {string} dirname - Name of the directory to find\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @param {Function} validator - Optional function to validate the directory\n * @returns {string|null} Full path to the directory or null if not found\n */\nfunction findDirectoryUpward(dirname, startDir = process.cwd(), validator = null) {\n const possiblePaths = [];\n let currentDir = startDir;\n const maxLevels = 10; // Prevent infinite loop\n \n // Build list of possible paths\n for (let i = 0; i < maxLevels; i++) {\n // Direct path\n possiblePaths.push(path.join(currentDir, dirname));\n \n // Relative paths up to 3 levels\n if (i < 3) {\n possiblePaths.push(path.join(currentDir, '../'.repeat(i + 1) + dirname));\n }\n \n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) break; // Reached root\n currentDir = parentDir;\n }\n \n // Also check from module directory (for when running from node_modules)\n possiblePaths.push(path.join(__dirname, '../../../', dirname));\n \n // Find first existing directory that passes validation\n for (const dirPath of possiblePaths) {\n if (fileExists(dirPath)) {\n if (!validator || validator(dirPath)) {\n return dirPath;\n }\n }\n }\n \n return null;\n}\n\n/**\n * Find a directory with multiple possible relative paths\n * @param {string[]} possiblePaths - Array of possible paths to check\n * @param {string} startDir - Starting directory (defaults to cwd)\n * @returns {string|null} Full path to the directory or null if not found\n */\nfunction findDirectoryWithPaths(possiblePaths, startDir = process.cwd()) {\n // Build absolute paths from the start directory\n const absolutePaths = possiblePaths.map(p => {\n if (path.isAbsolute(p)) {\n return p;\n }\n return path.join(startDir, p);\n });\n \n // Find first existing path\n for (const dirPath of absolutePaths) {\n if (fileExists(dirPath)) {\n return dirPath;\n }\n }\n \n return null;\n}\n\nmodule.exports = {\n findFileUpward,\n findDirectoryUpward,\n findDirectoryWithPaths\n};", "const path = require('path');\nconst { findDirectoryUpward } = require('./path-utils');\nconst { readJsonFileSafe, readFileSafe, fileExists } = require('./file-utils');\n\n/**\n * LocalTokenReader - Reads tokens directly from the local file system\n * Mimics the APIClient interface but reads from apps/tokens directory\n */\nclass LocalTokenReader {\n constructor(ffId, options = {}) {\n this.ffId = ffId;\n this.tokensBasePath = options.tokensBasePath || this.findTokensPath();\n this.folderMap = this.loadFolderMap();\n this.projectFolder = this.folderMap[ffId];\n \n if (!this.projectFolder) {\n throw new Error(`No folder mapping found for ff-id: ${ffId}`);\n }\n \n this.projectPath = path.join(this.tokensBasePath, this.projectFolder);\n }\n\n /**\n * Find the tokens directory by looking for apps/tokens in parent directories\n */\n findTokensPath() {\n // Try to find apps/tokens first\n let tokensPath = findDirectoryUpward('apps/tokens', process.cwd(), (dir) => {\n return fileExists(path.join(dir, 'folderMap.json'));\n });\n \n // If not found, try just 'tokens'\n if (!tokensPath) {\n tokensPath = findDirectoryUpward('tokens', process.cwd(), (dir) => {\n return fileExists(path.join(dir, 'folderMap.json'));\n });\n }\n \n if (!tokensPath) {\n throw new Error('Could not find tokens directory with folderMap.json');\n }\n \n return tokensPath;\n }\n\n /**\n * Load the folder mapping from folderMap.json\n */\n loadFolderMap() {\n const folderMapPath = path.join(this.tokensBasePath, 'folderMap.json');\n const folderMap = readJsonFileSafe(folderMapPath);\n \n if (!folderMap) {\n throw new Error(`Failed to load folderMap.json: File not found`);\n }\n \n return folderMap;\n }\n\n /**\n * Fetch all token files (global, colors, semantic)\n * Mimics the APIClient.fetchTokens() method\n */\n async fetchTokens() {\n const figmaPath = path.join(this.projectPath, 'figma');\n \n // Try different possible paths for tokens\n const tokenPaths = {\n global: [\n path.join(figmaPath, 'Global Tokens', 'Default.json'),\n path.join(figmaPath, 'global.json')\n ],\n colors: [\n path.join(figmaPath, 'Global Colors', 'Default.json'),\n path.join(figmaPath, 'Global Colors', 'Light.json')\n ],\n semantic: [\n path.join(figmaPath, 'Semantic', 'Light.json'),\n path.join(figmaPath, 'Semantic', 'Default.json')\n ],\n semanticDark: [\n path.join(figmaPath, 'Semantic', 'Dark.json')\n ]\n };\n\n const results = {};\n \n // Try each possible path for each token type\n for (const [key, paths] of Object.entries(tokenPaths)) {\n for (const tokenPath of paths) {\n const content = readJsonFileSafe(tokenPath);\n if (content !== null) {\n results[key] = content;\n break; // Found it, no need to try other paths\n }\n }\n // If not found in any path, set to null\n if (!results[key]) {\n results[key] = null;\n }\n }\n\n return results;\n }\n\n /**\n * Fetch pre-processed tokens (if available in cache folder)\n */\n async fetchProcessedTokens() {\n const cachePath = path.join(this.projectPath, 'cache');\n \n if (!fileExists(cachePath)) {\n return null;\n }\n\n const parseModuleExports = (content) => {\n if (content === null) return null;\n\n const moduleExports = {};\n const fakeModule = { exports: moduleExports };\n const evalFunc = new Function('module', 'exports', content);\n evalFunc(fakeModule, moduleExports);\n return fakeModule.exports;\n };\n\n // Read all local cache files and normalize them to CacheManager.save() keys.\n const cacheFiles = {\n tokens: { fileName: 'hashedTokens.js', type: 'module' },\n variables: { fileName: 'hashedVariables.js', type: 'module' },\n semanticVariables: { fileName: 'hashedSemanticVariables.js', type: 'module' },\n semanticDarkVariables: { fileName: 'hashedSemanticDarkVariables.js', type: 'module' },\n safelist: { fileName: 'safelist.js', type: 'module' },\n custom: { fileName: 'custom.js', type: 'module' },\n fonts: { fileName: 'fonts.json', type: 'json' },\n icons: { fileName: 'icons.json', type: 'json' },\n componentsConfig: { fileName: 'encoded-config.json', type: 'json' },\n version: { fileName: 'version.json', type: 'json' }\n };\n\n const processedData = {};\n \n for (const [key, { fileName, type }] of Object.entries(cacheFiles)) {\n const filePath = path.join(cachePath, fileName);\n const value = type === 'module'\n ? parseModuleExports(readFileSafe(filePath))\n : readJsonFileSafe(filePath);\n\n if (value !== null) {\n processedData[key] = value;\n }\n }\n\n // Only return if we have at least some data\n const hasData = Object.values(processedData).some(val => val !== null);\n return hasData ? processedData : null;\n }\n\n /**\n * Fetch components configuration\n */\n async fetchComponentsConfig() {\n return readJsonFileSafe(path.join(this.projectPath, 'components-config.json'));\n }\n\n /**\n * Fetch fonts configuration\n */\n async fetchFonts() {\n return readJsonFileSafe(path.join(this.projectPath, 'font.json'));\n }\n\n /**\n * Fetch icons configuration\n */\n async fetchIcons() {\n return readJsonFileSafe(path.join(this.projectPath, 'icons.json'));\n }\n\n /**\n * Fetch version information\n */\n async fetchVersion() {\n return readJsonFileSafe(path.join(this.projectPath, 'version.json'));\n }\n\n /**\n * Fetch custom CSS\n */\n async fetchCustomCss() {\n return readFileSafe(path.join(this.projectPath, 'custom.css'));\n }\n\n /**\n * Fetch plan metadata\n */\n async fetchPlanMetadata() {\n const metadata = readJsonFileSafe(path.join(this.projectPath, 'metadata.json'));\n \n // Default to full plan if no metadata exists\n return metadata || {\n planType: 'full',\n allowedComponents: null\n };\n }\n\n // Compatibility methods to match APIClient interface\n fetchJson() {\n throw new Error('fetchJson is not implemented in LocalTokenReader. Use specific fetch methods.');\n }\n\n fetchRaw() {\n throw new Error('fetchRaw is not implemented in LocalTokenReader. Use specific fetch methods.');\n }\n}\n\nmodule.exports = { LocalTokenReader };\n", "const fs = require('fs');\nconst path = require('path');\nconst os = require('os');\nconst https = require('https');\nconst http = require('http');\nconst { URL } = require('url');\nconst { DEFAULT_API_URL } = require('./constants');\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), '.frontfriend');\nconst CREDENTIALS_PATH = path.join(CREDENTIALS_DIR, 'credentials');\n\nfunction getCredentialsPath() {\n return CREDENTIALS_PATH;\n}\n\nfunction readCredentials() {\n try {\n if (!fs.existsSync(CREDENTIALS_PATH)) return null;\n return JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf8'));\n } catch {\n return null;\n }\n}\n\nfunction writeCredentials(credentials) {\n fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });\n fs.writeFileSync(CREDENTIALS_PATH, `${JSON.stringify(credentials, null, 2)}\\n`, { mode: 0o600 });\n try {\n fs.chmodSync(CREDENTIALS_PATH, 0o600);\n } catch {\n // Best effort on platforms that do not support chmod.\n }\n}\n\nfunction deleteCredentials() {\n if (fs.existsSync(CREDENTIALS_PATH)) {\n fs.unlinkSync(CREDENTIALS_PATH);\n return true;\n }\n return false;\n}\n\nfunction isExpired(credentials, skewMs = 60 * 1000) {\n return !credentials?.accessToken || !credentials.expiresAt || Date.now() + skewMs >= credentials.expiresAt;\n}\n\nfunction createAuthRefreshError(message) {\n const error = new Error(`${message}. Run \\`frontfriend login\\` to re-authenticate.`);\n error.code = 'FF_AUTH_REFRESH_FAILED';\n return error;\n}\n\nfunction postJson(url, body, authToken) {\n return new Promise((resolve, reject) => {\n const parsedUrl = new URL(url);\n const protocol = parsedUrl.protocol === 'https:' ? https : http;\n const payload = JSON.stringify(body || {});\n const request = protocol.request({\n hostname: parsedUrl.hostname,\n port: parsedUrl.port,\n path: `${parsedUrl.pathname}${parsedUrl.search}`,\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n ...(authToken ? { authorization: `Bearer ${authToken}` } : {}),\n },\n }, response => {\n let data = '';\n response.on('data', chunk => { data += chunk; });\n response.on('end', () => {\n if (response.statusCode >= 300 && response.statusCode < 400) {\n const redirectUrl = response.headers.location ? ` to ${response.headers.location}` : '';\n const error = new Error(`HTTP ${response.statusCode}: redirected${redirectUrl}`);\n error.statusCode = response.statusCode;\n error.body = data;\n reject(error);\n return;\n }\n\n let parsed = null;\n try {\n parsed = data ? JSON.parse(data) : null;\n } catch (error) {\n if (response.statusCode >= 400) {\n const httpError = new Error(`HTTP ${response.statusCode}: ${response.statusMessage || 'Non-JSON response'}`);\n httpError.statusCode = response.statusCode;\n httpError.body = data;\n reject(httpError);\n return;\n }\n reject(error);\n return;\n }\n if (response.statusCode >= 400) {\n const error = new Error(parsed?.error_description || parsed?.error || `HTTP ${response.statusCode}`);\n error.statusCode = response.statusCode;\n error.body = parsed;\n reject(error);\n return;\n }\n resolve(parsed);\n });\n });\n request.on('error', reject);\n request.write(payload);\n request.end();\n });\n}\n\nasync function refreshCredentials(credentials, baseURL = DEFAULT_API_URL) {\n if (!credentials?.refreshToken || !credentials?.deviceId) {\n throw createAuthRefreshError('FrontFriend session expired');\n }\n\n let response;\n try {\n response = await postJson(`${baseURL}/api/plugin/token`, {\n grant_type: 'refresh_token',\n refresh_token: credentials.refreshToken,\n device_id: credentials.deviceId,\n });\n } catch (error) {\n throw createAuthRefreshError(error?.message || 'Could not refresh FrontFriend session');\n }\n\n if (!response?.access_token || !response?.refresh_token) {\n throw createAuthRefreshError('Could not refresh FrontFriend session');\n }\n\n const refreshed = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token,\n deviceId: response.device_id || credentials.deviceId,\n expiresAt: Date.now() + (response.expires_in || 900) * 1000,\n refreshExpiresAt: Date.now() + (response.refresh_expires_in || 604800) * 1000,\n ffApiUrl: baseURL,\n };\n writeCredentials(refreshed);\n return refreshed;\n}\n\nasync function resolveAuthToken(options = {}) {\n if (!options.skipCredentials) {\n const credentials = readCredentials();\n if (credentials?.accessToken || credentials?.refreshToken) {\n const baseURL = options.baseURL || credentials.ffApiUrl || DEFAULT_API_URL;\n if (credentials.accessToken && !isExpired(credentials)) {\n return credentials.accessToken;\n }\n const refreshed = await refreshCredentials(credentials, baseURL);\n return refreshed.accessToken;\n }\n }\n\n if (options.envToken) return options.envToken;\n if (options.legacyToken) {\n if (!options.silent) {\n console.warn('\u26A0\uFE0F auth-token in frontfriend.config.js is deprecated. Run `frontfriend login` to store credentials outside the repo.');\n }\n return options.legacyToken;\n }\n return null;\n}\n\nmodule.exports = {\n getCredentialsPath,\n readCredentials,\n writeCredentials,\n deleteCredentials,\n isExpired,\n postJson,\n refreshCredentials,\n resolveAuthToken,\n createAuthRefreshError,\n};\n", "const https = require('https');\nconst http = require('http');\nconst { URL } = require('url');\nconst { DEFAULT_API_URL, LEGACY_API_URL, ENV_VARS } = require('./constants');\nconst { APIError } = require('./errors');\nconst { LocalTokenReader } = require('./local-token-reader');\nconst { resolveAuthToken } = require('./credentials');\n\nconst AUTH_REQUIRED_MESSAGE = 'Authentication required. Run `frontfriend login` to re-authenticate.';\n\nfunction getWithOptionalAuth(protocol, url, authToken, callback) {\n if (authToken) {\n return protocol.get(new URL(url), {\n headers: { authorization: `Bearer ${authToken}` },\n }, callback);\n }\n\n return protocol.get(url, callback);\n}\n\nfunction isAuthRedirect(response, body = '') {\n const location = response.headers?.location || '';\n return (\n response.statusCode === 401 ||\n response.statusCode === 403 ||\n (response.statusCode >= 300 && response.statusCode < 400 && location.includes('/sign-in')) ||\n String(body).trim().startsWith('/sign-in')\n );\n}\n\nfunction createHttpError(response, url, body = '') {\n if (isAuthRedirect(response, body)) {\n return new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url);\n }\n return new APIError(\n `HTTP ${response.statusCode}: ${response.statusMessage}`,\n response.statusCode,\n url\n );\n}\n\nclass APIClient {\n constructor(ffId, options = {}) {\n this.ffId = ffId;\n this.baseURL = options.baseURL || process.env[ENV_VARS.FF_API_URL] || DEFAULT_API_URL;\n this.legacyAuthToken = options.authToken || null;\n this.authToken = null;\n this.skipCredentials = options.skipCredentials || false;\n \n // Check if we should use local token reader\n if (process.env[ENV_VARS.FF_USE_LOCAL] === 'true') {\n console.log(' \uD83C\uDFE0 Using local token reader');\n this.localReader = new LocalTokenReader(ffId, options);\n }\n }\n\n /**\n * Fetch JSON data from a URL using native https module\n * @param {string} url - The URL to fetch\n * @param {Object} options - Fetch options\n * @param {boolean} options.returnHeaders - If true, return {data, headers} object\n * @returns {Promise<any>} Parsed JSON data or {data, headers} if returnHeaders is true\n */\n async getAuthToken() {\n this.authToken = await resolveAuthToken({\n baseURL: this.baseURL,\n envToken: process.env[ENV_VARS.FF_AUTH_TOKEN],\n legacyToken: this.legacyAuthToken,\n skipCredentials: this.skipCredentials,\n });\n return this.authToken;\n }\n\n async fetchJson(url, options = {}) {\n const authToken = await this.getAuthToken();\n return new Promise((resolve, reject) => {\n // Determine if we should use http or https\n const protocol = url.startsWith('https') ? https : http;\n\n getWithOptionalAuth(protocol, url, authToken, (response) => {\n let data = '';\n\n // Check for HTTP errors and redirects before waiting for a body. Some\n // tests and intermediaries do not send one.\n if (response.statusCode >= 300) {\n reject(createHttpError(response, url));\n return;\n }\n\n // Collect response chunks\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n // Parse JSON when complete\n response.on('end', () => {\n try {\n const parsed = JSON.parse(data);\n\n // Return headers if requested\n if (options.returnHeaders) {\n resolve({\n data: parsed,\n headers: response.headers\n });\n } else {\n resolve(parsed);\n }\n } catch (error) {\n if (isAuthRedirect(response, data)) {\n reject(new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url));\n return;\n }\n reject(new APIError(\n `Invalid JSON response: ${error.message}`,\n response.statusCode,\n url\n ));\n }\n });\n\n // Handle response errors\n response.on('error', (error) => {\n reject(new APIError(\n `Response error: ${error.message}`,\n response.statusCode,\n url\n ));\n });\n }).on('error', (error) => {\n // Handle network errors\n reject(new APIError(\n `Network error: ${error.message}`,\n 0,\n url\n ));\n });\n });\n }\n\n /**\n * Fetch raw content from a URL\n * @param {string} url - The URL to fetch\n * @returns {Promise<string>} Raw text content\n */\n async fetchRaw(url) {\n const authToken = await this.getAuthToken();\n return new Promise((resolve, reject) => {\n // Determine if we should use http or https\n const protocol = url.startsWith('https') ? https : http;\n \n getWithOptionalAuth(protocol, url, authToken, (response) => {\n let data = '';\n \n // Check for HTTP errors\n if (response.statusCode >= 400) {\n reject(new APIError(\n `HTTP ${response.statusCode}: ${response.statusMessage}`,\n response.statusCode,\n url\n ));\n return;\n }\n\n // Collect response chunks\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n // Return raw data when complete\n response.on('end', () => {\n resolve(data);\n });\n\n // Handle response errors\n response.on('error', (error) => {\n reject(new APIError(\n `Response error: ${error.message}`,\n response.statusCode,\n url\n ));\n });\n }).on('error', (error) => {\n // Handle network errors\n reject(new APIError(\n `Network error: ${error.message}`,\n 0,\n url\n ));\n });\n });\n }\n\n /**\n * Fetch all token files (global, colors, semantic)\n * @returns {Promise<Object>} Object with all token data\n */\n async fetchTokens() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchTokens();\n }\n \n // First try the new design system endpoint\n try {\n const designSystemUrl = `${this.baseURL}/api/design-systems/${this.ffId}/tokens`;\n const tokensData = await this.fetchJson(designSystemUrl);\n \n // If we have the new format, parse it\n if (tokensData && tokensData.tokens) {\n const tokens = tokensData.tokens;\n \n // Extract specific token sets from the new format\n return {\n global: tokens['Global Tokens/Default'] || tokens['global'] || null,\n colors: tokens['Global Colors/Default'] || tokens['colors'] || null,\n semantic: tokens['Semantic/Light'] || tokens['semantic/light'] || null,\n semanticDark: tokens['Semantic/Dark'] || tokens['semantic/dark'] || null\n };\n }\n } catch (err) {\n // If design system is not synced (400 error), throw with clear message\n if (err.statusCode === 400) {\n throw new APIError(\n 'Design system not synced with Figma. Please sync tokens from Figma before using this design system.',\n 400,\n `${this.baseURL}/api/design-systems/${this.ffId}/tokens`\n );\n }\n // Failed to fetch from design system endpoint, falling back to legacy URLs\n }\n \n // Fall back to legacy token URLs\n // Use legacy API URL for backward compatibility\n const legacyBaseURL = LEGACY_API_URL;\n const urls = {\n global: `${legacyBaseURL}/${this.ffId}/global-tokens/default.json`,\n colors: `${legacyBaseURL}/${this.ffId}/global-colors/default.json`,\n semantic: `${legacyBaseURL}/${this.ffId}/semantic/light.json`,\n semanticDark: `${legacyBaseURL}/${this.ffId}/semantic/dark.json`\n };\n\n const results = await Promise.all([\n this.fetchJson(urls.global).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.colors).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.semantic).catch(err => err.statusCode === 404 ? null : Promise.reject(err)),\n this.fetchJson(urls.semanticDark).catch(err => err.statusCode === 404 ? null : Promise.reject(err))\n ]);\n\n return {\n global: results[0],\n colors: results[1],\n semantic: results[2],\n semanticDark: results[3]\n };\n }\n\n /**\n * Fetch pre-processed tokens from the design system endpoint\n * @param {Object} options - Fetch options\n * @param {string} options.tag - Tag name (e.g., 'dev', 'next', 'latest')\n * @param {string} options.version - Version label (e.g., 'v1.0.0')\n * @param {boolean} options.tailwindV4 - Request OKLCH/v4 color encoding so\n * generated utilities reference variables without an hsl() wrapper (#421)\n * @returns {Promise<Object|null>} Processed tokens ready for caching with metadata or null if not found\n */\n async fetchProcessedTokens(options = {}) {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchProcessedTokens();\n }\n\n // Build URL with optional query parameters\n const url = new URL(`${this.baseURL}/api/design-systems/${this.ffId}/processed-tokens`);\n if (options.tag) {\n url.searchParams.append('tag', options.tag);\n }\n if (options.version) {\n url.searchParams.append('version', options.version);\n }\n if (options.tailwindV4) {\n // Tailwind v4 consumers need OKLCH-encoded variables so the generated\n // @utility rules can reference them directly. See issue #421.\n url.searchParams.append('tailwind', 'v4');\n }\n\n const processedUrl = url.toString();\n\n try {\n const result = await this.fetchJson(processedUrl, { returnHeaders: true });\n\n // Attach version metadata from response headers\n if (result.headers) {\n result.data.versionMetadata = {\n version: result.headers['x-frontfriend-version'],\n tag: result.headers['x-frontfriend-tag'],\n cached: result.headers['x-frontfriend-cached'] === 'true'\n };\n }\n\n return result.data;\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n // If design system is not synced (400 error), throw with clear message\n if (error.statusCode === 400) {\n throw new APIError(\n 'Design system not synced with Figma. Please sync tokens from Figma before using this design system.',\n 400,\n processedUrl\n );\n }\n throw error;\n }\n }\n\n\n\n /**\n * Send JSON data to a URL using native http/https modules.\n * @param {string} url - The URL to send to\n * @param {string} method - HTTP method\n * @param {Object} body - JSON body\n * @returns {Promise<any>} Parsed JSON response or null for empty response\n */\n async sendJson(url, method, body) {\n const authToken = await this.getAuthToken();\n if (!authToken) {\n throw new APIError(AUTH_REQUIRED_MESSAGE, 401, url);\n }\n\n return new Promise((resolve, reject) => {\n const parsedUrl = new URL(url);\n const protocol = url.startsWith('https') ? https : http;\n const payload = JSON.stringify(body || {});\n const request = protocol.request({\n hostname: parsedUrl.hostname,\n port: parsedUrl.port,\n path: `${parsedUrl.pathname}${parsedUrl.search}`,\n method,\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n ...(authToken ? { authorization: `Bearer ${authToken}` } : {}),\n },\n }, (response) => {\n let data = '';\n if (response.statusCode >= 300) {\n reject(createHttpError(response, url));\n return;\n }\n\n response.on('data', chunk => { data += chunk; });\n response.on('end', () => {\n if (!data) {\n resolve(null);\n return;\n }\n try {\n resolve(JSON.parse(data));\n } catch (error) {\n if (isAuthRedirect(response, data)) {\n reject(new APIError(AUTH_REQUIRED_MESSAGE, response.statusCode, url));\n return;\n }\n reject(new APIError(\n `Invalid JSON response: ${error.message}`,\n response.statusCode,\n url\n ));\n }\n });\n });\n request.on('error', error => {\n reject(new APIError(`Network error: ${error.message}`, 0, url));\n });\n request.write(payload);\n request.end();\n });\n }\n\n /**\n * Push migrated component config to the cloud as a user override.\n * @param {Object} componentsConfig - FF-canonical component config\n * @returns {Promise<any>}\n */\n async pushComponentsConfig(componentsConfig, customCss) {\n const url = `${this.baseURL}/api/design-systems/${this.ffId}/components-config`;\n const payload = { componentsConfig };\n if (typeof customCss === 'string' && customCss.length > 0) {\n payload.customCss = customCss;\n }\n return this.sendJson(url, 'PUT', payload);\n }\n\n\n /**\n * Fetch components configuration\n * @returns {Promise<Object|null>} Components config or null if not found\n */\n async fetchComponentsConfig() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchComponentsConfig();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/components-config.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch fonts configuration\n * @returns {Promise<Object|null>} Fonts object with font1, font2, etc. URLs or null\n */\n async fetchFonts() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchFonts();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/font.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch icons configuration\n * @returns {Promise<Object|null>} Icons data or null if not found\n */\n async fetchIcons() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchIcons();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/icons.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch version information\n * @returns {Promise<Object|null>} Version data or null if not found\n */\n async fetchVersion() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchVersion();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/version.json`;\n try {\n return await this.fetchJson(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch custom CSS\n * @returns {Promise<string|null>} Custom CSS string or null if not found\n */\n async fetchCustomCss() {\n // Use local reader if available\n if (this.localReader) {\n return this.localReader.fetchCustomCss();\n }\n \n // Always use legacy URL for these endpoints\n const url = `${LEGACY_API_URL}/${this.ffId}/custom.css`;\n try {\n return await this.fetchRaw(url);\n } catch (error) {\n if (error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Fetch plan metadata (plan type and allowed components)\n * @returns {Promise<Object|null>} Plan metadata or null if not found\n */\n async fetchPlanMetadata() {\n // Use local reader if available\n if (this.localReader) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 Using local reader for plan metadata');\n }\n return this.localReader.fetchPlanMetadata();\n }\n \n // First try the saas app (processed-tokens endpoint) - this is the authoritative source\n const processedUrl = `${this.baseURL}/api/design-systems/${this.ffId}/processed-tokens`;\n try {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching plan metadata from saas app: ${processedUrl}`);\n }\n \n const processedData = await this.fetchJson(processedUrl);\n \n // Extract metadata from processed tokens response\n if (processedData && processedData.metadata) {\n const metadata = {\n planType: processedData.metadata.planType || 'full',\n allowedComponents: processedData.metadata.allowedComponents || null\n };\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found plan metadata in saas app: ${metadata.planType}, allowed: ${metadata.allowedComponents ? metadata.allowedComponents.length + ' components' : 'all'}`);\n }\n \n return metadata;\n }\n } catch (saasError) {\n // If not found in saas app, try legacy server\n if (saasError.statusCode === 404) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 ff-id not found in saas app, trying legacy server');\n }\n \n // Try legacy tokens server (these are always full plan - no trial concept)\n const tokensUrl = `${LEGACY_API_URL}/${this.ffId}/metadata`;\n try {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching from legacy server: ${tokensUrl}`);\n }\n const legacyMetadata = await this.fetchJson(tokensUrl);\n \n // Use the plan metadata from legacy server if available\n const metadata = {\n planType: legacyMetadata.planType || 'full',\n allowedComponents: legacyMetadata.allowedComponents || null\n };\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found in legacy server: ${metadata.planType}, allowed: ${metadata.allowedComponents ? metadata.allowedComponents.length + ' components' : 'all'}`);\n }\n \n return metadata;\n } catch (legacyError) {\n if (legacyError.statusCode === 404) {\n // Not found in either place - DENY access\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 ff-id not found in any server - access denied');\n }\n \n // Return a denied plan type instead of defaulting to full\n return {\n planType: 'denied',\n allowedComponents: [],\n error: 'Design system not found. Please ensure your ff-id is valid.'\n };\n }\n throw legacyError;\n }\n }\n throw saasError;\n }\n }\n}\n\nmodule.exports = { APIClient };\n", "const https = require('https');\nconst http = require('http');\nconst fs = require('fs');\nconst path = require('path');\nconst { URL } = require('url');\nconst os = require('os');\n\nconst DEFAULT_REGISTRY_URL = 'https://registry.frontfriend.dev';\nconst SUPPORTED_REGISTRY_GENERATIONS = ['legacy', 'v4'];\n\nclass ComponentDownloader {\n constructor(options = {}) {\n this.appRoot = options.appRoot || process.cwd();\n this.framework = options.framework || this.detectFramework();\n this.config = options.config || {};\n this.registryGeneration = this.resolveRegistryGeneration(options.registryGeneration);\n this.outputPath = options.outputPath || this.getDefaultOutputPath();\n this.overwrite = options.overwrite || false;\n this.downloadedComponents = new Set();\n this.downloadingComponents = new Set();\n this.ffId = this.config.ffId || this.config['ff-id'] || null;\n this.registryUrl = this.resolveRegistryUrl(options.registryUrl);\n this.planMetadata = null; // Will be populated when needed\n }\n\n resolveRegistryUrl(override) {\n const registryConfig = this.config.registry;\n const configuredUrl =\n this.config.registryUrl ||\n this.config.registryBaseUrl ||\n (typeof registryConfig === 'object' ? registryConfig.url || registryConfig.baseUrl : undefined);\n\n return (override || configuredUrl || process.env.FF_REGISTRY_URL || DEFAULT_REGISTRY_URL).replace(/\\/+$/, '');\n }\n\n /**\n * Resolve registry generation with precedence:\n * CLI option > frontfriend config > Tailwind version auto-detection > legacy.\n */\n resolveRegistryGeneration(cliGeneration) {\n const registryConfig = this.config.registry;\n const configuredGeneration =\n this.config.registryGeneration ||\n this.config.registryVersion ||\n (typeof registryConfig === 'string' ? registryConfig : registryConfig?.generation || registryConfig?.version);\n\n return this.normalizeRegistryGeneration(\n cliGeneration || configuredGeneration || (this.detectTailwindV4() ? 'v4' : 'legacy')\n );\n }\n\n normalizeRegistryGeneration(value) {\n if (value === undefined || value === null || value === '') {\n return 'legacy';\n }\n\n if (value === 'v4' || value === 4 || value === '4') {\n return 'v4';\n }\n\n if (value === 'legacy') {\n return 'legacy';\n }\n\n throw new Error(\n `Unsupported registry generation \"${value}\". Supported generations: ${SUPPORTED_REGISTRY_GENERATIONS.join(', ')}.`\n );\n }\n\n readPackageJson() {\n const packageJsonPath = path.join(this.appRoot, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n } catch (error) {\n return null;\n }\n }\n\n getDependencyVersion(packageName) {\n const packageJson = this.readPackageJson();\n\n return (\n packageJson?.dependencies?.[packageName] ||\n packageJson?.devDependencies?.[packageName] ||\n packageJson?.peerDependencies?.[packageName] ||\n null\n );\n }\n\n getDependencyMajorVersion(packageName) {\n const version = this.getDependencyVersion(packageName);\n const majorVersion = version?.match(/(\\d+)/)?.[1];\n\n return majorVersion ? Number(majorVersion) : null;\n }\n\n validateRuntimeCompatibility() {\n if (this.framework !== 'react') {\n return;\n }\n\n const reactVersion = this.getDependencyVersion('react');\n const reactMajorVersion = this.getDependencyMajorVersion('react');\n\n if (!reactVersion || !reactMajorVersion) {\n return;\n }\n\n if (this.registryGeneration === 'v4' && reactMajorVersion < 19) {\n throw new Error(`Tailwind v4 React registry requires React 19; found react ${reactVersion}`);\n }\n\n if (this.registryGeneration === 'legacy' && reactMajorVersion >= 19) {\n throw new Error(\n `Legacy React registry targets React 18; found react ${reactVersion}. Use --registry v4 for React 19 projects.`\n );\n }\n }\n\n /**\n * Detect Tailwind v4 from the consuming app's package.json.\n */\n detectTailwindV4() {\n const tailwindMajorVersion = this.getDependencyMajorVersion('tailwindcss');\n\n return tailwindMajorVersion ? tailwindMajorVersion >= 4 : false;\n }\n\n /**\n * Build registry endpoint URLs for the selected generation.\n */\n getRegistryUrl(componentName, { custom = false, index = false } = {}) {\n const filename = index ? 'index.json' : `${componentName}.json`;\n\n if (custom) {\n if (this.registryGeneration === 'v4') {\n return `${this.registryUrl}/custom/v4/${this.ffId}/${this.framework}/${filename}`;\n }\n\n return `${this.registryUrl}/custom/${this.ffId}/${this.framework}/${filename}`;\n }\n\n if (this.registryGeneration === 'v4') {\n return `${this.registryUrl}/components/v4/${this.framework}/${filename}`;\n }\n\n return `${this.registryUrl}/components/${this.framework}/${filename}`;\n }\n\n /**\n * Normalize shadcn-compatible registry dependency URLs back to component\n * names for the Frontfriend downloader. Frontfriend dependency resolution\n * still uses same-generation custom-first fallback via downloadComponent().\n */\n getRegistryDependencyName(dependency) {\n if (typeof dependency !== 'string') {\n return dependency;\n }\n\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(dependency)) {\n return dependency;\n }\n\n try {\n const parsedUrl = new URL(dependency);\n const registryUrl = new URL(this.registryUrl);\n\n if (parsedUrl.origin !== registryUrl.origin) {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Only Frontfriend registry URLs are supported by this downloader.`\n );\n }\n\n const routeParts = parsedUrl.pathname\n .split('/')\n .filter(Boolean)\n .map(part => decodeURIComponent(part));\n let dependencyGeneration;\n let dependencyFramework;\n let dependencyFfId;\n let fileName;\n\n if (routeParts[0] !== 'r') {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Expected a Frontfriend /r/{generation}/{framework}/{component}.json route.`\n );\n }\n\n if (routeParts[2] === 'custom') {\n [, dependencyGeneration, , dependencyFfId, dependencyFramework, fileName] = routeParts;\n } else {\n [, dependencyGeneration, dependencyFramework, fileName] = routeParts;\n }\n\n if (!dependencyGeneration || !dependencyFramework || !fileName || !fileName.endsWith('.json')) {\n throw new Error(\n `Unsupported registry dependency URL \"${dependency}\". Expected a Frontfriend /r/{generation}/{framework}/{component}.json route.`\n );\n }\n\n if (dependencyGeneration !== this.registryGeneration) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets generation \"${dependencyGeneration}\" but downloader is using \"${this.registryGeneration}\".`\n );\n }\n\n if (dependencyFramework !== this.framework) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets framework \"${dependencyFramework}\" but downloader is using \"${this.framework}\".`\n );\n }\n\n if (dependencyFfId && dependencyFfId !== this.ffId) {\n throw new Error(\n `Registry dependency URL \"${dependency}\" targets ff-id \"${dependencyFfId}\" but downloader is using \"${this.ffId || 'none'}\".`\n );\n }\n\n return fileName.endsWith('.json')\n ? fileName.slice(0, -'.json'.length)\n : fileName;\n } catch (error) {\n if (\n error.message.startsWith('Unsupported registry dependency URL') ||\n error.message.startsWith('Registry dependency URL')\n ) {\n throw error;\n }\n\n return dependency;\n }\n }\n\n /**\n * Detect framework from package.json\n */\n detectFramework() {\n const packageJsonPath = path.join(this.appRoot, 'package.json');\n \n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (deps.vue) {\n return 'vue';\n } else if (deps.react) {\n return 'react';\n }\n }\n \n // Default to React if can't detect\n return 'react';\n }\n\n /**\n * Get default output path based on framework and config\n */\n getDefaultOutputPath() {\n // Check if config has ui alias\n if (this.config.aliases && this.config.aliases.ui) {\n const uiAlias = this.config.aliases.ui;\n // Convert alias to actual path (e.g., @/components/ui -> components/ui)\n const cleanPath = uiAlias.replace(/^@\\//, '');\n return path.join(this.appRoot, cleanPath);\n }\n \n // Fallback to default paths\n if (this.framework === 'vue') {\n return path.join(this.appRoot, 'src/components/ui');\n }\n return path.join(this.appRoot, 'components/ui');\n }\n\n /**\n * Fetch JSON from URL or local file\n */\n fetchJson(url) {\n // Check if using local mode at runtime\n // FF_USE_LOCAL: affects both tokens and components\n // FF_USE_LOCAL_REGISTRY: affects only components (for registry URLs)\n const USE_LOCAL = process.env.FF_USE_LOCAL === 'true';\n const USE_LOCAL_REGISTRY = process.env.FF_USE_LOCAL_REGISTRY === 'true';\n \n // Check if this is a registry URL\n const isRegistryUrl = url.includes(this.registryUrl);\n \n // Use local file system if:\n // 1. FF_USE_LOCAL is set (affects everything), OR\n // 2. FF_USE_LOCAL_REGISTRY is set AND this is a registry URL\n if (USE_LOCAL || (USE_LOCAL_REGISTRY && isRegistryUrl)) {\n if (process.env.FF_DEBUG && USE_LOCAL_REGISTRY && !USE_LOCAL) {\n console.log(' \u2192 Using local registry for components');\n }\n \n // Try multiple paths to find the registry\n const possiblePaths = [\n '../../packages/registry',\n '../../../packages/registry',\n '../../../../packages/registry',\n path.join(__dirname, '../../../registry'),\n 'packages/registry'\n ];\n \n let registryPath;\n for (const p of possiblePaths) {\n const fullPath = path.isAbsolute(p) ? p : path.join(process.cwd(), p);\n if (fs.existsSync(fullPath)) {\n registryPath = fullPath;\n break;\n }\n }\n \n if (!registryPath) {\n return Promise.reject(new Error(`Local registry not found. Tried paths: ${possiblePaths.join(', ')}`));\n }\n \n // Extract the path from the URL and construct proper local path\n const urlPath = url.replace(this.registryUrl, '').replace(/^\\//, '');\n const localPath = path.join(registryPath, ...urlPath.split('/'));\n \n try {\n const content = fs.readFileSync(localPath, 'utf8');\n return Promise.resolve(JSON.parse(content));\n } catch (error) {\n if (error.code === 'ENOENT') {\n return Promise.reject(new Error('HTTP 404: Not Found'));\n }\n return Promise.reject(error);\n }\n }\n\n return new Promise((resolve, reject) => {\n const client = new URL(url).protocol === 'http:' ? http : https;\n client.get(url, (response) => {\n let data = '';\n\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n response.on('end', () => {\n if (response.statusCode >= 400) {\n let errorMessage = response.statusMessage;\n\n try {\n const errorBody = JSON.parse(data);\n errorMessage = errorBody.error || errorBody.message || errorMessage;\n } catch (error) {\n // Keep the HTTP status text if the registry did not return JSON.\n }\n\n reject(new Error(`HTTP ${response.statusCode}: ${errorMessage}`));\n return;\n }\n\n try {\n resolve(JSON.parse(data));\n } catch (error) {\n reject(new Error(`Invalid JSON response: ${error.message}`));\n }\n });\n\n }).on('error', (error) => {\n reject(error);\n });\n });\n }\n\n /**\n * Get all available components from registry\n */\n async getAllComponents() {\n this.validateRuntimeCompatibility();\n\n try {\n const url = this.getRegistryUrl(null, { index: true });\n const index = await this.fetchJson(url);\n let components = index.components || [];\n \n // Filter components based on plan\n if (this.ffId) {\n // Ensure plan metadata is loaded\n try {\n await this.isComponentAllowed('dummy'); // This will load metadata\n } catch (error) {\n // If access is denied, throw error\n if (this.planMetadata && this.planMetadata.planType === 'denied') {\n throw new Error(this.planMetadata.error || 'Access denied. Your ff-id was not found in any server.');\n }\n }\n \n if (this.planMetadata && this.planMetadata.planType === 'trial' && this.planMetadata.allowedComponents) {\n components = components.filter(comp => this.planMetadata.allowedComponents.includes(comp));\n \n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Trial plan: filtering to ${components.length} allowed components`);\n }\n }\n }\n \n return components;\n } catch (error) {\n if (error.message.includes('404') && this.registryGeneration === 'v4') {\n throw new Error(`Tailwind v4 registry not available for ${this.framework}`);\n }\n\n if (this.planMetadata?.planType === 'denied' || error.message.startsWith('Access denied.')) {\n throw error;\n }\n\n throw new Error(`Failed to fetch component index: ${error.message}`);\n }\n }\n\n /**\n * Get all custom components for this ff-id\n */\n async getCustomComponents() {\n if (!this.ffId) {\n if (process.env.FF_DEBUG) {\n console.log(' \u2192 No ff-id found, skipping custom components');\n }\n return [];\n }\n\n this.validateRuntimeCompatibility();\n \n try {\n const url = this.getRegistryUrl(null, { custom: true, index: true });\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetching custom components from: ${url}`);\n }\n const index = await this.fetchJson(url);\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found custom components: ${JSON.stringify(index.components)}`);\n }\n return index.components || [];\n } catch (error) {\n // Custom components might not exist, that's ok\n if (!error.message.includes('404')) {\n throw new Error(`Failed to fetch custom component index: ${error.message}`);\n }\n\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 No custom components found: ${error.message}`);\n }\n return [];\n }\n }\n\n /**\n * Download multiple components\n */\n async downloadComponents(components) {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 ComponentDownloader initialized with ff-id: ${this.ffId}`);\n }\n \n const results = {\n successful: [],\n failed: [],\n dependencies: new Set()\n };\n\n for (const component of components) {\n try {\n const deps = await this.downloadComponent(component);\n results.successful.push(component);\n \n // Add dependencies\n deps.forEach(dep => results.dependencies.add(dep));\n } catch (error) {\n results.failed.push({\n component,\n error: error.message\n });\n }\n }\n\n return {\n successful: results.successful,\n failed: results.failed,\n dependencies: Array.from(results.dependencies)\n };\n }\n\n /**\n * Check if component is allowed based on plan\n */\n async isComponentAllowed(componentName) {\n // Fetch plan metadata if not already loaded\n if (!this.planMetadata && this.ffId) {\n const { APIClient } = require('./api-client');\n const apiClient = new APIClient(this.ffId, {\n baseURL: this.config['api-url'] || this.config.apiUrl\n });\n try {\n this.planMetadata = await apiClient.fetchPlanMetadata();\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Fetched plan metadata: ${this.planMetadata.planType}, allowed: ${this.planMetadata.allowedComponents ? this.planMetadata.allowedComponents.length + ' components' : 'all'}`);\n }\n } catch (error) {\n console.warn('Failed to fetch plan metadata:', error.message);\n // Default to full plan if we can't fetch metadata\n this.planMetadata = { planType: 'full', allowedComponents: null };\n }\n }\n\n // Handle denied plan (ff-id not found anywhere)\n if (this.planMetadata && this.planMetadata.planType === 'denied') {\n throw new Error(this.planMetadata.error || 'Access denied. Your ff-id was not found in any server.');\n }\n \n // If full plan or no metadata, allow all components\n if (!this.planMetadata || this.planMetadata.planType === 'full') {\n return true;\n }\n\n // For trial plan, check if component is in allowed list\n if (this.planMetadata.planType === 'trial' && this.planMetadata.allowedComponents) {\n return this.planMetadata.allowedComponents.includes(componentName);\n }\n\n // Default to denying if we can't determine (safer)\n return false;\n }\n\n /**\n * Download a single component and its registry dependencies\n */\n async downloadComponent(componentName) {\n this.validateRuntimeCompatibility();\n\n // Avoid downloading the same component twice\n if (this.downloadedComponents.has(componentName)) {\n return [];\n }\n\n if (this.downloadingComponents.has(componentName)) {\n throw new Error(`Circular registry dependency detected while downloading \"${componentName}\"`);\n }\n\n this.downloadingComponents.add(componentName);\n\n try {\n return await this.downloadComponentInternal(componentName);\n } finally {\n this.downloadingComponents.delete(componentName);\n }\n }\n\n async downloadComponentInternal(componentName) {\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Checking if component \"${componentName}\" is allowed...`);\n console.log(` \u2192 FF-ID: ${this.ffId}`);\n }\n\n // Check if component is allowed based on plan\n const isAllowed = await this.isComponentAllowed(componentName);\n if (!isAllowed) {\n const errorMsg = `Component \"${componentName}\" is not available in your trial plan. Please upgrade to access all components.`;\n console.error(`\u274C ${errorMsg}`);\n throw new Error(errorMsg);\n }\n\n console.log(`\uD83D\uDCE5 Downloading ${componentName}...`);\n\n // Try to fetch from custom components first if ff-id is available\n let componentData;\n let isCustom = false;\n \n if (this.ffId) {\n const customUrl = this.getRegistryUrl(componentName, { custom: true });\n try {\n componentData = await this.fetchJson(customUrl);\n isCustom = true;\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 Found custom component for ${componentName}`);\n }\n } catch (error) {\n // Custom component not found, try standard registry in the same\n // generation. Other failures should be explicit: silently installing\n // the standard component on a registry/server error could hide a\n // customer-specific override problem.\n if (!error.message.includes('404')) {\n throw new Error(`Failed to fetch custom component \"${componentName}\": ${error.message}`);\n }\n\n if (process.env.FF_DEBUG) {\n console.log(` \u2192 No custom component found for ${componentName}, trying standard`);\n }\n }\n }\n \n // If not found in custom, try standard registry\n if (!componentData) {\n const url = this.getRegistryUrl(componentName);\n \n try {\n componentData = await this.fetchJson(url);\n } catch (error) {\n // Check if it's a 404 (component not found)\n if (error.message.includes('404')) {\n if (this.registryGeneration === 'v4') {\n throw new Error(`Tailwind v4 component \"${componentName}\" not migrated for ${this.framework}`);\n }\n throw new Error(`Component \"${componentName}\" not found`);\n }\n throw new Error(`Failed to fetch ${componentName}: ${error.message}`);\n }\n }\n\n // Validate component data\n if (!componentData.files || !Array.isArray(componentData.files)) {\n throw new Error(`Invalid component data for ${componentName}`);\n }\n\n // Download registry dependencies. For v4, dependencies are required and\n // must be installed before writing the parent component to avoid partial\n // installs when the v4 registry slice is incomplete.\n const allDependencies = [...(componentData.dependencies || [])];\n const registryDependencies = (componentData.registryDependencies || []).map(dep => {\n try {\n return {\n dep,\n dependencyName: this.getRegistryDependencyName(dep)\n };\n } catch (error) {\n if (this.registryGeneration === 'v4') {\n throw new Error(\n `Failed to download required v4 registry dependency \"${dep}\" for \"${componentName}\": ${error.message}`\n );\n }\n\n throw error;\n }\n });\n const installRegistryDependencies = async () => {\n if (registryDependencies.length > 0) {\n console.log(` \uD83D\uDCE6 Installing registry dependencies: ${registryDependencies.map(({ dep }) => dep).join(', ')}`);\n\n for (const { dep, dependencyName } of registryDependencies) {\n try {\n const depDeps = await this.downloadComponent(dependencyName);\n depDeps.forEach(d => allDependencies.push(d));\n } catch (error) {\n if (this.registryGeneration === 'v4') {\n throw new Error(\n `Failed to download required v4 registry dependency \"${dep}\" for \"${componentName}\": ${error.message}`\n );\n }\n\n console.warn(` \u26A0\uFE0F Failed to download dependency ${dep}: ${error.message}`);\n }\n }\n }\n };\n\n if (this.registryGeneration === 'v4') {\n await installRegistryDependencies();\n }\n\n // Write component files\n for (const file of componentData.files) {\n await this.writeComponentFile(file);\n }\n\n this.downloadedComponents.add(componentName);\n console.log(` \u2713 ${componentName} downloaded${isCustom && process.env.FF_DEBUG ? ' (custom)' : ''}`);\n \n if (this.registryGeneration !== 'v4') {\n await installRegistryDependencies();\n }\n\n return allDependencies;\n }\n\n /**\n * Write component file to disk\n */\n async writeComponentFile(file) {\n const registryFilePath = file.target || file.name || file.path;\n if (!registryFilePath) {\n throw new Error('Invalid component file descriptor: missing name/path/target');\n }\n\n const normalizeRegistryPath = (registryPath) => registryPath.split('/').join(path.sep);\n const resolveInside = (baseDir, relativeFilePath, rootDescription) => {\n const resolvedBaseDir = path.resolve(baseDir);\n const resolvedFilePath = path.resolve(resolvedBaseDir, normalizeRegistryPath(relativeFilePath));\n const relativeToBase = path.relative(resolvedBaseDir, resolvedFilePath);\n\n if (\n relativeToBase === '' ||\n relativeToBase.startsWith('..') ||\n path.isAbsolute(relativeToBase)\n ) {\n throw new Error(\n `Unsafe component file path \"${registryFilePath}\": resolves outside ${rootDescription}`\n );\n }\n\n return resolvedFilePath;\n };\n\n let filePath;\n const targetAliasMatch = file.target?.match(/^@([^/]+)\\//);\n const resolveAliasBasePath = (aliasName) => {\n if (aliasName === 'ui') {\n return path.resolve(this.outputPath);\n }\n\n const configuredAlias = this.config.aliases?.[aliasName];\n const defaultAliasPaths = {\n components: 'components',\n hooks: 'hooks',\n lib: 'lib'\n };\n const aliasPath = configuredAlias || defaultAliasPaths[aliasName] || aliasName;\n const cleanAliasPath = aliasPath\n .replace(/^@\\//, '')\n .replace(/^~\\//, '');\n const resolvedAppRoot = path.resolve(this.appRoot);\n const resolvedAliasPath = path.isAbsolute(cleanAliasPath)\n ? path.resolve(cleanAliasPath)\n : path.resolve(resolvedAppRoot, normalizeRegistryPath(cleanAliasPath));\n const relativeToAppRoot = path.relative(resolvedAppRoot, resolvedAliasPath);\n\n if (\n relativeToAppRoot === '' ||\n relativeToAppRoot.startsWith('..') ||\n path.isAbsolute(relativeToAppRoot)\n ) {\n throw new Error(\n `Unsafe component file path \"${registryFilePath}\": alias @${aliasName} resolves outside app root`\n );\n }\n\n return resolvedAliasPath;\n };\n\n if (file.target?.startsWith('@ui/')) {\n filePath = resolveInside(this.outputPath, file.target.replace(/^@ui\\//, ''), 'output root');\n } else if (targetAliasMatch) {\n const aliasName = targetAliasMatch[1];\n const aliasBasePath = resolveAliasBasePath(aliasName);\n filePath = resolveInside(\n aliasBasePath,\n file.target.replace(new RegExp(`^@${aliasName}/`), ''),\n `@${aliasName} alias root`\n );\n } else if (file.target?.startsWith('~/')) {\n filePath = resolveInside(this.appRoot, file.target.replace(/^~\\//, ''), 'app root');\n } else if (file.target) {\n filePath = resolveInside(this.appRoot, file.target.replace(/^\\/+/, ''), 'app root');\n } else {\n // Normalize the file path for the current platform\n // Convert forward slashes to the platform-specific separator\n filePath = resolveInside(this.outputPath, registryFilePath, 'output root');\n }\n\n const dir = path.dirname(filePath);\n\n // Create directory if it doesn't exist\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Check if file exists and overwrite setting\n if (fs.existsSync(filePath) && !this.overwrite) {\n console.log(` \u26A0\uFE0F Skipping ${registryFilePath} (already exists)`);\n return;\n }\n\n // Normalize line endings to match the platform\n // This prevents git from showing every line as changed\n let normalizedContent = file.content;\n if (os.EOL !== '\\n') {\n // On Windows, replace LF with CRLF\n normalizedContent = file.content.replace(/\\n/g, os.EOL);\n }\n\n // Write file\n fs.writeFileSync(filePath, normalizedContent, 'utf8');\n }\n}\n\nmodule.exports = { ComponentDownloader };\n"],
5
+ "mappings": "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",
6
+ "names": ["require_constants", "__commonJSMin", "exports", "module", "DEFAULT_API_URL", "LEGACY_API_URL", "CACHE_DIR_NAME", "CACHE_FILES", "ENV_VARS", "require_errors", "__commonJSMin", "exports", "module", "APIError", "message", "statusCode", "url", "CacheError", "operation", "ConfigError", "field", "ProcessingError", "token", "require_file_utils", "__commonJSMin", "exports", "module", "fs", "readJsonFileSafe", "filepath", "content", "error", "readFileSafe", "writeJsonFile", "data", "indent", "writeTextFile", "writeModuleExportsFile", "fileExists", "ensureDirectoryExists", "dirpath", "removeDirectory", "require_path_utils", "__commonJSMin", "exports", "module", "path", "fileExists", "findFileUpward", "filename", "startDir", "currentDir", "filePath", "findDirectoryUpward", "dirname", "validator", "possiblePaths", "maxLevels", "i", "parentDir", "dirPath", "findDirectoryWithPaths", "absolutePaths", "p", "require_local_token_reader", "__commonJSMin", "exports", "module", "path", "findDirectoryUpward", "readJsonFileSafe", "readFileSafe", "fileExists", "LocalTokenReader", "ffId", "options", "tokensPath", "dir", "folderMapPath", "folderMap", "figmaPath", "tokenPaths", "results", "key", "paths", "tokenPath", "content", "cachePath", "parseModuleExports", "moduleExports", "fakeModule", "cacheFiles", "processedData", "fileName", "type", "filePath", "value", "val", "require_credentials", "__commonJSMin", "exports", "module", "fs", "path", "os", "https", "http", "URL", "DEFAULT_API_URL", "CREDENTIALS_DIR", "CREDENTIALS_PATH", "getCredentialsPath", "readCredentials", "writeCredentials", "credentials", "deleteCredentials", "isExpired", "skewMs", "createAuthRefreshError", "message", "error", "postJson", "url", "body", "authToken", "resolve", "reject", "parsedUrl", "protocol", "payload", "request", "response", "data", "chunk", "redirectUrl", "parsed", "httpError", "refreshCredentials", "baseURL", "refreshed", "resolveAuthToken", "options", "require_api_client", "__commonJSMin", "exports", "module", "https", "http", "URL", "DEFAULT_API_URL", "LEGACY_API_URL", "ENV_VARS", "APIError", "LocalTokenReader", "resolveAuthToken", "AUTH_REQUIRED_MESSAGE", "getWithOptionalAuth", "protocol", "url", "authToken", "callback", "isAuthRedirect", "response", "body", "_a", "location", "createHttpError", "APIClient", "ffId", "options", "resolve", "reject", "data", "chunk", "parsed", "error", "designSystemUrl", "tokensData", "tokens", "err", "legacyBaseURL", "urls", "results", "processedUrl", "result", "method", "parsedUrl", "payload", "request", "componentsConfig", "customCss", "processedData", "metadata", "saasError", "tokensUrl", "legacyMetadata", "legacyError", "https", "http", "fs", "path", "URL", "os", "DEFAULT_REGISTRY_URL", "SUPPORTED_REGISTRY_GENERATIONS", "ComponentDownloader", "options", "override", "registryConfig", "configuredUrl", "cliGeneration", "configuredGeneration", "value", "packageJsonPath", "packageName", "_a", "_b", "_c", "packageJson", "version", "majorVersion", "reactVersion", "reactMajorVersion", "tailwindMajorVersion", "componentName", "custom", "index", "filename", "dependency", "parsedUrl", "registryUrl", "routeParts", "part", "dependencyGeneration", "dependencyFramework", "dependencyFfId", "fileName", "error", "deps", "cleanPath", "url", "USE_LOCAL", "USE_LOCAL_REGISTRY", "isRegistryUrl", "possiblePaths", "registryPath", "p", "fullPath", "urlPath", "localPath", "content", "resolve", "reject", "response", "data", "chunk", "errorMessage", "errorBody", "components", "comp", "results", "component", "dep", "APIClient", "apiClient", "errorMsg", "componentData", "isCustom", "customUrl", "allDependencies", "registryDependencies", "installRegistryDependencies", "dependencyName", "d", "file", "registryFilePath", "normalizeRegistryPath", "resolveInside", "baseDir", "relativeFilePath", "rootDescription", "resolvedBaseDir", "resolvedFilePath", "relativeToBase", "filePath", "targetAliasMatch", "resolveAliasBasePath", "aliasName", "cleanAliasPath", "resolvedAppRoot", "resolvedAliasPath", "relativeToAppRoot", "aliasBasePath", "dir", "normalizedContent"]
7
7
  }