@frontfriend/tailwind 3.0.1 → 3.0.2

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/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var s=typeof window<"u"&&typeof window.document<"u",_=typeof process<"u"&&process.versions&&process.versions.node,i,o=null;if(_){let{createRequire:r}=await import("module"),e=r(import.meta.url);try{o=e("./index.js"),i=o}catch(t){console.error("[FrontFriend] Failed to load CommonJS module:",t),i=function(){return console.error("[FrontFriend] Plugin failed to load"),{}}}}else i=function(){return s&&console.warn("[FrontFriend] The Tailwind plugin cannot be used directly in browser environments"),{}};function c(){let r=new Map,e={get(t,n){return n===Symbol.toPrimitive||n==="valueOf"?()=>"":n==="toString"||n===Symbol.toStringTag?()=>"":n==="constructor"?Object:(r.has(n)||r.set(n,c()),r.get(n))},has(t,n){return!(typeof n=="symbol"&&n.toString().includes("nodejs.util.inspect"))},ownKeys(t){return[]},getOwnPropertyDescriptor(t,n){return{enumerable:!0,configurable:!0}}};return new Proxy({},e)}function u(r){return!r||typeof r!="object"?c():r}var a=_&&o?o.config:new Proxy({},{_proxyCache:new Map,get(r,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;let t=null;if(typeof __FF_CONFIG__<"u")t=__FF_CONFIG__;else if(typeof process<"u"&&process.env){if(process.env.NEXT_PUBLIC_FF_CONFIG)try{t=JSON.parse(process.env.NEXT_PUBLIC_FF_CONFIG)}catch{console.warn("[FrontFriend] Failed to parse NEXT_PUBLIC_FF_CONFIG")}else if(process.env.__FF_CONFIG__)try{t=JSON.parse(process.env.__FF_CONFIG__)}catch{console.warn("[FrontFriend] Failed to parse __FF_CONFIG__")}}else s&&window.__FF_CONFIG__&&(t=window.__FF_CONFIG__);return t&&e in t?t[e]:(this._proxyCache.has(e)||this._proxyCache.set(e,c()),this._proxyCache.get(e))},has(r,e){return!0},ownKeys(r){return[]},getOwnPropertyDescriptor(r,e){return{enumerable:!0,configurable:!0}}}),F=_&&o?o.iconSet:new Proxy({},{get(r,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;let t=null;if(typeof __FF_ICONS__<"u")t=__FF_ICONS__;else if(typeof process<"u"&&process.env){if(process.env.NEXT_PUBLIC_FF_ICONS)try{t=JSON.parse(process.env.NEXT_PUBLIC_FF_ICONS)}catch{console.warn("[FrontFriend] Failed to parse NEXT_PUBLIC_FF_ICONS")}else if(process.env.__FF_ICONS__)try{t=JSON.parse(process.env.__FF_ICONS__)}catch{console.warn("[FrontFriend] Failed to parse __FF_ICONS__")}}else s&&window.__FF_ICONS__&&(t=window.__FF_ICONS__);return t&&e in t?t[e]:null},has(r,e){return!1},ownKeys(r){return[]},getOwnPropertyDescriptor(r,e){}}),l=i;export{a as config,l as default,u as ffdc,F as iconSet};
1
+ var _=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var s=typeof window<"u"&&typeof window.document<"u",i=typeof process<"u"&&process.versions&&process.versions.node,o=null;var u=i?function(...t){if(!o)try{o=_("module").createRequire(import.meta.url)("./index.js")}catch(e){return console.error("[FrontFriend] Failed to load plugin:",e),{}}return typeof o=="function"?o(...t):o}:function(){return s&&console.warn("[FrontFriend] The Tailwind plugin cannot be used directly in browser environments"),{}};function c(){let t=new Map,e={get(r,n){return n===Symbol.toPrimitive||n==="valueOf"?()=>"":n==="toString"||n===Symbol.toStringTag?()=>"":n==="constructor"?Object:(t.has(n)||t.set(n,c()),t.get(n))},has(r,n){return!(typeof n=="symbol"&&n.toString().includes("nodejs.util.inspect"))},ownKeys(r){return[]},getOwnPropertyDescriptor(r,n){return{enumerable:!0,configurable:!0}}};return new Proxy({},e)}function f(t){return!t||typeof t!="object"?c():t}var l=new Proxy({},{_cjsConfig:null,_proxyCache:new Map,get(t,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;if(i&&!this._cjsConfig&&o&&(this._cjsConfig=o.config),i&&this._cjsConfig&&e in this._cjsConfig)return this._cjsConfig[e];let r=null;if(typeof __FF_CONFIG__<"u")r=__FF_CONFIG__;else if(typeof process<"u"&&process.env){if(process.env.NEXT_PUBLIC_FF_CONFIG)try{r=JSON.parse(process.env.NEXT_PUBLIC_FF_CONFIG)}catch{console.warn("[FrontFriend] Failed to parse NEXT_PUBLIC_FF_CONFIG")}else if(process.env.__FF_CONFIG__)try{r=JSON.parse(process.env.__FF_CONFIG__)}catch{console.warn("[FrontFriend] Failed to parse __FF_CONFIG__")}}else s&&window.__FF_CONFIG__&&(r=window.__FF_CONFIG__);return r&&e in r?r[e]:(this._proxyCache.has(e)||this._proxyCache.set(e,c()),this._proxyCache.get(e))},has(t,e){return!0},ownKeys(t){return[]},getOwnPropertyDescriptor(t,e){return{enumerable:!0,configurable:!0}}}),F=new Proxy({},{_cjsIconSet:null,get(t,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;if(i&&!this._cjsIconSet&&o&&(this._cjsIconSet=o.iconSet),i&&this._cjsIconSet&&e in this._cjsIconSet)return this._cjsIconSet[e];let r=null;if(typeof __FF_ICONS__<"u")r=__FF_ICONS__;else if(typeof process<"u"&&process.env){if(process.env.NEXT_PUBLIC_FF_ICONS)try{r=JSON.parse(process.env.NEXT_PUBLIC_FF_ICONS)}catch{console.warn("[FrontFriend] Failed to parse NEXT_PUBLIC_FF_ICONS")}else if(process.env.__FF_ICONS__)try{r=JSON.parse(process.env.__FF_ICONS__)}catch{console.warn("[FrontFriend] Failed to parse __FF_ICONS__")}}else s&&window.__FF_ICONS__&&(r=window.__FF_ICONS__);return r&&e in r?r[e]:null},has(t,e){return!1},ownKeys(t){return[]},getOwnPropertyDescriptor(t,e){}}),d=u;export{l as config,d as default,f as ffdc,F as iconSet};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.mjs"],
4
- "sourcesContent": ["// ES Module wrapper for frontfriend-tailwind\n// This file provides ES module exports for both Node.js and browser environments\n\n// Determine environment\nconst isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nconst isNode = typeof process !== 'undefined' && process.versions && process.versions.node;\n\n// In Node.js environments, load the full CommonJS plugin\n// In browser environments, provide stubs and proxies\nlet plugin;\nlet cjsModule = null;\n\nif (isNode) {\n // Node.js: Load the CommonJS module synchronously\n // Use createRequire for synchronous loading\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n\n try {\n // Load the full CommonJS module\n cjsModule = require('./index.js');\n\n // Export the plugin function directly\n plugin = cjsModule;\n } catch (error) {\n console.error('[FrontFriend] Failed to load CommonJS module:', error);\n plugin = function() {\n console.error('[FrontFriend] Plugin failed to load');\n return {};\n };\n }\n} else {\n // Browser: Use stub function (Tailwind plugin not usable in browsers)\n plugin = function() {\n if (isBrowser) {\n console.warn('[FrontFriend] The Tailwind plugin cannot be used directly in browser environments');\n }\n return {};\n };\n}\n\n/**\n * Creates a deep proxy that gracefully handles arbitrary nested property access\n * without throwing errors. This is essential for SSR and build-time scenarios\n * where configuration might not be loaded yet.\n *\n * Features:\n * - Infinite depth access: config.a.b.c.d.e never crashes\n * - Referential equality: config.a === config.a (memoized)\n * - Iteration support: Object.keys(), spread operator, for...in\n * - Type coercion: Works with toString, valueOf, Symbol.toPrimitive\n * - 'in' operator: 'property' in config returns true\n *\n * @returns {Proxy} A proxy object that handles any property access safely\n *\n * @example\n * const config = createDeepProxy();\n * const value = config.sidebar.root.wrapper.base; // Never crashes\n * config.a === config.a; // true (referential equality)\n * 'anything' in config; // true\n * Object.keys(config); // []\n */\nfunction createDeepProxy() {\n // Cache for memoization - ensures referential equality\n // This is critical for React dependency arrays and equality checks\n const cache = new Map();\n\n const handler = {\n /**\n * Handles property access with memoization\n * Ensures config.a === config.a for referential equality\n */\n get(target, prop) {\n // Handle special cases for type coercion and inspection\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // Return cached proxy for same property to maintain referential equality\n // This prevents issues with React hooks and memoization\n if (!cache.has(prop)) {\n cache.set(prop, createDeepProxy());\n }\n return cache.get(prop);\n },\n\n /**\n * Handles 'in' operator\n * Makes 'property' in config return true for any property\n */\n has(target, prop) {\n // Return true for all properties except internal symbols\n if (typeof prop === 'symbol' && prop.toString().includes('nodejs.util.inspect')) {\n return false;\n }\n return true;\n },\n\n /**\n * Handles Object.keys(), Object.getOwnPropertyNames(), for...in\n * Returns empty array since proxy represents missing/unknown config\n */\n ownKeys(target) {\n return [];\n },\n\n /**\n * Handles Object.getOwnPropertyDescriptor()\n * Required for proper iteration support with ownKeys\n */\n getOwnPropertyDescriptor(target, prop) {\n return {\n enumerable: true,\n configurable: true,\n };\n },\n };\n\n return new Proxy({}, handler);\n}\n\n/**\n * FrontFriend Design Config (ffdc) - Safe config wrapper with SSR support\n *\n * Wraps configuration objects to prevent crashes during SSR or when config\n * is not yet loaded. Returns actual config if valid, or a deep proxy fallback.\n *\n * This is the recommended way to access config in components to ensure\n * they work during both build-time (SSR) and runtime.\n *\n * @param {Object|null|undefined} config - The configuration object to wrap\n * @returns {Object|Proxy} The config object or a safe deep proxy\n *\n * @example\n * import { config, ffdc } from '@frontfriend/tailwind';\n *\n * // Safe access during SSR - never crashes\n * const sidebarConfig = ffdc(config || {}).sidebar;\n * const className = sidebarConfig.root.wrapper.base; // Always safe\n *\n * @example\n * // In a React component\n * function Sidebar() {\n * const cfg = ffdc(config).sidebar;\n * return <div className={cfg.root.base}>...</div>;\n * }\n */\nexport function ffdc(config) {\n // During SSR or initial load, config might not be available yet\n // Return a deep proxy that handles any property access without crashing\n if (!config || typeof config !== 'object') {\n return createDeepProxy();\n }\n\n return config;\n}\n\n// Export config and iconSet\n// In Node.js, use the CJS module's getters\n// In browser, use proxies with global variable fallbacks\nexport const config = isNode && cjsModule\n ? cjsModule.config\n : new Proxy({}, {\n // Cache for memoized deep proxies\n _proxyCache: new Map(),\n\n get(target, prop) {\n // Handle special cases for console.log, JSON.stringify, etc.\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '[object Object]';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // Try to get config from globals\n let _config = null;\n if (typeof __FF_CONFIG__ !== 'undefined') {\n _config = __FF_CONFIG__;\n } else if (typeof process !== 'undefined' && process.env) {\n if (process.env.NEXT_PUBLIC_FF_CONFIG) {\n try {\n _config = JSON.parse(process.env.NEXT_PUBLIC_FF_CONFIG);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse NEXT_PUBLIC_FF_CONFIG');\n }\n } else if (process.env.__FF_CONFIG__) {\n try {\n _config = JSON.parse(process.env.__FF_CONFIG__);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse __FF_CONFIG__');\n }\n }\n } else if (isBrowser && window.__FF_CONFIG__) {\n _config = window.__FF_CONFIG__;\n }\n\n // Return actual config value if it exists\n if (_config && prop in _config) {\n return _config[prop];\n }\n\n // Return memoized deep proxy for missing properties\n if (!this._proxyCache.has(prop)) {\n this._proxyCache.set(prop, createDeepProxy());\n }\n return this._proxyCache.get(prop);\n },\n\n has(target, prop) {\n return true;\n },\n\n ownKeys(target) {\n return [];\n },\n\n getOwnPropertyDescriptor(target, prop) {\n return {\n enumerable: true,\n configurable: true,\n };\n },\n });\n\nexport const iconSet = isNode && cjsModule\n ? cjsModule.iconSet\n : new Proxy({}, {\n get(target, prop) {\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '[object Object]';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // Try to get icons from globals\n let _iconSet = null;\n if (typeof __FF_ICONS__ !== 'undefined') {\n _iconSet = __FF_ICONS__;\n } else if (typeof process !== 'undefined' && process.env) {\n if (process.env.NEXT_PUBLIC_FF_ICONS) {\n try {\n _iconSet = JSON.parse(process.env.NEXT_PUBLIC_FF_ICONS);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse NEXT_PUBLIC_FF_ICONS');\n }\n } else if (process.env.__FF_ICONS__) {\n try {\n _iconSet = JSON.parse(process.env.__FF_ICONS__);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse __FF_ICONS__');\n }\n }\n } else if (isBrowser && window.__FF_ICONS__) {\n _iconSet = window.__FF_ICONS__;\n }\n\n if (_iconSet && prop in _iconSet) {\n return _iconSet[prop];\n }\n\n return null;\n },\n\n has(target, prop) {\n return false;\n },\n\n ownKeys(target) {\n return [];\n },\n\n getOwnPropertyDescriptor(target, prop) {\n return undefined;\n },\n });\n\n// Default export is the plugin\nexport default plugin;\n"],
5
- "mappings": "AAIA,IAAMA,EAAY,OAAO,OAAW,KAAe,OAAO,OAAO,SAAa,IACxEC,EAAS,OAAO,QAAY,KAAe,QAAQ,UAAY,QAAQ,SAAS,KAIlFC,EACAC,EAAY,KAEhB,GAAIF,EAAQ,CAGV,GAAM,CAAE,cAAAG,CAAc,EAAI,KAAM,QAAO,QAAQ,EACzCC,EAAUD,EAAc,YAAY,GAAG,EAE7C,GAAI,CAEFD,EAAYE,EAAQ,YAAY,EAGhCH,EAASC,CACX,OAASG,EAAO,CACd,QAAQ,MAAM,gDAAiDA,CAAK,EACpEJ,EAAS,UAAW,CAClB,eAAQ,MAAM,qCAAqC,EAC5C,CAAC,CACV,CACF,CACF,MAEEA,EAAS,UAAW,CAClB,OAAIF,GACF,QAAQ,KAAK,mFAAmF,EAE3F,CAAC,CACV,EAwBF,SAASO,GAAkB,CAGzB,IAAMC,EAAQ,IAAI,IAEZC,EAAU,CAKd,IAAIC,EAAQC,EAAM,CAEhB,OAAIA,IAAS,OAAO,aAAeA,IAAS,UACnC,IAAM,GAEXA,IAAS,YAAcA,IAAS,OAAO,YAClC,IAAM,GAEXA,IAAS,cACJ,QAKJH,EAAM,IAAIG,CAAI,GACjBH,EAAM,IAAIG,EAAMJ,EAAgB,CAAC,EAE5BC,EAAM,IAAIG,CAAI,EACvB,EAMA,IAAID,EAAQC,EAAM,CAEhB,MAAI,SAAOA,GAAS,UAAYA,EAAK,SAAS,EAAE,SAAS,qBAAqB,EAIhF,EAMA,QAAQD,EAAQ,CACd,MAAO,CAAC,CACV,EAMA,yBAAyBA,EAAQC,EAAM,CACrC,MAAO,CACL,WAAY,GACZ,aAAc,EAChB,CACF,CACF,EAEA,OAAO,IAAI,MAAM,CAAC,EAAGF,CAAO,CAC9B,CA4BO,SAASG,EAAKC,EAAQ,CAG3B,MAAI,CAACA,GAAU,OAAOA,GAAW,SACxBN,EAAgB,EAGlBM,CACT,CAKO,IAAMA,EAASZ,GAAUE,EAC5BA,EAAU,OACV,IAAI,MAAM,CAAC,EAAG,CAEZ,YAAa,IAAI,IAEjB,IAAIO,EAAQC,EAAM,CAEhB,GAAIA,IAAS,OAAO,aAAeA,IAAS,UAC1C,MAAO,IAAM,GAEf,GAAIA,IAAS,YAAcA,IAAS,OAAO,YACzC,MAAO,IAAM,kBAEf,GAAIA,IAAS,cACX,OAAO,OAIT,IAAIG,EAAU,KACd,GAAI,OAAO,cAAkB,IAC3BA,EAAU,sBACD,OAAO,QAAY,KAAe,QAAQ,KACnD,GAAI,QAAQ,IAAI,sBACd,GAAI,CACFA,EAAU,KAAK,MAAM,QAAQ,IAAI,qBAAqB,CACxD,MAAY,CACV,QAAQ,KAAK,qDAAqD,CACpE,SACS,QAAQ,IAAI,cACrB,GAAI,CACFA,EAAU,KAAK,MAAM,QAAQ,IAAI,aAAa,CAChD,MAAY,CACV,QAAQ,KAAK,6CAA6C,CAC5D,OAEOd,GAAa,OAAO,gBAC7Bc,EAAU,OAAO,eAInB,OAAIA,GAAWH,KAAQG,EACdA,EAAQH,CAAI,GAIhB,KAAK,YAAY,IAAIA,CAAI,GAC5B,KAAK,YAAY,IAAIA,EAAMJ,EAAgB,CAAC,EAEvC,KAAK,YAAY,IAAII,CAAI,EAClC,EAEA,IAAID,EAAQC,EAAM,CAChB,MAAO,EACT,EAEA,QAAQD,EAAQ,CACd,MAAO,CAAC,CACV,EAEA,yBAAyBA,EAAQC,EAAM,CACrC,MAAO,CACL,WAAY,GACZ,aAAc,EAChB,CACF,CACF,CAAC,EAEQI,EAAUd,GAAUE,EAC7BA,EAAU,QACV,IAAI,MAAM,CAAC,EAAG,CACZ,IAAIO,EAAQC,EAAM,CAChB,GAAIA,IAAS,OAAO,aAAeA,IAAS,UAC1C,MAAO,IAAM,GAEf,GAAIA,IAAS,YAAcA,IAAS,OAAO,YACzC,MAAO,IAAM,kBAEf,GAAIA,IAAS,cACX,OAAO,OAIT,IAAIK,EAAW,KACf,GAAI,OAAO,aAAiB,IAC1BA,EAAW,qBACF,OAAO,QAAY,KAAe,QAAQ,KACnD,GAAI,QAAQ,IAAI,qBACd,GAAI,CACFA,EAAW,KAAK,MAAM,QAAQ,IAAI,oBAAoB,CACxD,MAAY,CACV,QAAQ,KAAK,oDAAoD,CACnE,SACS,QAAQ,IAAI,aACrB,GAAI,CACFA,EAAW,KAAK,MAAM,QAAQ,IAAI,YAAY,CAChD,MAAY,CACV,QAAQ,KAAK,4CAA4C,CAC3D,OAEOhB,GAAa,OAAO,eAC7BgB,EAAW,OAAO,cAGpB,OAAIA,GAAYL,KAAQK,EACfA,EAASL,CAAI,EAGf,IACT,EAEA,IAAID,EAAQC,EAAM,CAChB,MAAO,EACT,EAEA,QAAQD,EAAQ,CACd,MAAO,CAAC,CACV,EAEA,yBAAyBA,EAAQC,EAAM,CAEvC,CACF,CAAC,EAGEM,EAAQf",
6
- "names": ["isBrowser", "isNode", "plugin", "cjsModule", "createRequire", "require", "error", "createDeepProxy", "cache", "handler", "target", "prop", "ffdc", "config", "_config", "iconSet", "_iconSet", "frontfriend_tailwind_default"]
4
+ "sourcesContent": ["// ES Module wrapper for frontfriend-tailwind\n// This file provides ES module exports for both Node.js and browser environments\n\n// Determine environment\nconst isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nconst isNode = typeof process !== 'undefined' && process.versions && process.versions.node;\n\n// Lazy-loaded CJS module reference\nlet cjsModule = null;\nlet cjsModulePromise = null;\n\n// Lazy loader for CJS module (only loads when needed)\nasync function loadCjsModule() {\n if (cjsModule) return cjsModule;\n if (cjsModulePromise) return cjsModulePromise;\n\n cjsModulePromise = (async () => {\n try {\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n cjsModule = require('./index.js');\n return cjsModule;\n } catch (error) {\n console.error('[FrontFriend] Failed to load CommonJS module:', error);\n throw error;\n }\n })();\n\n return cjsModulePromise;\n}\n\n// Create plugin function that loads CJS module on demand\nconst plugin = isNode\n ? function(...args) {\n // Synchronous require - this works because Node.js supports it\n if (!cjsModule) {\n try {\n // Use dynamic require - only available in Node.js\n const module = require('module');\n const req = module.createRequire(import.meta.url);\n cjsModule = req('./index.js');\n } catch (error) {\n console.error('[FrontFriend] Failed to load plugin:', error);\n return {};\n }\n }\n return typeof cjsModule === 'function' ? cjsModule(...args) : cjsModule;\n }\n : function() {\n // Browser: Use stub function\n if (isBrowser) {\n console.warn('[FrontFriend] The Tailwind plugin cannot be used directly in browser environments');\n }\n return {};\n };\n\n/**\n * Creates a deep proxy that gracefully handles arbitrary nested property access\n * without throwing errors. This is essential for SSR and build-time scenarios\n * where configuration might not be loaded yet.\n *\n * Features:\n * - Infinite depth access: config.a.b.c.d.e never crashes\n * - Referential equality: config.a === config.a (memoized)\n * - Iteration support: Object.keys(), spread operator, for...in\n * - Type coercion: Works with toString, valueOf, Symbol.toPrimitive\n * - 'in' operator: 'property' in config returns true\n *\n * @returns {Proxy} A proxy object that handles any property access safely\n *\n * @example\n * const config = createDeepProxy();\n * const value = config.sidebar.root.wrapper.base; // Never crashes\n * config.a === config.a; // true (referential equality)\n * 'anything' in config; // true\n * Object.keys(config); // []\n */\nfunction createDeepProxy() {\n // Cache for memoization - ensures referential equality\n // This is critical for React dependency arrays and equality checks\n const cache = new Map();\n\n const handler = {\n /**\n * Handles property access with memoization\n * Ensures config.a === config.a for referential equality\n */\n get(target, prop) {\n // Handle special cases for type coercion and inspection\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // Return cached proxy for same property to maintain referential equality\n // This prevents issues with React hooks and memoization\n if (!cache.has(prop)) {\n cache.set(prop, createDeepProxy());\n }\n return cache.get(prop);\n },\n\n /**\n * Handles 'in' operator\n * Makes 'property' in config return true for any property\n */\n has(target, prop) {\n // Return true for all properties except internal symbols\n if (typeof prop === 'symbol' && prop.toString().includes('nodejs.util.inspect')) {\n return false;\n }\n return true;\n },\n\n /**\n * Handles Object.keys(), Object.getOwnPropertyNames(), for...in\n * Returns empty array since proxy represents missing/unknown config\n */\n ownKeys(target) {\n return [];\n },\n\n /**\n * Handles Object.getOwnPropertyDescriptor()\n * Required for proper iteration support with ownKeys\n */\n getOwnPropertyDescriptor(target, prop) {\n return {\n enumerable: true,\n configurable: true,\n };\n },\n };\n\n return new Proxy({}, handler);\n}\n\n/**\n * FrontFriend Design Config (ffdc) - Safe config wrapper with SSR support\n *\n * Wraps configuration objects to prevent crashes during SSR or when config\n * is not yet loaded. Returns actual config if valid, or a deep proxy fallback.\n *\n * This is the recommended way to access config in components to ensure\n * they work during both build-time (SSR) and runtime.\n *\n * @param {Object|null|undefined} config - The configuration object to wrap\n * @returns {Object|Proxy} The config object or a safe deep proxy\n *\n * @example\n * import { config, ffdc } from '@frontfriend/tailwind';\n *\n * // Safe access during SSR - never crashes\n * const sidebarConfig = ffdc(config || {}).sidebar;\n * const className = sidebarConfig.root.wrapper.base; // Always safe\n *\n * @example\n * // In a React component\n * function Sidebar() {\n * const cfg = ffdc(config).sidebar;\n * return <div className={cfg.root.base}>...</div>;\n * }\n */\nexport function ffdc(config) {\n // During SSR or initial load, config might not be available yet\n // Return a deep proxy that handles any property access without crashing\n if (!config || typeof config !== 'object') {\n return createDeepProxy();\n }\n\n return config;\n}\n\n// Export config and iconSet with lazy getters\n// In Node.js, load CJS module on first access\n// In browser, use proxies with global variable fallbacks\nexport const config = new Proxy({}, {\n // Cache for the loaded CJS module config\n _cjsConfig: null,\n // Cache for memoized deep proxies\n _proxyCache: new Map(),\n\n get(target, prop) {\n // Handle special cases for console.log, JSON.stringify, etc.\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '[object Object]';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // In Node.js, try to get config from CJS module first\n if (isNode && !this._cjsConfig && cjsModule) {\n this._cjsConfig = cjsModule.config;\n }\n\n if (isNode && this._cjsConfig && prop in this._cjsConfig) {\n return this._cjsConfig[prop];\n }\n\n // Try to get config from globals\n let _config = null;\n if (typeof __FF_CONFIG__ !== 'undefined') {\n _config = __FF_CONFIG__;\n } else if (typeof process !== 'undefined' && process.env) {\n if (process.env.NEXT_PUBLIC_FF_CONFIG) {\n try {\n _config = JSON.parse(process.env.NEXT_PUBLIC_FF_CONFIG);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse NEXT_PUBLIC_FF_CONFIG');\n }\n } else if (process.env.__FF_CONFIG__) {\n try {\n _config = JSON.parse(process.env.__FF_CONFIG__);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse __FF_CONFIG__');\n }\n }\n } else if (isBrowser && window.__FF_CONFIG__) {\n _config = window.__FF_CONFIG__;\n }\n\n // Return actual config value if it exists\n if (_config && prop in _config) {\n return _config[prop];\n }\n\n // Return memoized deep proxy for missing properties\n if (!this._proxyCache.has(prop)) {\n this._proxyCache.set(prop, createDeepProxy());\n }\n return this._proxyCache.get(prop);\n },\n\n has(target, prop) {\n return true;\n },\n\n ownKeys(target) {\n return [];\n },\n\n getOwnPropertyDescriptor(target, prop) {\n return {\n enumerable: true,\n configurable: true,\n };\n },\n });\n\nexport const iconSet = new Proxy({}, {\n // Cache for the loaded CJS module iconSet\n _cjsIconSet: null,\n\n get(target, prop) {\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => '';\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => '[object Object]';\n }\n if (prop === 'constructor') {\n return Object;\n }\n\n // In Node.js, try to get iconSet from CJS module first\n if (isNode && !this._cjsIconSet && cjsModule) {\n this._cjsIconSet = cjsModule.iconSet;\n }\n\n if (isNode && this._cjsIconSet && prop in this._cjsIconSet) {\n return this._cjsIconSet[prop];\n }\n\n // Try to get icons from globals\n let _iconSet = null;\n if (typeof __FF_ICONS__ !== 'undefined') {\n _iconSet = __FF_ICONS__;\n } else if (typeof process !== 'undefined' && process.env) {\n if (process.env.NEXT_PUBLIC_FF_ICONS) {\n try {\n _iconSet = JSON.parse(process.env.NEXT_PUBLIC_FF_ICONS);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse NEXT_PUBLIC_FF_ICONS');\n }\n } else if (process.env.__FF_ICONS__) {\n try {\n _iconSet = JSON.parse(process.env.__FF_ICONS__);\n } catch (e) {\n console.warn('[FrontFriend] Failed to parse __FF_ICONS__');\n }\n }\n } else if (isBrowser && window.__FF_ICONS__) {\n _iconSet = window.__FF_ICONS__;\n }\n\n if (_iconSet && prop in _iconSet) {\n return _iconSet[prop];\n }\n\n return null;\n },\n\n has(target, prop) {\n return false;\n },\n\n ownKeys(target) {\n return [];\n },\n\n getOwnPropertyDescriptor(target, prop) {\n return undefined;\n },\n });\n\n// Default export is the plugin\nexport default plugin;\n"],
5
+ "mappings": "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",
6
+ "names": ["isBrowser", "isNode", "cjsModule", "plugin", "isNode", "args", "cjsModule", "error", "isBrowser", "createDeepProxy", "cache", "handler", "target", "prop", "ffdc", "config", "_config", "iconSet", "_iconSet", "frontfriend_tailwind_default"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontfriend/tailwind",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Design token management for Tailwind CSS",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/types/index.d.ts",