@frontfriend/tailwind 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js.map CHANGED
@@ -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/cache-manager.js", "../vite.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://tokens-studio-donux.up.railway.app/api';\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 'cls.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_USE_LOCAL_REGISTRY: 'FF_USE_LOCAL_REGISTRY'\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 this.code = `CONFIG_${field.toUpperCase()}`;\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 * @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 return fs.readFileSync(filepath, 'utf8');\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 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 writeModuleExportsFile,\n fileExists,\n ensureDirectoryExists,\n removeDirectory\n};", "const path = require('path');\nconst { CACHE_DIR_NAME, CACHE_TTL_MS, CACHE_FILES } = require('./constants');\nconst { CacheError } = require('./errors');\nconst { readJsonFileSafe, readFileSafe, writeJsonFile, writeModuleExportsFile, fileExists, ensureDirectoryExists, removeDirectory } = require('./file-utils');\n\nclass CacheManager {\n constructor(appRoot = process.cwd()) {\n this.appRoot = appRoot;\n this.cacheDir = path.join(appRoot, 'node_modules', CACHE_DIR_NAME);\n this.metadataFile = path.join(this.cacheDir, 'metadata.json');\n this.maxAge = CACHE_TTL_MS;\n }\n\n /**\n * Get the cache directory path\n * @returns {string} Cache directory path\n */\n getCacheDir() {\n return this.cacheDir;\n }\n\n /**\n * Check if cache directory exists\n * @returns {boolean} True if cache exists\n */\n exists() {\n return fileExists(this.cacheDir);\n }\n\n /**\n * Check if cache is valid (exists and not expired)\n * @returns {boolean} True if cache is valid\n */\n isValid() {\n if (!this.exists()) {\n return false;\n }\n\n try {\n const metadata = readJsonFileSafe(this.metadataFile);\n if (!metadata) {\n return false;\n }\n\n const timestamp = new Date(metadata.timestamp).getTime();\n const now = Date.now();\n \n return (now - timestamp) < this.maxAge;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Load all cached data\n * @returns {Object|null} Cached data object or null if not found\n */\n load() {\n if (!this.exists()) {\n return null;\n }\n\n try {\n const data = {};\n \n // Load all .js files\n for (const file of CACHE_FILES.JS) {\n const filePath = path.join(this.cacheDir, file);\n if (fileExists(filePath)) {\n // Remove .js extension for key\n const key = file.replace('.js', '');\n try {\n // Use a more secure approach - parse the exported data\n const content = readFileSafe(filePath);\n if (content !== null) {\n // Create a safe evaluation context\n const moduleExports = {};\n const fakeModule = { exports: moduleExports };\n \n // Use Function constructor to evaluate in isolated scope\n const evalFunc = new Function('module', 'exports', content);\n evalFunc(fakeModule, moduleExports);\n \n data[key] = fakeModule.exports;\n }\n } catch (e) {\n // Skip files that can't be parsed\n }\n }\n }\n\n // Load all .json files\n for (const file of CACHE_FILES.JSON) {\n const filePath = path.join(this.cacheDir, file);\n const key = file.replace('.json', '');\n const content = readJsonFileSafe(filePath);\n if (content !== null) {\n data[key] = content;\n }\n }\n\n // Rename components-config to componentsConfig for consistency\n if (data['components-config']) {\n data.componentsConfig = data['components-config'];\n delete data['components-config'];\n }\n\n return data;\n } catch (error) {\n throw new CacheError(`Failed to load cache: ${error.message}`, 'read');\n }\n }\n\n /**\n * Save data to cache\n * @param {Object} data - Data object to save\n * @throws {Error} If save operation fails\n */\n save(data) {\n try {\n // Create cache directory\n ensureDirectoryExists(this.cacheDir);\n\n // Save metadata first\n const metadata = {\n timestamp: new Date().toISOString(),\n version: data.metadata?.version || '2.0.0',\n ffId: data.metadata?.ffId\n };\n writeJsonFile(this.metadataFile, metadata);\n\n // Save .js files\n const jsFiles = [\n 'tokens',\n 'variables',\n 'semanticVariables',\n 'semanticDarkVariables',\n 'cls',\n 'custom'\n ];\n\n for (const key of jsFiles) {\n if (data[key] !== undefined) {\n const filePath = path.join(this.cacheDir, `${key}.js`);\n writeModuleExportsFile(filePath, data[key]);\n }\n }\n\n // Save .json files\n const jsonData = {\n fonts: data.fonts,\n icons: data.icons || data.iconSet,\n 'components-config': data.componentsConfig,\n version: data.version\n };\n\n for (const [key, value] of Object.entries(jsonData)) {\n if (value !== undefined) {\n const filePath = path.join(this.cacheDir, `${key}.json`);\n writeJsonFile(filePath, value);\n }\n }\n } catch (error) {\n throw new CacheError(`Failed to save cache: ${error.message}`, 'write');\n }\n }\n\n /**\n * Clear the cache directory\n */\n clear() {\n if (this.exists()) {\n removeDirectory(this.cacheDir);\n }\n }\n}\n\nmodule.exports = CacheManager;", "// CommonJS wrapper for vite.mjs to support Jest testing\nmodule.exports = function vitePlugin() {\n // Return a mock plugin for testing\n let config;\n \n return {\n name: 'frontfriend-tailwind',\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n load(id) {\n if (id === 'virtual:frontfriend-config') {\n // Mock implementation for testing\n try {\n const CacheManager = require('./lib/core/cache-manager');\n const cacheManager = new CacheManager(config?.root || process.cwd());\n \n if (!cacheManager.exists()) {\n console.warn('[FrontFriend Vite] No cache found. Please run \"npx frontfriend init\" first.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n let cache;\n try {\n cache = cacheManager.load();\n } catch (error) {\n console.error('[FrontFriend Vite] Failed to load cache.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n if (!cache) {\n console.error('[FrontFriend Vite] Failed to load cache.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n const componentsConfig = cache.componentsConfig || null;\n const icons = cache.icons || null;\n \n if (config?.command === 'serve') {\n console.log('[FrontFriend Vite] Injected configuration and icons into build');\n }\n \n return `\n globalThis.__FF_CONFIG__ = ${JSON.stringify(componentsConfig)};\n globalThis.__FF_ICONS__ = ${JSON.stringify(icons)};\n `;\n } catch (error) {\n // Handle any errors gracefully\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n }\n \n return null;\n }\n };\n};"],
5
- "mappings": "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",
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://tokens-studio-donux.up.railway.app/api';\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 'cls.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};\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 this.code = `CONFIG_${field.toUpperCase()}`;\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 * @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 return fs.readFileSync(filepath, 'utf8');\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 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 writeModuleExportsFile,\n fileExists,\n ensureDirectoryExists,\n removeDirectory\n};", "const path = require('path');\nconst { CACHE_DIR_NAME, CACHE_TTL_MS, CACHE_FILES } = require('./constants');\nconst { CacheError } = require('./errors');\nconst { readJsonFileSafe, readFileSafe, writeJsonFile, writeModuleExportsFile, fileExists, ensureDirectoryExists, removeDirectory } = require('./file-utils');\n\nclass CacheManager {\n constructor(appRoot = process.cwd()) {\n this.appRoot = appRoot;\n this.cacheDir = path.join(appRoot, 'node_modules', CACHE_DIR_NAME);\n this.metadataFile = path.join(this.cacheDir, 'metadata.json');\n this.maxAge = CACHE_TTL_MS;\n }\n\n /**\n * Get the cache directory path\n * @returns {string} Cache directory path\n */\n getCacheDir() {\n return this.cacheDir;\n }\n\n /**\n * Check if cache directory exists\n * @returns {boolean} True if cache exists\n */\n exists() {\n return fileExists(this.cacheDir);\n }\n\n /**\n * Check if cache is valid (exists and not expired)\n * @returns {boolean} True if cache is valid\n */\n isValid() {\n if (!this.exists()) {\n return false;\n }\n\n try {\n const metadata = readJsonFileSafe(this.metadataFile);\n if (!metadata) {\n return false;\n }\n\n const timestamp = new Date(metadata.timestamp).getTime();\n const now = Date.now();\n \n return (now - timestamp) < this.maxAge;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Load all cached data\n * @returns {Object|null} Cached data object or null if not found\n */\n load() {\n if (!this.exists()) {\n return null;\n }\n\n try {\n const data = {};\n \n // Load all .js files\n for (const file of CACHE_FILES.JS) {\n const filePath = path.join(this.cacheDir, file);\n if (fileExists(filePath)) {\n // Remove .js extension for key\n const key = file.replace('.js', '');\n try {\n // Use a more secure approach - parse the exported data\n const content = readFileSafe(filePath);\n if (content !== null) {\n // Create a safe evaluation context\n const moduleExports = {};\n const fakeModule = { exports: moduleExports };\n \n // Use Function constructor to evaluate in isolated scope\n const evalFunc = new Function('module', 'exports', content);\n evalFunc(fakeModule, moduleExports);\n \n data[key] = fakeModule.exports;\n }\n } catch (e) {\n // Skip files that can't be parsed\n }\n }\n }\n\n // Load all .json files\n for (const file of CACHE_FILES.JSON) {\n const filePath = path.join(this.cacheDir, file);\n const key = file.replace('.json', '');\n const content = readJsonFileSafe(filePath);\n if (content !== null) {\n data[key] = content;\n }\n }\n\n // Rename components-config to componentsConfig for consistency\n if (data['components-config']) {\n data.componentsConfig = data['components-config'];\n delete data['components-config'];\n }\n\n return data;\n } catch (error) {\n throw new CacheError(`Failed to load cache: ${error.message}`, 'read');\n }\n }\n\n /**\n * Save data to cache\n * @param {Object} data - Data object to save\n * @throws {Error} If save operation fails\n */\n save(data) {\n try {\n // Create cache directory\n ensureDirectoryExists(this.cacheDir);\n\n // Save metadata first\n const metadata = {\n timestamp: new Date().toISOString(),\n version: data.metadata?.version || '2.0.0',\n ffId: data.metadata?.ffId\n };\n writeJsonFile(this.metadataFile, metadata);\n\n // Save .js files\n const jsFiles = [\n 'tokens',\n 'variables',\n 'semanticVariables',\n 'semanticDarkVariables',\n 'cls',\n 'custom'\n ];\n\n for (const key of jsFiles) {\n if (data[key] !== undefined) {\n const filePath = path.join(this.cacheDir, `${key}.js`);\n writeModuleExportsFile(filePath, data[key]);\n }\n }\n\n // Save .json files\n const jsonData = {\n fonts: data.fonts,\n icons: data.icons || data.iconSet,\n 'components-config': data.componentsConfig,\n version: data.version\n };\n\n for (const [key, value] of Object.entries(jsonData)) {\n if (value !== undefined) {\n const filePath = path.join(this.cacheDir, `${key}.json`);\n writeJsonFile(filePath, value);\n }\n }\n } catch (error) {\n throw new CacheError(`Failed to save cache: ${error.message}`, 'write');\n }\n }\n\n /**\n * Clear the cache directory\n */\n clear() {\n if (this.exists()) {\n removeDirectory(this.cacheDir);\n }\n }\n}\n\nmodule.exports = CacheManager;", "// CommonJS wrapper for vite.mjs to support Jest testing\nmodule.exports = function vitePlugin() {\n // Return a mock plugin for testing\n let config;\n \n return {\n name: 'frontfriend-tailwind',\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n load(id) {\n if (id === 'virtual:frontfriend-config') {\n // Mock implementation for testing\n try {\n const CacheManager = require('./lib/core/cache-manager');\n const cacheManager = new CacheManager(config?.root || process.cwd());\n \n if (!cacheManager.exists()) {\n console.warn('[FrontFriend Vite] No cache found. Please run \"npx frontfriend init\" first.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n let cache;\n try {\n cache = cacheManager.load();\n } catch (error) {\n console.error('[FrontFriend Vite] Failed to load cache.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n if (!cache) {\n console.error('[FrontFriend Vite] Failed to load cache.');\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n \n const componentsConfig = cache.componentsConfig || null;\n const icons = cache.icons || null;\n \n if (config?.command === 'serve') {\n console.log('[FrontFriend Vite] Injected configuration and icons into build');\n }\n \n return `\n globalThis.__FF_CONFIG__ = ${JSON.stringify(componentsConfig)};\n globalThis.__FF_ICONS__ = ${JSON.stringify(icons)};\n `;\n } catch (error) {\n // Handle any errors gracefully\n return `\n globalThis.__FF_CONFIG__ = null;\n globalThis.__FF_ICONS__ = null;\n `;\n }\n }\n \n return null;\n }\n };\n};"],
5
+ "mappings": "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",
6
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", "writeModuleExportsFile", "fileExists", "ensureDirectoryExists", "dirpath", "removeDirectory", "require_cache_manager", "__commonJSMin", "exports", "module", "path", "CACHE_DIR_NAME", "CACHE_TTL_MS", "CACHE_FILES", "CacheError", "readJsonFileSafe", "readFileSafe", "writeJsonFile", "writeModuleExportsFile", "fileExists", "ensureDirectoryExists", "removeDirectory", "CacheManager", "appRoot", "metadata", "timestamp", "data", "file", "filePath", "key", "content", "moduleExports", "fakeModule", "error", "_a", "_b", "jsFiles", "jsonData", "value", "config", "resolvedConfig", "id", "CacheManager", "cacheManager", "cache", "componentsConfig", "icons"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontfriend/tailwind",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Design token management for Tailwind CSS",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/types/index.d.ts",