@frontfriend/tailwind 3.0.4 → 4.0.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.
Files changed (51) hide show
  1. package/README.md +94 -1
  2. package/dist/browser.mjs +2 -0
  3. package/dist/browser.mjs.map +7 -0
  4. package/dist/cli.js +47 -41
  5. package/dist/components-config-schema.d.ts +2 -0
  6. package/dist/components-config-schema.js +2 -0
  7. package/dist/components-config-schema.js.map +7 -0
  8. package/dist/ffdc.d.ts +3 -1
  9. package/dist/ffdc.js +1 -1
  10. package/dist/ffdc.js.map +4 -4
  11. package/dist/index.js +3 -3
  12. package/dist/index.js.map +4 -4
  13. package/dist/index.mjs +1 -1
  14. package/dist/index.mjs.map +3 -3
  15. package/dist/lib/core/api-client.js +2 -1
  16. package/dist/lib/core/api-client.js.map +4 -4
  17. package/dist/lib/core/cache-manager.js +11 -2
  18. package/dist/lib/core/component-downloader.js +3 -2
  19. package/dist/lib/core/component-downloader.js.map +4 -4
  20. package/dist/lib/core/components-config-schema.js +2 -0
  21. package/dist/lib/core/components-config-schema.js.map +7 -0
  22. package/dist/lib/core/constants.js +1 -1
  23. package/dist/lib/core/constants.js.map +2 -2
  24. package/dist/lib/core/credentials.js +3 -0
  25. package/dist/lib/core/credentials.js.map +7 -0
  26. package/dist/lib/core/default-config-data.js +2 -0
  27. package/dist/lib/core/default-config-data.js.map +7 -0
  28. package/dist/lib/core/default-config.js +2 -0
  29. package/dist/lib/core/default-config.js.map +7 -0
  30. package/dist/lib/core/env-utils.js +1 -1
  31. package/dist/lib/core/env-utils.js.map +3 -3
  32. package/dist/lib/core/file-utils.js +1 -1
  33. package/dist/lib/core/file-utils.js.map +3 -3
  34. package/dist/lib/core/local-token-reader.js +1 -1
  35. package/dist/lib/core/local-token-reader.js.map +3 -3
  36. package/dist/lib/core/path-utils.js +1 -1
  37. package/dist/lib/core/path-utils.js.map +3 -3
  38. package/dist/lib/core/token-processor.js +3 -1
  39. package/dist/lib/core/token-processor.js.map +3 -3
  40. package/dist/next.js +1 -1
  41. package/dist/next.js.map +4 -4
  42. package/dist/types/index.d.ts +107 -11
  43. package/dist/vite.js +13 -8
  44. package/dist/vite.js.map +4 -4
  45. package/dist/vite.mjs +6 -1
  46. package/dist/vite.mjs.map +3 -3
  47. package/package.json +15 -5
  48. package/scripts/build.js +21 -4
  49. package/scripts/master-components-config.json +953 -0
  50. package/scripts/update-default-config-data.js +690 -0
  51. package/src/theme.css +9 -0
package/README.md CHANGED
@@ -51,6 +51,37 @@ module.exports = {
51
51
  }
52
52
  ```
53
53
 
54
+ ### Tailwind v4 CSS-first setup
55
+
56
+ For Tailwind v4 projects, run `init` as usual and import the generated FrontFriend CSS theme from your app CSS:
57
+
58
+ ```css
59
+ @import "tailwindcss";
60
+ @import "@frontfriend/tailwind/theme.css";
61
+ ```
62
+
63
+ FrontFriend keeps readable semantic utility classes such as `bg-brand-mid`, `text-onbrand-strong`, and `border-neutral-subtle`.
64
+ The generated cache theme provides Tailwind v4 `@theme`, `@utility`, and `@source` output so registry components do not need arbitrary CSS-variable class names.
65
+
66
+ Use the v4 component registry for Tailwind v4/React 19 apps:
67
+
68
+ ```bash
69
+ npx frontfriend add button --registry v4
70
+ ```
71
+
72
+ The initial v4 React registry intentionally includes only `button, icon, and spinner`.
73
+ Requests for non-migrated v4 components fail explicitly instead of falling back to legacy components.
74
+
75
+ #### Installable with the shadcn CLI
76
+
77
+ v4 items are shadcn-protocol-compliant and can be added directly with the shadcn CLI:
78
+
79
+ ```bash
80
+ npx shadcn@latest add https://registry.frontfriend.dev/r/v4/react/button.json
81
+ ```
82
+
83
+ Each v4 item declares `@frontfriend/tailwind` in its `dependencies` so the shadcn CLI installs it automatically. After the first install, run `npx frontfriend init` once and import `@frontfriend/tailwind/theme.css` from your app CSS to get the generated v4 theme.
84
+
54
85
  ## Framework Integration
55
86
 
56
87
  ### Vite Plugin
@@ -128,12 +159,33 @@ npx frontfriend download <components...> [options]
128
159
  Options:
129
160
  -f, --framework <framework> Framework to download for (react/vue)
130
161
  -o, --output <path> Output directory for components
162
+ --registry <generation> Registry generation (legacy/v4)
131
163
  --overwrite Overwrite existing files
132
164
 
133
165
  Examples:
134
166
  npx frontfriend download button card # Download specific components
135
167
  npx frontfriend download all -f react # Download all React components
136
168
  npx frontfriend download all -f vue -o ./src # Download all Vue components to src/
169
+ npx frontfriend download button --registry v4 # Download from the Tailwind v4 registry
170
+ ```
171
+
172
+ ### Add Components or Generated Pages
173
+
174
+ ```bash
175
+ npx frontfriend add <component...> [options]
176
+ npx frontfriend add page <id> [options]
177
+ npx frontfriend add project <id> [options]
178
+
179
+ Options:
180
+ -f, --framework <framework> Framework for component installs (react/vue)
181
+ -o, --output <path> Output directory for components
182
+ --registry <generation> Registry generation (legacy/v4)
183
+ --overwrite Overwrite existing component files
184
+
185
+ Examples:
186
+ npx frontfriend add button --registry v4
187
+ npx frontfriend add button icon --registry v4 --output components/ui
188
+ npx frontfriend add page page-id --registry v4
137
189
  ```
138
190
 
139
191
  ### Clean Cache
@@ -184,6 +236,47 @@ export default {
184
236
  };
185
237
  ```
186
238
 
239
+ Select a registry generation in config when you do not want to pass `--registry` on every command:
240
+
241
+ ```js
242
+ module.exports = {
243
+ 'ff-id': 'your-frontfriend-id',
244
+ registry: 'v4'
245
+ };
246
+ ```
247
+
248
+ Registry selection precedence is:
249
+
250
+ ```txt
251
+ CLI flag > frontfriend.config.js > auto-detect Tailwind version > legacy fallback
252
+ ```
253
+
254
+ React compatibility is enforced for registry installs:
255
+
256
+ - `legacy` targets React 18-era components.
257
+ - `v4` targets Tailwind v4 and React 19-era React components.
258
+
259
+ ### shadcn-compatible registry item support
260
+
261
+ The FrontFriend downloader can also consume shadcn-compatible registry items
262
+ emitted by the FrontFriend `/r/...` routes.
263
+
264
+ - file `target` aliases are resolved before writing files:
265
+ - `@ui/...` writes under the configured component output directory;
266
+ - `@lib/...`, `@hooks/...`, and `@components/...` use matching `frontfriend.config.js`
267
+ aliases when present, otherwise conventional app directories like `lib/` and `hooks/`;
268
+ - `~/...` writes relative to the app root.
269
+ - `registryDependencies` may be plain component names or shadcn-compatible
270
+ FrontFriend URLs such as `https://.../r/v4/react/icon.json`; URL dependencies
271
+ are normalized back to component names and still use FrontFriend same-generation
272
+ custom-first resolution. Only FrontFriend `/r/{generation}/{framework}/{component}.json`
273
+ routes matching the selected registry generation and framework are accepted;
274
+ custom dependency URLs must also match the active `ff-id`. External URLs,
275
+ cross-generation URLs, or cross-client custom URLs fail explicitly instead of
276
+ being reinterpreted as local FrontFriend components.
277
+ - registry file paths are validated before writing so a malicious `../` target
278
+ cannot escape the selected alias root.
279
+
187
280
  ## TypeScript
188
281
 
189
282
  Full TypeScript support is included:
@@ -228,4 +321,4 @@ module.exports = {
228
321
  This is proprietary software. Usage is restricted to licensed FrontFriend clients only.
229
322
  See LICENSE file for details.
230
323
 
231
- © 2025 FrontFriend. All rights reserved.
324
+ © 2025 FrontFriend. All rights reserved.
@@ -0,0 +1,2 @@
1
+ var o=typeof window<"u"&&typeof window.document<"u";function i(t=""){let e=new Map;return new Proxy({},{get(r,n){return n===Symbol.toPrimitive||n==="valueOf"?()=>t:n==="toString"||n===Symbol.toStringTag?()=>t:n==="constructor"?Object:(e.has(n)||e.set(n,i(t)),e.get(n))},has(){return!0},ownKeys(){return[]},getOwnPropertyDescriptor(){return{enumerable:!0,configurable:!0}}})}function u(t){return t==="__FF_CONFIG__"&&typeof __FF_CONFIG__<"u"?__FF_CONFIG__:t==="__FF_ICONS__"&&typeof __FF_ICONS__<"u"?__FF_ICONS__:typeof globalThis<"u"&&globalThis[t]?globalThis[t]:o&&window[t]?window[t]:null}function _(t){return!t||typeof t!="object"?i():t}var c=new Proxy({},{get(t,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;let r=u("__FF_CONFIG__");return r&&e in r?r[e]:i()},has(){return!0},ownKeys(){return[]},getOwnPropertyDescriptor(){return{enumerable:!0,configurable:!0}}}),s=new Proxy({},{get(t,e){if(e===Symbol.toPrimitive||e==="valueOf")return()=>"";if(e==="toString"||e===Symbol.toStringTag)return()=>"[object Object]";if(e==="constructor")return Object;let r=u("__FF_ICONS__");return r&&e in r?r[e]:i()},has(){return!0},ownKeys(){return[]},getOwnPropertyDescriptor(){return{enumerable:!0,configurable:!0}}}),g={};function y(t){return typeof t=="string"&&t.trim().length>0}function f(){return{}}export{g as componentsConfigSchema,c as config,f as default,_ as ffdc,s as iconSet,y as isCSSClassString};
2
+ //# sourceMappingURL=browser.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../browser.mjs"],
4
+ "sourcesContent": ["// Browser-safe FrontFriend runtime used by Vite-built component consumers.\n\nconst isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n\nfunction createDeepProxy(fallbackValue = '') {\n const cache = new Map();\n\n return new Proxy({}, {\n get(target, prop) {\n if (prop === Symbol.toPrimitive || prop === 'valueOf') {\n return () => fallbackValue;\n }\n if (prop === 'toString' || prop === Symbol.toStringTag) {\n return () => fallbackValue;\n }\n if (prop === 'constructor') {\n return Object;\n }\n if (!cache.has(prop)) {\n cache.set(prop, createDeepProxy(fallbackValue));\n }\n return cache.get(prop);\n },\n has() {\n return true;\n },\n ownKeys() {\n return [];\n },\n getOwnPropertyDescriptor() {\n return { enumerable: true, configurable: true };\n },\n });\n}\n\nfunction readGlobal(name) {\n if (name === '__FF_CONFIG__' && typeof __FF_CONFIG__ !== 'undefined') {\n return __FF_CONFIG__;\n }\n if (name === '__FF_ICONS__' && typeof __FF_ICONS__ !== 'undefined') {\n return __FF_ICONS__;\n }\n if (typeof globalThis !== 'undefined' && globalThis[name]) {\n return globalThis[name];\n }\n if (isBrowser && window[name]) {\n return window[name];\n }\n return null;\n}\n\nexport function ffdc(config) {\n if (!config || typeof config !== 'object') {\n return createDeepProxy();\n }\n return config;\n}\n\nexport const config = new Proxy({}, {\n get(target, prop) {\n if (prop === Symbol.toPrimitive || prop === 'valueOf') return () => '';\n if (prop === 'toString' || prop === Symbol.toStringTag) return () => '[object Object]';\n if (prop === 'constructor') return Object;\n\n const currentConfig = readGlobal('__FF_CONFIG__');\n if (currentConfig && prop in currentConfig) {\n return currentConfig[prop];\n }\n return createDeepProxy();\n },\n has() {\n return true;\n },\n ownKeys() {\n return [];\n },\n getOwnPropertyDescriptor() {\n return { enumerable: true, configurable: true };\n },\n});\n\nexport const iconSet = new Proxy({}, {\n get(target, prop) {\n if (prop === Symbol.toPrimitive || prop === 'valueOf') return () => '';\n if (prop === 'toString' || prop === Symbol.toStringTag) return () => '[object Object]';\n if (prop === 'constructor') return Object;\n\n const icons = readGlobal('__FF_ICONS__');\n if (icons && prop in icons) {\n return icons[prop];\n }\n return createDeepProxy();\n },\n has() {\n return true;\n },\n ownKeys() {\n return [];\n },\n getOwnPropertyDescriptor() {\n return { enumerable: true, configurable: true };\n },\n});\n\nexport const componentsConfigSchema = {};\n\nexport function isCSSClassString(value) {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nexport default function frontfriend() {\n return {};\n}\n"],
5
+ "mappings": "AAEA,IAAMA,EAAY,OAAO,OAAW,KAAe,OAAO,OAAO,SAAa,IAE9E,SAASC,EAAgBC,EAAgB,GAAI,CAC3C,IAAMC,EAAQ,IAAI,IAElB,OAAO,IAAI,MAAM,CAAC,EAAG,CACnB,IAAIC,EAAQC,EAAM,CAChB,OAAIA,IAAS,OAAO,aAAeA,IAAS,UACnC,IAAMH,EAEXG,IAAS,YAAcA,IAAS,OAAO,YAClC,IAAMH,EAEXG,IAAS,cACJ,QAEJF,EAAM,IAAIE,CAAI,GACjBF,EAAM,IAAIE,EAAMJ,EAAgBC,CAAa,CAAC,EAEzCC,EAAM,IAAIE,CAAI,EACvB,EACA,KAAM,CACJ,MAAO,EACT,EACA,SAAU,CACR,MAAO,CAAC,CACV,EACA,0BAA2B,CACzB,MAAO,CAAE,WAAY,GAAM,aAAc,EAAK,CAChD,CACF,CAAC,CACH,CAEA,SAASC,EAAWC,EAAM,CACxB,OAAIA,IAAS,iBAAmB,OAAO,cAAkB,IAChD,cAELA,IAAS,gBAAkB,OAAO,aAAiB,IAC9C,aAEL,OAAO,WAAe,KAAe,WAAWA,CAAI,EAC/C,WAAWA,CAAI,EAEpBP,GAAa,OAAOO,CAAI,EACnB,OAAOA,CAAI,EAEb,IACT,CAEO,SAASC,EAAKC,EAAQ,CAC3B,MAAI,CAACA,GAAU,OAAOA,GAAW,SACxBR,EAAgB,EAElBQ,CACT,CAEO,IAAMA,EAAS,IAAI,MAAM,CAAC,EAAG,CAClC,IAAIL,EAAQC,EAAM,CAChB,GAAIA,IAAS,OAAO,aAAeA,IAAS,UAAW,MAAO,IAAM,GACpE,GAAIA,IAAS,YAAcA,IAAS,OAAO,YAAa,MAAO,IAAM,kBACrE,GAAIA,IAAS,cAAe,OAAO,OAEnC,IAAMK,EAAgBJ,EAAW,eAAe,EAChD,OAAII,GAAiBL,KAAQK,EACpBA,EAAcL,CAAI,EAEpBJ,EAAgB,CACzB,EACA,KAAM,CACJ,MAAO,EACT,EACA,SAAU,CACR,MAAO,CAAC,CACV,EACA,0BAA2B,CACzB,MAAO,CAAE,WAAY,GAAM,aAAc,EAAK,CAChD,CACF,CAAC,EAEYU,EAAU,IAAI,MAAM,CAAC,EAAG,CACnC,IAAIP,EAAQC,EAAM,CAChB,GAAIA,IAAS,OAAO,aAAeA,IAAS,UAAW,MAAO,IAAM,GACpE,GAAIA,IAAS,YAAcA,IAAS,OAAO,YAAa,MAAO,IAAM,kBACrE,GAAIA,IAAS,cAAe,OAAO,OAEnC,IAAMO,EAAQN,EAAW,cAAc,EACvC,OAAIM,GAASP,KAAQO,EACZA,EAAMP,CAAI,EAEZJ,EAAgB,CACzB,EACA,KAAM,CACJ,MAAO,EACT,EACA,SAAU,CACR,MAAO,CAAC,CACV,EACA,0BAA2B,CACzB,MAAO,CAAE,WAAY,GAAM,aAAc,EAAK,CAChD,CACF,CAAC,EAEYY,EAAyB,CAAC,EAEhC,SAASC,EAAiBC,EAAO,CACtC,OAAO,OAAOA,GAAU,UAAYA,EAAM,KAAK,EAAE,OAAS,CAC5D,CAEe,SAARC,GAA+B,CACpC,MAAO,CAAC,CACV",
6
+ "names": ["isBrowser", "createDeepProxy", "fallbackValue", "cache", "target", "prop", "readGlobal", "name", "ffdc", "config", "currentConfig", "iconSet", "icons", "componentsConfigSchema", "isCSSClassString", "value", "frontfriend"]
7
+ }
package/dist/cli.js CHANGED
@@ -1,72 +1,78 @@
1
1
  #!/usr/bin/env node
2
- var _=(s,t)=>()=>(t||s((t={exports:{}}).exports,t),t.exports);var q=_((K,E)=>{var P=require("fs"),N=require("path");function M(s={}){let t=s.projectRoot||process.cwd(),o=N.join(t,"node_modules",".cache","frontfriend","icons.json"),e=s.outputPath||N.join(t,"types","frontfriend.d.ts");P.existsSync(o)||(console.error('[FrontFriend] Error: icons.json not found. Please run "npx frontfriend init" first.'),process.exit(1));try{let i=function(v){for(let m of Object.values(v))typeof m=="string"?u.add(m):typeof m=="object"&&m!==null&&i(m)},a=function(v,m=" "){let p=[];for(let[D,l]of Object.entries(v))typeof l=="string"?p.push(`${m}${D}: '${l}';`):typeof l=="object"&&l!==null&&(p.push(`${m}${D}: {`),p.push(a(l,m+" ")),p.push(`${m}};`));return p.join(`
3
- `)};var r=i,F=a;let g=JSON.parse(P.readFileSync(o,"utf-8")),u=new Set;i(g);let n=Array.from(u).map(v=>`'${v}'`).join(" | "),d=`// Generated by @frontfriend/tailwind
2
+ var L=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var B=L((Xe,H)=>{var ge="https://app.frontfriend.dev",ue="https://registry-legacy.frontfriend.dev",pe=".cache/frontfriend",me={JS:["tokens.js","variables.js","semanticVariables.js","semanticDarkVariables.js","safelist.js","custom.js"],JSON:["fonts.json","icons.json","components-config.json","version.json","metadata.json"]},he={FF_ID:"FF_ID",FF_API_URL:"FF_API_URL",FF_USE_LOCAL:"FF_USE_LOCAL",FF_AUTH_TOKEN:"FF_AUTH_TOKEN"};H.exports={DEFAULT_API_URL:ge,LEGACY_API_URL:ue,CACHE_DIR_NAME:pe,CACHE_TTL_DAYS:7,CACHE_TTL_MS:6048e5,CACHE_FILES:me,ENV_VARS:he}});var ne=L((eo,oe)=>{var x=require("fs"),z=require("path"),ye=require("os"),Ce=require("https"),ve=require("http"),{URL:we}=require("url"),{DEFAULT_API_URL:Y}=B(),K=z.join(ye.homedir(),".frontfriend"),j=z.join(K,"credentials");function Se(){return j}function Z(){try{return x.existsSync(j)?JSON.parse(x.readFileSync(j,"utf8")):null}catch{return null}}function W(e){x.mkdirSync(K,{recursive:!0,mode:448}),x.writeFileSync(j,`${JSON.stringify(e,null,2)}
3
+ `,{mode:384});try{x.chmodSync(j,384)}catch{}}function Fe(){return x.existsSync(j)?(x.unlinkSync(j),!0):!1}function Q(e,n=60*1e3){return!(e!=null&&e.accessToken)||!e.expiresAt||Date.now()+n>=e.expiresAt}function X(e,n,o){return new Promise((t,s)=>{let r=new we(e),c=r.protocol==="https:"?Ce:ve,g=JSON.stringify(n||{}),a=c.request({hostname:r.hostname,port:r.port,path:`${r.pathname}${r.search}`,method:"POST",headers:{"content-type":"application/json","content-length":Buffer.byteLength(g),...o?{authorization:`Bearer ${o}`}:{}}},f=>{let u="";f.on("data",i=>{u+=i}),f.on("end",()=>{let i=null;try{i=u?JSON.parse(u):null}catch(p){s(p);return}if(f.statusCode>=400){let p=new Error((i==null?void 0:i.error_description)||(i==null?void 0:i.error)||`HTTP ${f.statusCode}`);p.statusCode=f.statusCode,p.body=i,s(p);return}t(i)})});a.on("error",s),a.write(g),a.end()})}async function ee(e,n=Y){if(!(e!=null&&e.refreshToken)||!(e!=null&&e.deviceId))return e;let o=await X(`${n}/api/plugin/token`,{grant_type:"refresh_token",refresh_token:e.refreshToken,device_id:e.deviceId}),t={accessToken:o.access_token,refreshToken:o.refresh_token,deviceId:o.device_id||e.deviceId,expiresAt:Date.now()+(o.expires_in||900)*1e3,refreshExpiresAt:Date.now()+(o.refresh_expires_in||604800)*1e3,ffApiUrl:n};return W(t),t}async function ke(e={}){if(!e.skipCredentials){let n=Z();if(n!=null&&n.accessToken){let o=e.baseURL||n.ffApiUrl||Y;if(Q(n))try{let t=await ee(n,o);return(t==null?void 0:t.accessToken)||null}catch{return null}return n.accessToken}}return e.envToken?e.envToken:e.legacyToken?(e.silent||console.warn("\u26A0\uFE0F auth-token in frontfriend.config.js is deprecated. Run `frontfriend login` to store credentials outside the repo."),e.legacyToken):null}oe.exports={getCredentialsPath:Se,readCredentials:Z,writeCredentials:W,deleteCredentials:Fe,isExpired:Q,postJson:X,refreshCredentials:ee,resolveAuthToken:ke}});var E=L((oo,O)=>{var F=require("fs"),_=require("path");function te(e={}){let n=e.projectRoot||process.cwd(),o=_.join(n,"node_modules",".cache","frontfriend","icons.json"),t=e.outputPath||_.join(n,"types","frontfriend.d.ts");F.existsSync(o)||(console.error('[FrontFriend] Error: icons.json not found. Please run "npx frontfriend init" first.'),process.exit(1));try{let a=function(C){for(let h of Object.values(C))typeof h=="string"?g.add(h):typeof h=="object"&&h!==null&&a(h)},f=function(C,h=" "){let v=[];for(let[I,S]of Object.entries(C))typeof S=="string"?v.push(`${h}${I}: '${S}';`):typeof S=="object"&&S!==null&&(v.push(`${h}${I}: {`),v.push(f(S,h+" ")),v.push(`${h}};`));return v.join(`
4
+ `)};var s=a,r=f;let c=JSON.parse(F.readFileSync(o,"utf-8")),g=new Set;a(c);let u=Array.from(g).map(C=>`'${C}'`).join(" | "),i=`// Generated by @frontfriend/tailwind
4
5
  // DO NOT EDIT THIS FILE MANUALLY
5
6
 
6
7
  import type { IconSetStructure } from '@frontfriend/tailwind';
7
8
 
8
9
  declare module '@frontfriend/tailwind' {
9
10
  // Icon names used in this project
10
- export type ProjectIconName = ${n||"string"};
11
+ export type ProjectIconName = ${u||"string"};
11
12
 
12
13
  // Typed iconSet structure with exact icon names
13
14
  export interface TypedIconSet extends IconSetStructure {
14
- ${a(g)}
15
+ ${f(c)}
15
16
  }
16
17
  }
17
18
 
18
19
  // Augment Vue component types with exact icon names
19
20
  declare module '*/components/ui/icon/*.vue' {
20
- export type IconName = ${n||"string"};
21
+ export type IconName = ${u||"string"};
21
22
  }
22
23
 
23
24
  declare module '@/components/ui/icon/*.vue' {
24
- export type IconName = ${n||"string"};
25
+ export type IconName = ${u||"string"};
25
26
  }
26
27
 
27
28
  declare module '@/components/ui/icon' {
28
- export type IconName = ${n||"string"};
29
+ export type IconName = ${u||"string"};
29
30
  }
30
31
 
31
32
  declare module '@/src/components/ui/icon' {
32
- export type IconName = ${n||"string"};
33
+ export type IconName = ${u||"string"};
33
34
  }
34
35
 
35
36
  declare module '@/src/components/ui/icon/Icon.vue' {
36
- export type IconName = ${n||"string"};
37
+ export type IconName = ${u||"string"};
37
38
  }
38
- `,x=N.dirname(e);P.existsSync(x)||P.mkdirSync(x,{recursive:!0}),P.writeFileSync(e,d),console.log("[FrontFriend] \u2713 Generated types at",N.relative(t,e));let k=N.join(t,"tsconfig.json");if(P.existsSync(k)){let v=JSON.parse(P.readFileSync(k,"utf-8"));v.include||(v.include=[]);let m="types/**/*.d.ts";v.include.includes(m)||(v.include.push(m),P.writeFileSync(k,JSON.stringify(v,null,2)),console.log("[FrontFriend] \u2713 Updated tsconfig.json to include generated types"))}}catch(g){console.error("[FrontFriend] Error generating icon types:",g.message),process.exit(1)}}require.main===E&&M();E.exports={generateIconTypes:M}});var{Command:G}=require("commander"),O=require("./lib/core/config-loader"),U=require("./lib/core/cache-manager"),{APIClient:J}=require("./lib/core/api-client"),{ComponentDownloader:A}=require("./lib/core/component-downloader"),B=require("./lib/core/token-processor"),{ConfigError:R,APIError:H,CacheError:V}=require("./lib/core/errors"),{loadEnvLocal:Y}=require("./lib/core/env-utils"),L=require("path");Y();var b=new G;b.name("frontfriend").description("FrontFriend Tailwind CLI - Manage design tokens and cache").version("2.4.0");b.command("init").description("Initialize FrontFriend configuration and fetch from API").option("--force","Force refresh even if cache is valid").option("--verbose","Show detailed output including safelist size and token counts").option("--tag <tag>","Fetch specific tag (e.g., dev, next, latest)").option("--version <version>","Fetch specific version (e.g., v1.0.0)").action(async s=>{var t;try{console.log("\u{1F527} FrontFriend Setup"),console.log(`==================
39
- `);let e=await new O().load();if(!e.ffId)throw new R(`ff-id not found in frontfriend.config.js
40
- Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let r=s.tag||e.tag,F=s.version||e.version;console.log("\u{1F4CB} Configuration loaded"),console.log(` FF_ID: ${e.ffId}`),console.log(` App Root: ${e.appRoot}`),r&&console.log(` Tag: ${r}`),F&&console.log(` Version: ${F}`),console.log("");let g=new U(e.appRoot);!s.force&&g.exists()&&g.isValid()&&(console.log("\u2705 Cache is valid and up to date"),console.log(" Use --force to refresh anyway"),process.exit(0)),console.log("\u{1F50D} Checking cache..."),s.force?console.log(` Force refresh requested
41
- `):g.exists()?console.log(` Cache expired
39
+ `,p=_.dirname(t);F.existsSync(p)||F.mkdirSync(p,{recursive:!0}),F.writeFileSync(t,i),console.log("[FrontFriend] \u2713 Generated types at",_.relative(n,t));let T=_.join(n,"tsconfig.json");if(F.existsSync(T)){let C=JSON.parse(F.readFileSync(T,"utf-8"));C.include||(C.include=[]);let h="types/**/*.d.ts";C.include.includes(h)||(C.include.push(h),F.writeFileSync(T,JSON.stringify(C,null,2)),console.log("[FrontFriend] \u2713 Updated tsconfig.json to include generated types"))}}catch(c){console.error("[FrontFriend] Error generating icon types:",c.message),process.exit(1)}}require.main===O&&te();O.exports={generateIconTypes:te}});var{loadEnvLocal:xe}=require("./lib/core/env-utils");xe();var{Command:je}=require("commander"),P=require("./lib/core/config-loader"),A=require("./lib/core/cache-manager"),{APIClient:re}=require("./lib/core/api-client"),{getCredentialsPath:$e,writeCredentials:Te,readCredentials:be,deleteCredentials:_e,postJson:N}=ne(),{ComponentDownloader:Pe}=require("./lib/core/component-downloader"),Ie=require("./lib/core/token-processor"),{ConfigError:k,APIError:Ae,CacheError:V}=require("./lib/core/errors"),d=require("path"),l=require("fs"),{spawn:De}=require("child_process"),w=new je,Le="https://registry.frontfriend.dev/r/v4",se='@import "@frontfriend/tailwind/theme.css";';function D(e){try{return JSON.parse(l.readFileSync(e,"utf8"))}catch{return null}}function q(e,n){l.writeFileSync(e,`${JSON.stringify(n,null,2)}
40
+ `)}function Oe(e){let n=D(d.join(e,"package.json"))||{},o={...n.dependencies||{},...n.devDependencies||{}};return o.vue||o["@vitejs/plugin-vue"]?"vue":"react"}function Ee(e){let n=D(d.join(e,"package.json"))||{},o={...n.dependencies||{},...n.devDependencies||{}};return o.next||l.existsSync(d.join(e,"next.config.js"))||l.existsSync(d.join(e,"next.config.mjs"))?"next":o.vite||l.existsSync(d.join(e,"vite.config.ts"))||l.existsSync(d.join(e,"vite.config.js"))?"vite":null}function Ne(e,n){let o=d.join(e,"components.json");if(!l.existsSync(o))return!1;let t=D(o)||{};t.registries=t.registries||{};let s=`${Le}/${n}`;return t.registries["@frontfriend"]===s?!1:(t.registries["@frontfriend"]=s,q(o,t),!0)}function Re(e){let n=d.join(e,"package.json"),o=D(n);return o?(o.dependencies=o.dependencies||{},o.dependencies["@frontfriend/tailwind"]?!1:(o.dependencies["@frontfriend/tailwind"]="^4.0.0",q(n,o),!0)):!1}function Ue(e){let n=d.join(e,"next.config.js");return l.existsSync(n)&&l.readFileSync(n,"utf8").includes("@frontfriend/tailwind/next")?!1:(l.writeFileSync(n,`const frontfriend = require('@frontfriend/tailwind/next');
41
+
42
+ module.exports = frontfriend({});
43
+ `),!0)}function Ve(e){let n=l.existsSync(d.join(e,"vite.config.ts"))?d.join(e,"vite.config.ts"):d.join(e,"vite.config.js");return l.existsSync(n)&&l.readFileSync(n,"utf8").includes("@frontfriend/tailwind/vite")?!1:(l.writeFileSync(n,`import { defineConfig } from 'vite';
44
+ import frontfriend from '@frontfriend/tailwind/vite';
45
+
46
+ export default defineConfig({
47
+ plugins: [frontfriend()],
48
+ });
49
+ `),!0)}function qe(e){let t=["app/globals.css","src/app/globals.css","styles/globals.css","src/styles/globals.css","src/index.css"].find(r=>l.existsSync(d.join(e,r)))||"app/globals.css",s=d.join(e,t);return l.mkdirSync(d.dirname(s),{recursive:!0}),l.existsSync(s)||l.writeFileSync(s,""),{fullPath:s,relativePath:t}}function Me(e){let{fullPath:n,relativePath:o}=qe(e),t=l.readFileSync(n,"utf8");return t.includes(se)?{changed:!1,relativePath:o}:(l.writeFileSync(n,`${se}
50
+ ${t}`),{changed:!0,relativePath:o})}function Je(e){let n=d.join(e,"components.json");if(!l.existsSync(n))return{isShadcnProject:!1,changes:[]};let o=Oe(e),t=Ee(e),s=[];Ne(e,o)&&s.push(`registered @frontfriend registry for ${o}`),Re(e)&&s.push("added @frontfriend/tailwind dependency"),t==="next"&&Ue(e)&&s.push("wired Next.js plugin"),t==="vite"&&Ve(e)&&s.push("wired Vite plugin");let r=Me(e);return r.changed&&s.push(`imported bundled theme in ${r.relativePath}`),{isShadcnProject:!0,changes:s,framework:o,buildTool:t}}function Ge(e){return new Promise(n=>setTimeout(n,e))}function He(e){let n=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",o=process.platform==="win32"?["/c","start","",e]:[e];try{return De(n,o,{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}function Be(e){e.isShadcnProject&&(console.log("\u{1F9E9} shadcn project wiring"),e.changes.length===0?console.log(" \u2713 Already configured"):e.changes.forEach(n=>console.log(` \u2713 ${n}`)),console.log(` Next: npx shadcn add @frontfriend/button
51
+ `))}function ze(e,n){let o=e.indexOf(`${n}:`);if(o===-1)return null;let t=e.indexOf("{",o);if(t===-1)return null;let s=0;for(let r=t;r<e.length;r+=1){let c=e[r];if(c==="{"&&(s+=1),c==="}"&&(s-=1),s===0)return e.slice(t+1,r)}return null}function Ye(e){let n={},o=/([A-Za-z0-9_-]+):\s*(['"`])([\s\S]*?)\2/g,t;for(;t=o.exec(e||"");)n[t[1]]=t[3].replace(/\s+/g," ").trim();return n}function Ke(e,n){let o=n;for(;/\s|,/.test(e[o]||"");)o+=1;let t=e[o];if(t==='"'||t==="'"||t==="`"){let r=e.indexOf(t,o+1);return r===-1?null:{name:e.slice(o+1,r),end:r+1}}let s=e.slice(o).match(/^([A-Za-z0-9_-]+)/);return s?{name:s[1],end:o+s[1].length}:null}function Ze(e){let n={},o=0;for(;o<(e||"").length;){let t=Ke(e,o);if(!t){o+=1;continue}for(o=t.end;/\s/.test(e[o]||"");)o+=1;if(e[o]!==":")continue;for(o+=1;/\s/.test(e[o]||"");)o+=1;if(e[o]!=="{")continue;let s=0,r=o;for(;o<e.length;o+=1)if(e[o]==="{"&&(s+=1),e[o]==="}"&&(s-=1),s===0){n[t.name]=Ye(e.slice(r+1,o)),o+=1;break}}return n}function R(e,n){if(!e.includes("cva(")||!e.includes("variants:"))return{skipped:!0,reason:`${n} source is not cva-structured`};let o=e.match(/cva\(\s*(['"`])([\s\S]*?)\1\s*,/),t=ze(e,"variants"),s=Ze(t);if(Object.values(s).every(g=>Object.keys(g).length===0))return{skipped:!0,reason:"no cva variant class maps found"};let r={default:"main",outline:"tertiary",destructive:"destructive",secondary:"secondary",ghost:"ghost",link:"link"},c={root:o?o[2].replace(/\s+/g," ").trim():"",variants:{}};for(let[g,a]of Object.entries(s)){c.variants[g]={};for(let[f,u]of Object.entries(a)){let i=n==="button"&&g==="variant"&&r[f]||f;c.variants[g][i]=u}}return{skipped:!1,config:{[n]:c}}}function U(...e){return e.reduce((n,o)=>({...n,...o||{}}),{})}function We(e){let n=require("./lib/core/token-processor"),{mergeComponentsConfig:o}=require("./lib/core/default-config"),t=new n,s=o(e),r=t.extractClassesFromComponentsConfig(s);return{componentsConfig:s,icons:{},safelist:r,classesContent:t.generateClassesContent(r),themeCSS:t.generateThemeCSS({}),metadata:{version:"local-components"}}}function ie(e,n){let o=new A(e),t=o.exists()?o.load()||{}:{},s=U(t.componentsConfig,n),r=We(s);return o.save({...t,...r,icons:t.icons||{}}),r.componentsConfig}function ce(e){return d.basename(e).replace(/\.(tsx|ts|jsx|js|vue)$/,"").replace(/[-_]([a-z])/g,(n,o)=>o.toUpperCase())}function ae(e,n){if(n&&n!=="all"){let t=d.join(e,"components","ui",`${n}.tsx`);return l.existsSync(t)?[{component:n,inputPath:t}]:[]}let o=d.join(e,"components","ui");return l.existsSync(o)?l.readdirSync(o).filter(t=>/\.(tsx|ts|jsx|js|vue)$/.test(t)).map(t=>({component:ce(t),inputPath:d.join(o,t)})):[]}function le(e){let n={},o=[],t=ae(e,"all");for(let{component:s,inputPath:r}of t){let c=R(l.readFileSync(r,"utf8"),s);if(c.skipped){o.push({component:s,reason:c.reason});continue}Object.assign(n,c.config)}return{config:n,skipped:o}}w.name("frontfriend").description("FrontFriend Tailwind CLI - Manage design tokens and cache").version("4.0.0");w.command("login").description("Authenticate FrontFriend CLI with an 8-digit device code").option("--api-url <url>","FrontFriend API URL",process.env.FF_API_URL||"https://app.frontfriend.dev").option("--no-open","Do not open the browser automatically").action(async e=>{try{let n=e.apiUrl.replace(/\/$/,""),o=await N(`${n}/api/auth/device/start`,{}),t=o.interval||5,s=Date.now()+(o.expires_in||600)*1e3;for(console.log("\u{1F510} FrontFriend Login"),console.log(`====================
52
+ `),console.log(`Vai su ${o.verification_uri} e inserisci il codice:`),console.log(`
53
+ ${o.user_code}
54
+ `),e.open!==!1&&He(o.verification_uri_complete||o.verification_uri)&&console.log("Ho aperto il browser per te."),console.log(`In attesa di approvazione...
55
+ `);Date.now()<s;){await Ge(t*1e3);let r=await N(`${n}/api/auth/device/poll`,{device_code:o.device_code});if(r.error!=="authorization_pending"){if(r.error==="slow_down"){t=r.interval||t+5;continue}if(r.error)throw new Error(`${r.error}: ${r.error_description||"Authentication failed"}`);Te({accessToken:r.access_token,refreshToken:r.refresh_token,deviceId:r.device_id,expiresAt:Date.now()+(r.expires_in||900)*1e3,refreshExpiresAt:Date.now()+(r.refresh_expires_in||604800)*1e3,ffApiUrl:n}),console.log("\u2705 Login completato!"),console.log(` Credenziali salvate in ${$e()}`),process.exit(0)}}throw new Error("expired_token: codice scaduto, esegui di nuovo `frontfriend login`.")}catch(n){console.error("\u274C Login failed:",n.message),process.exit(1)}});w.command("logout").description("Remove FrontFriend CLI credentials").option("--api-url <url>","FrontFriend API URL",process.env.FF_API_URL||"https://app.frontfriend.dev").action(async e=>{let n=be(),o=(e.apiUrl||(n==null?void 0:n.ffApiUrl)||"https://app.frontfriend.dev").replace(/\/$/,"");if(n!=null&&n.accessToken&&(n!=null&&n.deviceId))try{await N(`${o}/api/plugin/logout`,{device_id:n.deviceId},n.accessToken)}catch{}let t=_e();console.log(t?"\u2705 Logged out. Credentials removed.":"\u2139\uFE0F No stored credentials found."),process.exit(0)});w.command("init").description("Initialize FrontFriend configuration and fetch from API").option("--force","Force refresh even if cache is valid").option("--verbose","Show detailed output including safelist size and token counts").option("--tag <tag>","Fetch specific tag (e.g., dev, next, latest)").option("--version <version>","Fetch specific version (e.g., v1.0.0)").action(async e=>{var n;try{console.log("\u{1F527} FrontFriend Setup"),console.log(`==================
56
+ `);let t=await new P().load(),s=Je(t.appRoot),r=s.isShadcnProject?le(t.appRoot):{config:{},skipped:[]};if(Be(s),!t.ffId)throw s.isShadcnProject&&(ie(t.appRoot,r.config),console.log("\u2705 Local FrontFriend wiring complete!"),console.log(` Local component config cached (${Object.keys(r.config).length||"default"} component${Object.keys(r.config).length===1?"":"s"}).`),console.log(' Add frontfriend.config.js with "ff-id" later to fetch cloud design tokens.'),process.exit(0)),new k(`ff-id not found in frontfriend.config.js
57
+ Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let c=e.tag||t.tag,g=e.version||t.version;console.log("\u{1F4CB} Configuration loaded"),console.log(` FF_ID: ${t.ffId}`),console.log(` App Root: ${t.appRoot}`),c&&console.log(` Tag: ${c}`),g&&console.log(` Version: ${g}`),console.log("");let a=new A(t.appRoot);!e.force&&a.exists()&&a.isValid()&&(console.log("\u2705 Cache is valid and up to date"),console.log(" Use --force to refresh anyway"),process.exit(0)),console.log("\u{1F50D} Checking cache..."),e.force?console.log(` Force refresh requested
58
+ `):a.exists()?console.log(` Cache expired
42
59
  `):console.log(` No cache found
43
- `),console.log("\u{1F310} Fetching configuration...");let u=new J(e.ffId,{baseURL:e["api-url"]||e.apiUrl});(e["api-url"]||e.apiUrl)&&console.log(` Using API URL: ${e["api-url"]||e.apiUrl}`);let i=null;try{i=await u.fetchProcessedTokens({tag:r,version:F})}catch(c){console.log(` \u26A0\uFE0F Failed to fetch pre-processed tokens: ${c.message}`)}if(i){if(console.log(" \u2713 Pre-processed tokens fetched from server"),console.log(" \u2713 Skipping local processing"),i.versionMetadata){let c=i.versionMetadata;console.log(" \u2139\uFE0F Version Information:"),c.version&&console.log(` Version: ${c.version}`),c.tag&&console.log(` Tag: ${c.tag}`),c.cached!==void 0&&console.log(` From Cache: ${c.cached?"Yes":"No"}`)}if(console.log(""),(!((t=i.tokens)!=null&&t.fontFamily)||Object.keys(i.tokens.fontFamily).length===0)&&(console.log("\u26A0\uFE0F Warning: No font family utilities found"),console.log(" Font classes like font-primary and font-secondary will not be available"),i.globalTokens?console.log(` Global tokens are present - font processor may need to be updated
60
+ `),console.log("\u{1F310} Fetching configuration...");let f=new re(t.ffId,{baseURL:t["api-url"]||t.apiUrl,authToken:t["auth-token"]||t.authToken});(t["api-url"]||t.apiUrl)&&console.log(` Using API URL: ${t["api-url"]||t.apiUrl}`);let u=new Ie,i=null;try{i=await f.fetchProcessedTokens({tag:c,version:g,tailwindV4:u.useTailwindV4})}catch(m){console.log(` \u26A0\uFE0F Failed to fetch pre-processed tokens: ${m.message}`)}if(i){if(console.log(" \u2713 Pre-processed tokens fetched from server"),console.log(" \u2713 Skipping local processing"),Object.keys(r.config).length>0&&(i.componentsConfig=U(i.componentsConfig,r.config),console.log(` \u2713 Preserved host component classes for ${Object.keys(r.config).join(", ")}`)),i.versionMetadata){let m=i.versionMetadata;console.log(" \u2139\uFE0F Version Information:"),m.version&&console.log(` Version: ${m.version}`),m.tag&&console.log(` Tag: ${m.tag}`),m.cached!==void 0&&console.log(` From Cache: ${m.cached?"Yes":"No"}`)}if(console.log(""),(!((n=i.tokens)!=null&&n.fontFamily)||Object.keys(i.tokens.fontFamily).length===0)&&(console.log("\u26A0\uFE0F Warning: No font family utilities found"),console.log(" Font classes like font-primary and font-secondary will not be available"),i.globalTokens?console.log(` Global tokens are present - font processor may need to be updated
44
61
  `):console.log(` Consider adding font family tokens to your design system
45
- `)),console.log("\u{1F4BE} Saving cache..."),(process.env.FF_VERBOSE==="true"||s.verbose)&&console.log(` Safelist has ${i.safelist?i.safelist.length:0} items`),g.save(i),console.log(` \u2713 Cache saved successfully
46
- `),console.log("\u2705 Setup complete!"),console.log(" Your FrontFriend configuration has been cached."),console.log(" The Tailwind plugin will now use this cached data."),e.types){console.log(`
47
- \u{1F524} Generating TypeScript types...`);try{let{generateIconTypes:c}=q(),y=e.aliases&&e.aliases.types?L.join(e.appRoot,e.aliases.types,"frontfriend.d.ts"):void 0;c({projectRoot:e.appRoot,outputPath:y})}catch(c){console.log(" \u26A0\uFE0F Type generation failed:",c.message),console.log(' Enable type generation in frontfriend.config.js with "types": true')}}process.exit(0)}console.log(` \u2139\uFE0F Pre-processed tokens not available, falling back to local processing
48
- `);let[a,n,d,x,k,v]=await Promise.all([u.fetchTokens(),u.fetchComponentsConfig(),u.fetchFonts(),u.fetchIcons(),u.fetchVersion(),u.fetchCustomCss()]);if(console.log(" \u2713 Tokens fetched"),a.global||a.colors||a.semantic||a.semanticDark){let c=[a.global?"global":null,a.colors?"colors":null,a.semantic?"semantic":null,a.semanticDark?"semanticDark":null].filter(Boolean).join(", ");console.log(` (Found: ${c})`)}console.log(" \u2713 Components config fetched"),console.log(" \u2713 Fonts fetched"),console.log(" \u2713 Icons fetched"),console.log(" \u2713 Version fetched"),console.log(` \u2713 Custom CSS fetched
49
- `),console.log("\u2699\uFE0F Processing tokens...");let m=new B;console.log(" Processing raw token data...");let p=await m.process({colors:a.colors||a.global,semantic:a.semantic,semanticDark:a.semanticDark,fonts:d,globalTokens:a.global,animations:a.animations,version:k==null?void 0:k.version,ffId:e.ffId,customCss:v});console.log(" \u2713 Colors processed"),console.log(" \u2713 Semantic tokens processed"),p.fontFaces.length>0&&console.log(` \u2713 ${p.fontFaces.length} font faces processed`),Object.keys(p.animations).length>0&&console.log(` \u2713 ${Object.keys(p.animations).length} animations processed`),console.log(`
50
- `);let D=m.extractClassesFromComponentsConfig(n),l=[...p.safelist||[],...D||[]],f=[...new Set(l)].sort(),h={tokens:p.utilities,variables:p.variables,semanticVariables:p.semanticVariables,semanticDarkVariables:p.semanticDarkVariables,fonts:p.fontFaces,icons:x,componentsConfig:n,keyframes:p.keyframes,animations:p.animations,safelist:f,version:k,metadata:p.metadata,custom:p.custom};if(console.log("\u{1F4BE} Saving cache..."),(process.env.FF_VERBOSE==="true"||s.verbose)&&(console.log(" Cache data summary:"),console.log(` - Tokens: ${Object.keys(h.tokens||{}).length} utilities`),console.log(` - Variables: ${Object.keys(h.variables||{}).length} CSS variables`),console.log(` - Semantic variables: ${Object.keys(h.semanticVariables||{}).length} semantic variables`),console.log(` - Font faces: ${(h.fonts||[]).length} fonts`),console.log(` - Safelist: ${(h.safelist||[]).length} safelist classes`)),g.save(h),console.log(` \u2713 Cache saved successfully
51
- `),console.log("\u2705 Setup complete!"),console.log(" Your FrontFriend configuration has been cached."),console.log(" The Tailwind plugin will now use this cached data."),e.types){console.log(`
52
- \u{1F524} Generating TypeScript types...`);try{let{generateIconTypes:c}=q(),y=e.aliases&&e.aliases.types?L.join(e.appRoot,e.aliases.types,"frontfriend.d.ts"):void 0;c({projectRoot:e.appRoot,outputPath:y})}catch(c){console.log(" \u26A0\uFE0F Type generation failed:",c.message),console.log(' Enable type generation in frontfriend.config.js with "types": true')}}process.exit(0)}catch(o){o instanceof R?console.error("\u274C Configuration Error:",o.message):o instanceof H?(console.error("\u274C API Error:",o.message),console.error(` Status: ${o.statusCode}`),console.error(` URL: ${o.url}`)):o instanceof V?(console.error("\u274C Cache Error:",o.message),console.error(` Operation: ${o.operation}`)):console.error("\u274C Setup failed:",o.message),process.exit(1)}});b.command("clean").description("Remove cached configuration").action(async()=>{try{console.log(`\u{1F9F9} Cleaning FrontFriend cache...
53
- `);let t=new O().load(),o=new U(t.appRoot);o.exists()?(o.clear(),console.log("\u2705 Cache cleared successfully")):console.log("\u2139\uFE0F No cache found"),process.exit(0)}catch(s){s instanceof V?(console.error("\u274C Cache Error:",s.message),console.error(` Operation: ${s.operation}`)):console.error("\u274C Clean failed:",s.message),process.exit(1)}});b.command("status").description("Show cache status and configuration").action(async()=>{try{console.log("\u{1F4CA} FrontFriend Status"),console.log(`===================
54
- `),console.log("Package:"),console.log(" Version: 2.4.0"),console.log("");let t=await new O().load();console.log("Configuration:"),console.log(` FF_ID: ${t.ffId||"Not set"}`),console.log(` App Root: ${t.appRoot}`),t.tag&&console.log(` Tag: ${t.tag}`),t.version&&console.log(` Version: ${t.version}`),console.log("");let o=new U(t.appRoot),e=o.getCacheDir();if(console.log("Cache:"),console.log(` Directory: ${L.relative(process.cwd(),e)}`),o.exists()){console.log(` Status: ${o.isValid()?"\u2705 Valid":"\u26A0\uFE0F Expired"}`);let r=o.load();if(r&&r.metadata){let F=new Date(r.metadata.timestamp);console.log(` Created: ${F.toLocaleString()}`),console.log(` Format Version: ${r.metadata.version||"Unknown"}`)}r&&r.versionMetadata&&(console.log(" Cached Version Info:"),r.versionMetadata.version&&console.log(` Version: ${r.versionMetadata.version}`),r.versionMetadata.tag&&console.log(` Tag: ${r.versionMetadata.tag}`))}else console.log(" Status: \u274C Not found");process.exit(0)}catch(s){s instanceof R?console.error("\u274C Configuration Error:",s.message):s instanceof V?(console.error("\u274C Cache Error:",s.message),console.error(` Operation: ${s.operation}`)):console.error("\u274C Status check failed:",s.message),process.exit(1)}});b.command("download").description("Download components from registry").argument("<components...>",'component names to download (or "all" to download all components)').option("-f, --framework <framework>","Framework to download components for (react/vue)").option("-o, --output <path>","Output directory for components").option("--overwrite","Overwrite existing files").action(async(s,t)=>{try{console.log(`\u{1F4E6} Downloading components...
55
- `);let e=await new O().load();if(!e.ffId)throw new R(`ff-id not found in frontfriend.config.js
56
- Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let r=new A({appRoot:e.appRoot,config:e,framework:t.framework,outputPath:t.output,overwrite:t.overwrite}),F=s;if(s.length===1&&s[0].toLowerCase()==="all"){let u=await r.getAllComponents(),i=await r.getCustomComponents();process.env.FF_DEBUG&&console.log(`Debug: Found ${i.length} custom components: ${i.join(", ")}`),u.length===0&&(console.error("\u274C Failed to fetch component list"),process.exit(1));let a=new Set(i),n=u.filter(d=>!a.has(d));F=[...i,...n],console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${r.framework}`),console.log(` Output: ${r.outputPath}`),console.log(` Components: All ${F.length} components`),process.env.FF_DEBUG&&i.length>0&&console.log(` Debug: ${i.length} custom components will override standard ones`),console.log("")}else console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${r.framework}`),console.log(` Output: ${r.outputPath}`),console.log(` Components: ${s.join(", ")}
57
- `);let g=await r.downloadComponents(F);g.successful.length>0&&(console.log(`
58
- \u2705 Download complete!`),console.log(` Downloaded: ${g.successful.length} components`)),g.failed.length>0&&(console.log(""),g.failed.forEach(u=>{u.error.includes("not found")?console.log(`\u274C ${u.error}`):console.log(`\u274C Failed to download ${u.component}: ${u.error}`)})),g.successful.length>0&&g.dependencies.length>0&&(console.log(`
59
- \u{1F4E6} Install dependencies:`),console.log(` npm install ${g.dependencies.join(" ")}`)),g.successful.length===0&&g.failed.length>0&&process.exit(1),process.exit(0)}catch(o){o instanceof R?(console.error("\u274C Configuration Error:",o.message),o.missingKey&&console.error(` Missing key: ${o.missingKey}`)):console.error("\u274C Download failed:",o.message),process.exit(1)}});b.command("add").description("Add generated pages from Frontfriend platform").argument("<type>","Type of resource to add (page or project)").argument("<id>","ID of the resource").option("--name <name>","Component name for the page").option("--path <path>","Output path (overrides aliases.pages)").option("--force","Overwrite existing files").option("--pages <ids>","Specific page IDs for project (comma-separated)").option("--all","Add all pages from project").action(async(s,t,o)=>{var e,r,F,g,u,i;try{console.log(`\u{1F680} Frontfriend Add
60
- `);let n=await new O().load();if(!n.ffId)throw new R(`ff-id not found in frontfriend.config.js
61
- Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let d=require("fs"),x=require("path"),k=require("https"),v=require("http"),{URL:m}=require("url"),p=l=>new Promise((f,h)=>{let c=new m(l),y=c.protocol==="https:",T=y?k:v,j={hostname:c.hostname,port:c.port||(y?443:80),path:c.pathname+c.search,method:"GET",headers:{Accept:"application/json"}};T.get(j,C=>{let $="";C.on("data",w=>$+=w),C.on("end",()=>{if(C.statusCode===200)try{f(JSON.parse($))}catch{h(new Error("Invalid JSON response"))}else try{let w=JSON.parse($);h(new Error(w.error||`HTTP ${C.statusCode}`))}catch{h(new Error(`HTTP ${C.statusCode}: ${$}`))}})}).on("error",h)}),D=n["api-url"]||n.apiUrl||"https://app.frontfriend.dev";if(s==="page"){console.log("\u{1F4CB} Configuration"),console.log(` FF_ID: ${n.ffId}`),console.log(` Page ID: ${t}`);let l=o.path||((e=n.aliases)==null?void 0:e.pages)||"src/pages";console.log(` Output: ${l}
62
- `),console.log("\u{1F310} Fetching page...");let f=await p(`${D}/api/export/pages/${t}?ffId=${n.ffId}`);if(console.log(` \u2713 Page fetched: ${f.name}`),f.components&&f.components.length>0){console.log(`
63
- \u{1F4E6} Checking UI components...`);let C=new A({appRoot:n.appRoot,config:n,framework:n.framework||"react"}),$=((F=(r=n.aliases)==null?void 0:r.ui)==null?void 0:F.replace("@/",""))||"src/components/ui",w=[];for(let S of f.components){let I=x.join(n.appRoot,$,S);d.existsSync(I)||d.existsSync(I+".tsx")||d.existsSync(I+".jsx")||d.existsSync(I+".vue")||w.push(S)}if(w.length>0){console.log(` Missing components: ${w.join(", ")}`),console.log(" Downloading missing components...");let S=await C.downloadComponents(w);S.successful.length>0&&console.log(` \u2713 Downloaded ${S.successful.length} components`)}else console.log(" \u2713 All required components present")}console.log(`
64
- \u{1F4BE} Writing page file...`);let h=o.name?`${o.name}.tsx`:`${f.componentName}.tsx`,c=l.startsWith("@/")?l.replace("@/",""):l,y=x.join(n.appRoot,c,h);d.existsSync(y)&&!o.force&&(console.error(`
65
- \u274C File already exists: ${y}`),console.error(" Use --force to overwrite"),process.exit(1));let T=x.dirname(y);d.existsSync(T)||d.mkdirSync(T,{recursive:!0}),d.writeFileSync(y,f.code),console.log(` \u2713 Created: ${x.relative(n.appRoot,y)}`),console.log(`
66
- \u2705 Page added successfully!`),console.log(` Component: ${f.componentName}`),console.log(` Location: ${x.relative(n.appRoot,y)}`),console.log(`
67
- \u{1F4DA} Import in your app:`);let j;l.startsWith("@/")?j=`${l}/${f.componentName}`:l.startsWith("src/")?j=`@/${l.substring(4)}/${f.componentName}`:j=`@/${l}/${f.componentName}`,console.log(` import ${f.componentName} from '${j}';`)}else if(s==="project"){!o.all&&!o.pages&&(console.error("\u274C Please specify --all or --pages <ids>"),process.exit(1)),console.log("\u{1F4CB} Configuration"),console.log(` FF_ID: ${n.ffId}`),console.log(` Project ID: ${t}`);let l=o.path||((g=n.aliases)==null?void 0:g.pages)||"src/pages";console.log(` Output: ${l}
68
- `),console.log("\u{1F310} Fetching project pages...");let f=await p(`${D}/api/export/projects/${t}?ffId=${n.ffId}`);console.log(` \u2713 Project fetched: ${f.projectTitle}`),console.log(` \u2713 Found ${f.pages.length} pages`);let h=f.pages;if(o.pages){let C=o.pages.split(",").map($=>$.trim());h=f.pages.filter($=>C.includes($.id)),console.log(` \u2713 Adding ${h.length} specific pages`)}if(f.components&&f.components.length>0){console.log(`
69
- \u{1F4E6} Checking UI components...`);let C=new A({appRoot:n.appRoot,config:n,framework:n.framework||"react"}),$=((i=(u=n.aliases)==null?void 0:u.ui)==null?void 0:i.replace("@/",""))||"src/components/ui",w=[];for(let S of f.components){let I=x.join(n.appRoot,$,S);d.existsSync(I)||d.existsSync(I+".tsx")||d.existsSync(I+".jsx")||d.existsSync(I+".vue")||w.push(S)}if(w.length>0){console.log(` Missing components: ${w.join(", ")}`),console.log(" Downloading missing components...");let S=await C.downloadComponents(w);S.successful.length>0&&console.log(` \u2713 Downloaded ${S.successful.length} components`)}else console.log(" \u2713 All required components present")}console.log(`
70
- \u{1F4BE} Writing page files...`);let c=l.startsWith("@/")?l.replace("@/",""):l,y=x.join(n.appRoot,c);d.existsSync(y)||d.mkdirSync(y,{recursive:!0});let T=0,j=0;for(let C of h){let $=`${C.componentName}.tsx`,w=x.join(y,$);if(d.existsSync(w)&&!o.force){console.log(` \u26A0\uFE0F Skipped (exists): ${$}`),j++;continue}d.writeFileSync(w,C.code),console.log(` \u2713 Created: ${$}`),T++}console.log(`
71
- \u2705 Project pages added!`),console.log(` Added: ${T} pages`),j>0&&(console.log(` Skipped: ${j} pages (already exist)`),console.log(" Use --force to overwrite existing files"))}else console.error(`\u274C Unknown type: ${s}`),console.error(' Use "page" or "project"'),process.exit(1);process.exit(0)}catch(a){a instanceof R?console.error("\u274C Configuration Error:",a.message):console.error("\u274C Failed:",a.message),process.exit(1)}});b.parse(process.argv);process.argv.slice(2).length||(b.outputHelp(),process.exit(0));
62
+ `)),u.useTailwindV4){let m=u.extractClassesFromComponentsConfig(i.componentsConfig),b=[...i.safelist||[],...m||[]];i.safelist=[...new Set(b)].sort(),i.themeCSS||(i.themeCSS=u.generateThemeCSS({variables:i.variables||{},semanticVariables:i.semanticVariables||{},semanticDarkVariables:i.semanticDarkVariables||{},fontFaces:i.fonts||[],keyframes:i.keyframes||{},animations:i.animations||{},custom:i.custom||{}})),(!i.classesContent||Object.keys(r.config).length>0)&&(i.classesContent=u.generateClassesContent(i.safelist))}if(console.log("\u{1F4BE} Saving cache..."),(process.env.FF_VERBOSE==="true"||e.verbose)&&console.log(` Safelist has ${i.safelist?i.safelist.length:0} items`),a.save(i),console.log(` \u2713 Cache saved successfully
63
+ `),console.log("\u2705 Setup complete!"),console.log(" Your FrontFriend configuration has been cached."),console.log(" The Tailwind plugin will now use this cached data."),t.types){console.log(`
64
+ \u{1F524} Generating TypeScript types...`);try{let{generateIconTypes:m}=E(),b=t.aliases&&t.aliases.types?d.join(t.appRoot,t.aliases.types,"frontfriend.d.ts"):void 0;m({projectRoot:t.appRoot,outputPath:b})}catch(m){console.log(" \u26A0\uFE0F Type generation failed:",m.message),console.log(' Enable type generation in frontfriend.config.js with "types": true')}}process.exit(0)}console.log(` \u2139\uFE0F Pre-processed tokens not available, falling back to local processing
65
+ `);let[p,T,C,h,v,I]=await Promise.all([f.fetchTokens(),f.fetchComponentsConfig(),f.fetchFonts(),f.fetchIcons(),f.fetchVersion(),f.fetchCustomCss()]),S=U(T,r.config);if(console.log(" \u2713 Tokens fetched"),p.global||p.colors||p.semantic||p.semanticDark){let m=[p.global?"global":null,p.colors?"colors":null,p.semantic?"semantic":null,p.semanticDark?"semanticDark":null].filter(Boolean).join(", ");console.log(` (Found: ${m})`)}console.log(" \u2713 Components config fetched"),Object.keys(r.config).length>0&&console.log(` \u2713 Preserved host component classes for ${Object.keys(r.config).join(", ")}`),console.log(" \u2713 Fonts fetched"),console.log(" \u2713 Icons fetched"),console.log(" \u2713 Version fetched"),console.log(` \u2713 Custom CSS fetched
66
+ `),console.log("\u2699\uFE0F Processing tokens..."),console.log(" Processing raw token data...");let y=await u.process({colors:p.colors||p.global,semantic:p.semantic,semanticDark:p.semanticDark,fonts:C,globalTokens:p.global,animations:p.animations,version:v==null?void 0:v.version,ffId:t.ffId,customCss:I});console.log(" \u2713 Colors processed"),console.log(" \u2713 Semantic tokens processed"),y.fontFaces.length>0&&console.log(` \u2713 ${y.fontFaces.length} font faces processed`),Object.keys(y.animations).length>0&&console.log(` \u2713 ${Object.keys(y.animations).length} animations processed`),console.log(`
67
+ `);let fe=u.extractClassesFromComponentsConfig(S),de=[...y.safelist||[],...fe||[]],M=[...new Set(de)].sort(),J,G;u.useTailwindV4&&(console.log("\u{1F3A8} Generating Tailwind v4 CSS artifacts..."),J=u.generateThemeCSS(y),G=u.generateClassesContent(M),console.log(" \u2713 theme.css generated"),console.log(` \u2713 classes.css generated for @source scanning
68
+ `));let $={tokens:y.utilities,variables:y.variables,semanticVariables:y.semanticVariables,semanticDarkVariables:y.semanticDarkVariables,fonts:y.fontFaces,icons:h,componentsConfig:S,keyframes:y.keyframes,animations:y.animations,safelist:M,version:v,metadata:y.metadata,custom:y.custom,themeCSS:J,classesContent:G};if(console.log("\u{1F4BE} Saving cache..."),(process.env.FF_VERBOSE==="true"||e.verbose)&&(console.log(" Cache data summary:"),console.log(` - Tokens: ${Object.keys($.tokens||{}).length} utilities`),console.log(` - Variables: ${Object.keys($.variables||{}).length} CSS variables`),console.log(` - Semantic variables: ${Object.keys($.semanticVariables||{}).length} semantic variables`),console.log(` - Font faces: ${($.fonts||[]).length} fonts`),console.log(` - Safelist: ${($.safelist||[]).length} safelist classes`)),a.save($),console.log(` \u2713 Cache saved successfully
69
+ `),console.log("\u2705 Setup complete!"),console.log(" Your FrontFriend configuration has been cached."),console.log(" The Tailwind plugin will now use this cached data."),t.types){console.log(`
70
+ \u{1F524} Generating TypeScript types...`);try{let{generateIconTypes:m}=E(),b=t.aliases&&t.aliases.types?d.join(t.appRoot,t.aliases.types,"frontfriend.d.ts"):void 0;m({projectRoot:t.appRoot,outputPath:b})}catch(m){console.log(" \u26A0\uFE0F Type generation failed:",m.message),console.log(' Enable type generation in frontfriend.config.js with "types": true')}}process.exit(0)}catch(o){o instanceof k?console.error("\u274C Configuration Error:",o.message):o instanceof Ae?(console.error("\u274C API Error:",o.message),console.error(` Status: ${o.statusCode}`),console.error(` URL: ${o.url}`)):o instanceof V?(console.error("\u274C Cache Error:",o.message),console.error(` Operation: ${o.operation}`)):console.error("\u274C Setup failed:",o.message),process.exit(1)}});w.command("clean").description("Remove cached configuration").action(async()=>{try{console.log(`\u{1F9F9} Cleaning FrontFriend cache...
71
+ `);let n=new P().load(),o=new A(n.appRoot);o.exists()?(o.clear(),console.log("\u2705 Cache cleared successfully")):console.log("\u2139\uFE0F No cache found"),process.exit(0)}catch(e){e instanceof V?(console.error("\u274C Cache Error:",e.message),console.error(` Operation: ${e.operation}`)):console.error("\u274C Clean failed:",e.message),process.exit(1)}});w.command("status").description("Show cache status and configuration").action(async()=>{try{console.log("\u{1F4CA} FrontFriend Status"),console.log(`===================
72
+ `),console.log("Package:"),console.log(" Version: 4.0.0"),console.log("");let n=await new P().load();console.log("Configuration:"),console.log(` FF_ID: ${n.ffId||"Not set"}`),console.log(` App Root: ${n.appRoot}`),n.tag&&console.log(` Tag: ${n.tag}`),n.version&&console.log(` Version: ${n.version}`),console.log("");let o=new A(n.appRoot),t=o.getCacheDir();if(console.log("Cache:"),console.log(` Directory: ${d.relative(process.cwd(),t)}`),o.exists()){console.log(` Status: ${o.isValid()?"\u2705 Valid":"\u26A0\uFE0F Expired"}`);let s=o.load();if(s&&s.metadata){let r=new Date(s.metadata.timestamp);console.log(` Created: ${r.toLocaleString()}`),console.log(` Format Version: ${s.metadata.version||"Unknown"}`)}s&&s.versionMetadata&&(console.log(" Cached Version Info:"),s.versionMetadata.version&&console.log(` Version: ${s.versionMetadata.version}`),s.versionMetadata.tag&&console.log(` Tag: ${s.versionMetadata.tag}`))}else console.log(" Status: \u274C Not found");process.exit(0)}catch(e){e instanceof k?console.error("\u274C Configuration Error:",e.message):e instanceof V?(console.error("\u274C Cache Error:",e.message),console.error(` Operation: ${e.operation}`)):console.error("\u274C Status check failed:",e.message),process.exit(1)}});w.command("migrate").description("Migrate cva-structured shadcn components into FrontFriend config").option("--component <name>",'Component to migrate, or "all" to scan components/ui',"all").option("--input <path>","Path to the shadcn component source").option("--output <path>","Output JSON path for migrated config","frontfriend.migrated-components.json").option("--no-push","Do not push migrated config to the configured FrontFriend cloud").action(async e=>{try{let o=await new P().load(),t=o.appRoot,s=e.input&&e.component==="all"?ce(e.input):e.component,r;if(e.input){let a=d.resolve(t,e.input);if(!l.existsSync(a))throw new k(`Component source not found: ${d.relative(t,a)}`);let f=l.readFileSync(a,"utf8");r=R(f,s)}else if(s==="all")r=le(t);else{let a=ae(t,s);if(a.length===0)throw new k(`Component source not found: components/ui/${s}.tsx`);let f=l.readFileSync(a[0].inputPath,"utf8");r=R(f,s)}if(r.skipped===!0||Object.keys(r.config||{}).length===0){let a=r.reason||"no cva-structured components found";console.log(`\u23ED\uFE0F Skipped ${s}: ${a}`),process.exit(0)}let c=d.resolve(t,e.output);q(c,r.config),ie(t,r.config);let g=!1;e.push&&o.ffId&&(await new re(o.ffId,{baseURL:o["api-url"]||o.apiUrl,authToken:o["auth-token"]||o.authToken}).pushComponentsConfig(r.config),g=!0),console.log("\u2705 Migration complete!"),console.log(` Component: ${s==="all"?Object.keys(r.config).join(", "):s}`),console.log(` Output: ${d.relative(t,c)}`),console.log(" Local config: cached for the FrontFriend plugin"),console.log(g?" Cloud config: pushed user override":" Cloud config: not pushed (missing ff-id or --no-push)"),process.exit(0)}catch(n){n instanceof k?console.error("\u274C Migration Error:",n.message):console.error("\u274C Migration failed:",n.message),process.exit(1)}});w.command("download").description("Download components from registry").argument("<components...>",'component names to download (or "all" to download all components)').option("-f, --framework <framework>","Framework to download components for (react/vue)").option("-o, --output <path>","Output directory for components").option("--registry <generation>","Registry generation to use (legacy/v4)").option("--overwrite","Overwrite existing files").action(async(e,n)=>{try{console.log(`\u{1F4E6} Downloading components...
73
+ `);let t=await new P().load();if(!t.ffId)throw new k(`ff-id not found in frontfriend.config.js
74
+ Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let s=new Pe({appRoot:t.appRoot,config:t,framework:n.framework,registryGeneration:n.registry,outputPath:n.output,overwrite:n.overwrite}),r=e;if(e.length===1&&e[0].toLowerCase()==="all"){let g=await s.getAllComponents(),a=await s.getCustomComponents();process.env.FF_DEBUG&&console.log(`Debug: Found ${a.length} custom components: ${a.join(", ")}`),g.length===0&&(console.error("\u274C Failed to fetch component list"),process.exit(1));let f=new Set(a),u=g.filter(i=>!f.has(i));r=[...a,...u],console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${s.framework}`),console.log(` Registry: ${s.registryGeneration}`),console.log(` Output: ${s.outputPath}`),console.log(` Components: All ${r.length} components`),process.env.FF_DEBUG&&a.length>0&&console.log(` Debug: ${a.length} custom components will override standard ones`),console.log("")}else console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${s.framework}`),console.log(` Registry: ${s.registryGeneration}`),console.log(` Output: ${s.outputPath}`),console.log(` Components: ${e.join(", ")}
75
+ `);let c=await s.downloadComponents(r);c.successful.length>0&&(console.log(`
76
+ \u2705 Download complete!`),console.log(` Downloaded: ${c.successful.length} components`)),c.failed.length>0&&(console.log(""),c.failed.forEach(g=>{g.error.includes("not found")?console.log(`\u274C ${g.error}`):console.log(`\u274C Failed to download ${g.component}: ${g.error}`)})),c.successful.length>0&&c.dependencies.length>0&&(console.log(`
77
+ \u{1F4E6} Install dependencies:`),console.log(` npm install ${c.dependencies.join(" ")}`)),c.successful.length===0&&c.failed.length>0&&process.exit(1),process.exit(0)}catch(o){o instanceof k?(console.error("\u274C Configuration Error:",o.message),o.missingKey&&console.error(` Missing key: ${o.missingKey}`)):console.error("\u274C Download failed:",o.message),process.exit(1)}});w.parse(process.argv);process.argv.slice(2).length||(w.outputHelp(),process.exit(0));
72
78
  //# sourceMappingURL=cli-temp.js.map
@@ -0,0 +1,2 @@
1
+ export const componentsConfigSchema: Record<string, any>;
2
+ export function isCSSClassString(value: string): boolean;
@@ -0,0 +1,2 @@
1
+ var a={anyOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"null"}]},r={$id:"https://frontfriend.dev/schemas/components-config.schema.json",type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"},$defs:{classValue:a,classMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/classMap"}]}},propMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/propMap"}]}},componentEnvelope:{type:"object",additionalProperties:!1,properties:{root:{anyOf:[{type:"string"},{type:"null"}]},variants:{type:"object",additionalProperties:{$ref:"#/$defs/classMap"}},variant:{$ref:"#/$defs/classMap"},size:{$ref:"#/$defs/classMap"},sizes:{$ref:"#/$defs/classMap"},iconPosition:{$ref:"#/$defs/classMap"},color:{$ref:"#/$defs/classMap"},fullwidth:{$ref:"#/$defs/classMap"},slots:{type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"}},icon:{$ref:"#/$defs/componentEnvelope"},states:{$ref:"#/$defs/classMap"},compoundVariants:{$ref:"#/$defs/classMap"},defaultVariants:{$ref:"#/$defs/propMap"},props:{$ref:"#/$defs/propMap"}}}}};function o(e){if(typeof e!="string"||e.trim().length===0||/^[0-9]+$/.test(e)||e==="true"||e==="false")return!1;let s=/\s/.test(e),t=/[-:\[\]\/]/.test(e);return!0}module.exports={componentsConfigSchema:r,isCSSClassString:o};
2
+ //# sourceMappingURL=components-config-schema.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../lib/core/components-config-schema.js"],
4
+ "sourcesContent": ["/**\n * Shared componentsConfig schema for FrontFriend tools.\n *\n * The schema defines the canonical per-component envelope used by ffdc,\n * validation scripts, migration tooling, and registry completeness checks.\n * Keep this file as the single source of truth; consumers should re-export it\n * instead of maintaining local schema copies.\n */\n\nconst classValueSchema = {\n anyOf: [\n { type: 'string' },\n { type: 'number' },\n { type: 'boolean' },\n { type: 'null' },\n ],\n};\n\nconst componentsConfigSchema = {\n $id: 'https://frontfriend.dev/schemas/components-config.schema.json',\n type: 'object',\n additionalProperties: { $ref: '#/$defs/componentEnvelope' },\n $defs: {\n classValue: classValueSchema,\n classMap: {\n type: 'object',\n additionalProperties: {\n anyOf: [\n { $ref: '#/$defs/classValue' },\n { $ref: '#/$defs/classMap' },\n ],\n },\n },\n propMap: {\n type: 'object',\n additionalProperties: {\n anyOf: [\n { $ref: '#/$defs/classValue' },\n { $ref: '#/$defs/propMap' },\n ],\n },\n },\n componentEnvelope: {\n type: 'object',\n additionalProperties: false,\n properties: {\n // Root classes for the component itself.\n root: { anyOf: [{ type: 'string' }, { type: 'null' }] },\n\n // Canonical variant buckets: variants.variant, variants.size,\n // variants.iconPosition, etc. Values stay recursive so leaves can be\n // overridden independently during deep merges.\n variants: {\n type: 'object',\n additionalProperties: { $ref: '#/$defs/classMap' },\n },\n\n // Compatibility aliases for existing component code while v4 sources\n // move to the canonical variants/slots envelope.\n variant: { $ref: '#/$defs/classMap' },\n size: { $ref: '#/$defs/classMap' },\n sizes: { $ref: '#/$defs/classMap' },\n iconPosition: { $ref: '#/$defs/classMap' },\n color: { $ref: '#/$defs/classMap' },\n fullwidth: { $ref: '#/$defs/classMap' },\n\n // Named child slots. Each slot uses the same envelope so tooling can be\n // generic instead of component-specific.\n slots: {\n type: 'object',\n additionalProperties: { $ref: '#/$defs/componentEnvelope' },\n },\n\n // Compatibility alias for the Button icon slot.\n icon: { $ref: '#/$defs/componentEnvelope' },\n\n states: { $ref: '#/$defs/classMap' },\n compoundVariants: { $ref: '#/$defs/classMap' },\n defaultVariants: { $ref: '#/$defs/propMap' },\n props: { $ref: '#/$defs/propMap' },\n },\n },\n },\n};\n\nfunction isCSSClassString(value) {\n if (typeof value !== 'string') return false;\n\n if (value.trim().length === 0) return false;\n\n if (/^[0-9]+$/.test(value)) return false;\n\n if (value === 'true' || value === 'false') return false;\n\n const hasSpaces = /\\s/.test(value);\n const hasTailwindSyntax = /[-:\\[\\]\\/]/.test(value);\n\n if (hasSpaces || hasTailwindSyntax) return true;\n\n return true;\n}\n\nmodule.exports = {\n componentsConfigSchema,\n isCSSClassString,\n};\n"],
5
+ "mappings": "AASA,IAAMA,EAAmB,CACvB,MAAO,CACL,CAAE,KAAM,QAAS,EACjB,CAAE,KAAM,QAAS,EACjB,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,MAAO,CACjB,CACF,EAEMC,EAAyB,CAC7B,IAAK,gEACL,KAAM,SACN,qBAAsB,CAAE,KAAM,2BAA4B,EAC1D,MAAO,CACL,WAAYD,EACZ,SAAU,CACR,KAAM,SACN,qBAAsB,CACpB,MAAO,CACL,CAAE,KAAM,oBAAqB,EAC7B,CAAE,KAAM,kBAAmB,CAC7B,CACF,CACF,EACA,QAAS,CACP,KAAM,SACN,qBAAsB,CACpB,MAAO,CACL,CAAE,KAAM,oBAAqB,EAC7B,CAAE,KAAM,iBAAkB,CAC5B,CACF,CACF,EACA,kBAAmB,CACjB,KAAM,SACN,qBAAsB,GACtB,WAAY,CAEV,KAAM,CAAE,MAAO,CAAC,CAAE,KAAM,QAAS,EAAG,CAAE,KAAM,MAAO,CAAC,CAAE,EAKtD,SAAU,CACR,KAAM,SACN,qBAAsB,CAAE,KAAM,kBAAmB,CACnD,EAIA,QAAS,CAAE,KAAM,kBAAmB,EACpC,KAAM,CAAE,KAAM,kBAAmB,EACjC,MAAO,CAAE,KAAM,kBAAmB,EAClC,aAAc,CAAE,KAAM,kBAAmB,EACzC,MAAO,CAAE,KAAM,kBAAmB,EAClC,UAAW,CAAE,KAAM,kBAAmB,EAItC,MAAO,CACL,KAAM,SACN,qBAAsB,CAAE,KAAM,2BAA4B,CAC5D,EAGA,KAAM,CAAE,KAAM,2BAA4B,EAE1C,OAAQ,CAAE,KAAM,kBAAmB,EACnC,iBAAkB,CAAE,KAAM,kBAAmB,EAC7C,gBAAiB,CAAE,KAAM,iBAAkB,EAC3C,MAAO,CAAE,KAAM,iBAAkB,CACnC,CACF,CACF,CACF,EAEA,SAASE,EAAiBC,EAAO,CAO/B,GANI,OAAOA,GAAU,UAEjBA,EAAM,KAAK,EAAE,SAAW,GAExB,WAAW,KAAKA,CAAK,GAErBA,IAAU,QAAUA,IAAU,QAAS,MAAO,GAElD,IAAMC,EAAY,KAAK,KAAKD,CAAK,EAC3BE,EAAoB,aAAa,KAAKF,CAAK,EAEjD,MAA2C,EAG7C,CAEA,OAAO,QAAU,CACf,uBAAAF,EACA,iBAAAC,CACF",
6
+ "names": ["classValueSchema", "componentsConfigSchema", "isCSSClassString", "value", "hasSpaces", "hasTailwindSyntax"]
7
+ }
package/dist/ffdc.d.ts CHANGED
@@ -3,4 +3,6 @@
3
3
  * @param config - Design configuration object
4
4
  * @returns Processed configuration
5
5
  */
6
- export function ffdc(config: Record<string, any> | null | undefined): Record<string, any>;
6
+ export function ffdc(config: Record<string, any> | null | undefined): Record<string, any>;
7
+ export const componentsConfigSchema: Record<string, any>;
8
+ export function isCSSClassString(value: string): boolean;
package/dist/ffdc.js CHANGED
@@ -1,2 +1,2 @@
1
- module.exports=function(r){if(!r)return{};if(typeof r!="object")throw new Error("Config must be an object");return r};
1
+ var n=(e,s)=>()=>(s||e((s={exports:{}}).exports,s),s.exports);var o=n(($,r)=>{var f={anyOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"null"}]},p={$id:"https://frontfriend.dev/schemas/components-config.schema.json",type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"},$defs:{classValue:f,classMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/classMap"}]}},propMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/propMap"}]}},componentEnvelope:{type:"object",additionalProperties:!1,properties:{root:{anyOf:[{type:"string"},{type:"null"}]},variants:{type:"object",additionalProperties:{$ref:"#/$defs/classMap"}},variant:{$ref:"#/$defs/classMap"},size:{$ref:"#/$defs/classMap"},sizes:{$ref:"#/$defs/classMap"},iconPosition:{$ref:"#/$defs/classMap"},color:{$ref:"#/$defs/classMap"},fullwidth:{$ref:"#/$defs/classMap"},slots:{type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"}},icon:{$ref:"#/$defs/componentEnvelope"},states:{$ref:"#/$defs/classMap"},compoundVariants:{$ref:"#/$defs/classMap"},defaultVariants:{$ref:"#/$defs/propMap"},props:{$ref:"#/$defs/propMap"}}}}};function i(e){if(typeof e!="string"||e.trim().length===0||/^[0-9]+$/.test(e)||e==="true"||e==="false")return!1;let s=/\s/.test(e),a=/[-:\[\]\/]/.test(e);return!0}r.exports={componentsConfigSchema:p,isCSSClassString:i}});var{componentsConfigSchema:c,isCSSClassString:l}=o();function t(e){if(!e)return{};if(typeof e!="object")throw new Error("Config must be an object");return e}t.componentsConfigSchema=c;t.isCSSClassString=l;module.exports=t;
2
2
  //# sourceMappingURL=ffdc.js.map
package/dist/ffdc.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../ffdc.js"],
4
- "sourcesContent": ["// ffdc.js - Simple config accessor\n// No base64 decoding, just returns the config object directly\n\nmodule.exports = function ffdc(config) {\n if (!config) {\n return {};\n }\n \n if (typeof config !== 'object') {\n throw new Error('Config must be an object');\n }\n \n return config;\n};"],
5
- "mappings": "AAGA,OAAO,QAAU,SAAcA,EAAQ,CACrC,GAAI,CAACA,EACH,MAAO,CAAC,EAGV,GAAI,OAAOA,GAAW,SACpB,MAAM,IAAI,MAAM,0BAA0B,EAG5C,OAAOA,CACT",
6
- "names": ["config"]
3
+ "sources": ["../lib/core/components-config-schema.js", "../ffdc.js"],
4
+ "sourcesContent": ["/**\n * Shared componentsConfig schema for FrontFriend tools.\n *\n * The schema defines the canonical per-component envelope used by ffdc,\n * validation scripts, migration tooling, and registry completeness checks.\n * Keep this file as the single source of truth; consumers should re-export it\n * instead of maintaining local schema copies.\n */\n\nconst classValueSchema = {\n anyOf: [\n { type: 'string' },\n { type: 'number' },\n { type: 'boolean' },\n { type: 'null' },\n ],\n};\n\nconst componentsConfigSchema = {\n $id: 'https://frontfriend.dev/schemas/components-config.schema.json',\n type: 'object',\n additionalProperties: { $ref: '#/$defs/componentEnvelope' },\n $defs: {\n classValue: classValueSchema,\n classMap: {\n type: 'object',\n additionalProperties: {\n anyOf: [\n { $ref: '#/$defs/classValue' },\n { $ref: '#/$defs/classMap' },\n ],\n },\n },\n propMap: {\n type: 'object',\n additionalProperties: {\n anyOf: [\n { $ref: '#/$defs/classValue' },\n { $ref: '#/$defs/propMap' },\n ],\n },\n },\n componentEnvelope: {\n type: 'object',\n additionalProperties: false,\n properties: {\n // Root classes for the component itself.\n root: { anyOf: [{ type: 'string' }, { type: 'null' }] },\n\n // Canonical variant buckets: variants.variant, variants.size,\n // variants.iconPosition, etc. Values stay recursive so leaves can be\n // overridden independently during deep merges.\n variants: {\n type: 'object',\n additionalProperties: { $ref: '#/$defs/classMap' },\n },\n\n // Compatibility aliases for existing component code while v4 sources\n // move to the canonical variants/slots envelope.\n variant: { $ref: '#/$defs/classMap' },\n size: { $ref: '#/$defs/classMap' },\n sizes: { $ref: '#/$defs/classMap' },\n iconPosition: { $ref: '#/$defs/classMap' },\n color: { $ref: '#/$defs/classMap' },\n fullwidth: { $ref: '#/$defs/classMap' },\n\n // Named child slots. Each slot uses the same envelope so tooling can be\n // generic instead of component-specific.\n slots: {\n type: 'object',\n additionalProperties: { $ref: '#/$defs/componentEnvelope' },\n },\n\n // Compatibility alias for the Button icon slot.\n icon: { $ref: '#/$defs/componentEnvelope' },\n\n states: { $ref: '#/$defs/classMap' },\n compoundVariants: { $ref: '#/$defs/classMap' },\n defaultVariants: { $ref: '#/$defs/propMap' },\n props: { $ref: '#/$defs/propMap' },\n },\n },\n },\n};\n\nfunction isCSSClassString(value) {\n if (typeof value !== 'string') return false;\n\n if (value.trim().length === 0) return false;\n\n if (/^[0-9]+$/.test(value)) return false;\n\n if (value === 'true' || value === 'false') return false;\n\n const hasSpaces = /\\s/.test(value);\n const hasTailwindSyntax = /[-:\\[\\]\\/]/.test(value);\n\n if (hasSpaces || hasTailwindSyntax) return true;\n\n return true;\n}\n\nmodule.exports = {\n componentsConfigSchema,\n isCSSClassString,\n};\n", "// ffdc.js - Simple config accessor\n// No base64 decoding, just returns the config object directly\n\nconst {\n componentsConfigSchema,\n isCSSClassString,\n} = require('./lib/core/components-config-schema');\n\nfunction ffdc(config) {\n if (!config) {\n return {};\n }\n\n if (typeof config !== 'object') {\n throw new Error('Config must be an object');\n }\n\n return config;\n}\n\nffdc.componentsConfigSchema = componentsConfigSchema;\nffdc.isCSSClassString = isCSSClassString;\n\nmodule.exports = ffdc;\n"],
5
+ "mappings": "8DAAA,IAAAA,EAAAC,EAAA,CAAAC,EAAAC,IAAA,CASA,IAAMC,EAAmB,CACvB,MAAO,CACL,CAAE,KAAM,QAAS,EACjB,CAAE,KAAM,QAAS,EACjB,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,MAAO,CACjB,CACF,EAEMC,EAAyB,CAC7B,IAAK,gEACL,KAAM,SACN,qBAAsB,CAAE,KAAM,2BAA4B,EAC1D,MAAO,CACL,WAAYD,EACZ,SAAU,CACR,KAAM,SACN,qBAAsB,CACpB,MAAO,CACL,CAAE,KAAM,oBAAqB,EAC7B,CAAE,KAAM,kBAAmB,CAC7B,CACF,CACF,EACA,QAAS,CACP,KAAM,SACN,qBAAsB,CACpB,MAAO,CACL,CAAE,KAAM,oBAAqB,EAC7B,CAAE,KAAM,iBAAkB,CAC5B,CACF,CACF,EACA,kBAAmB,CACjB,KAAM,SACN,qBAAsB,GACtB,WAAY,CAEV,KAAM,CAAE,MAAO,CAAC,CAAE,KAAM,QAAS,EAAG,CAAE,KAAM,MAAO,CAAC,CAAE,EAKtD,SAAU,CACR,KAAM,SACN,qBAAsB,CAAE,KAAM,kBAAmB,CACnD,EAIA,QAAS,CAAE,KAAM,kBAAmB,EACpC,KAAM,CAAE,KAAM,kBAAmB,EACjC,MAAO,CAAE,KAAM,kBAAmB,EAClC,aAAc,CAAE,KAAM,kBAAmB,EACzC,MAAO,CAAE,KAAM,kBAAmB,EAClC,UAAW,CAAE,KAAM,kBAAmB,EAItC,MAAO,CACL,KAAM,SACN,qBAAsB,CAAE,KAAM,2BAA4B,CAC5D,EAGA,KAAM,CAAE,KAAM,2BAA4B,EAE1C,OAAQ,CAAE,KAAM,kBAAmB,EACnC,iBAAkB,CAAE,KAAM,kBAAmB,EAC7C,gBAAiB,CAAE,KAAM,iBAAkB,EAC3C,MAAO,CAAE,KAAM,iBAAkB,CACnC,CACF,CACF,CACF,EAEA,SAASE,EAAiBC,EAAO,CAO/B,GANI,OAAOA,GAAU,UAEjBA,EAAM,KAAK,EAAE,SAAW,GAExB,WAAW,KAAKA,CAAK,GAErBA,IAAU,QAAUA,IAAU,QAAS,MAAO,GAElD,IAAMC,EAAY,KAAK,KAAKD,CAAK,EAC3BE,EAAoB,aAAa,KAAKF,CAAK,EAEjD,MAA2C,EAG7C,CAEAJ,EAAO,QAAU,CACf,uBAAAE,EACA,iBAAAC,CACF,ICtGA,GAAM,CACJ,uBAAAI,EACA,iBAAAC,CACF,EAAI,IAEJ,SAASC,EAAKC,EAAQ,CACpB,GAAI,CAACA,EACH,MAAO,CAAC,EAGV,GAAI,OAAOA,GAAW,SACpB,MAAM,IAAI,MAAM,0BAA0B,EAG5C,OAAOA,CACT,CAEAD,EAAK,uBAAyBF,EAC9BE,EAAK,iBAAmBD,EAExB,OAAO,QAAUC",
6
+ "names": ["require_components_config_schema", "__commonJSMin", "exports", "module", "classValueSchema", "componentsConfigSchema", "isCSSClassString", "value", "hasSpaces", "hasTailwindSyntax", "componentsConfigSchema", "isCSSClassString", "ffdc", "config"]
7
7
  }
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var y=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var D=y((de,F)=>{var m=require("fs");function L(e){try{let n=m.readFileSync(e,"utf8");return JSON.parse(n)}catch(n){if(n.code==="ENOENT")return null;throw n}}function q(e){try{return m.readFileSync(e,"utf8").replace(/^\uFEFF/,"")}catch(n){if(n.code==="ENOENT")return null;throw n}}function R(e,n,i=2){let r=JSON.stringify(n,null,i);m.writeFileSync(e,r,"utf8")}function P(e,n){if(n==null||typeof n=="object"&&Object.keys(n).length===0||Array.isArray(n)&&n.length===0){let r=`module.exports = ${Array.isArray(n)?"[]":"{}"};`;m.writeFileSync(e,r,"utf8")}else{let i=`module.exports = ${JSON.stringify(n,null,2)};`;m.writeFileSync(e,i,"utf8")}}function K(e){return m.existsSync(e)}function M(e){m.mkdirSync(e,{recursive:!0})}function Y(e){m.rmSync(e,{recursive:!0,force:!0})}F.exports={readJsonFileSafe:L,readFileSafe:q,writeJsonFile:R,writeModuleExportsFile:P,fileExists:K,ensureDirectoryExists:M,removeDirectory:Y}});var O=y((pe,W)=>{W.exports={name:"dotenv",version:"16.6.1",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard",pretest:"npm run lint && npm run dts-check",test:"tap run --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},homepage:"https://github.com/motdotla/dotenv#readme",funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@types/node":"^18.11.3",decache:"^4.6.2",sinon:"^14.0.1",standard:"^17.0.0","standard-version":"^9.5.0",tap:"^19.2.0",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var T=y((ve,v)=>{var _=require("fs"),b=require("path"),B=require("os"),J=require("crypto"),G=O(),E=G.version,U=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function Q(e){let n={},i=e.toString();i=i.replace(/\r\n?/mg,`
2
- `);let r;for(;(r=U.exec(i))!=null;){let f=r[1],c=r[2]||"";c=c.trim();let o=c[0];c=c.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),o==='"'&&(c=c.replace(/\\n/g,`
3
- `),c=c.replace(/\\r/g,"\r")),n[f]=c}return n}function z(e){e=e||{};let n=j(e);e.path=n;let i=d.configDotenv(e);if(!i.parsed){let o=new Error(`MISSING_DATA: Cannot parse ${n} for an unknown reason`);throw o.code="MISSING_DATA",o}let r=k(e).split(","),f=r.length,c;for(let o=0;o<f;o++)try{let l=r[o].trim(),t=X(i,l);c=d.decrypt(t.ciphertext,t.key);break}catch(l){if(o+1>=f)throw l}return d.parse(c)}function H(e){console.log(`[dotenv@${E}][WARN] ${e}`)}function h(e){console.log(`[dotenv@${E}][DEBUG] ${e}`)}function $(e){console.log(`[dotenv@${E}] ${e}`)}function k(e){return e&&e.DOTENV_KEY&&e.DOTENV_KEY.length>0?e.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function X(e,n){let i;try{i=new URL(n)}catch(l){if(l.code==="ERR_INVALID_URL"){let t=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw t.code="INVALID_DOTENV_KEY",t}throw l}let r=i.password;if(!r){let l=new Error("INVALID_DOTENV_KEY: Missing key part");throw l.code="INVALID_DOTENV_KEY",l}let f=i.searchParams.get("environment");if(!f){let l=new Error("INVALID_DOTENV_KEY: Missing environment part");throw l.code="INVALID_DOTENV_KEY",l}let c=`DOTENV_VAULT_${f.toUpperCase()}`,o=e.parsed[c];if(!o){let l=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${c} in your .env.vault file.`);throw l.code="NOT_FOUND_DOTENV_ENVIRONMENT",l}return{ciphertext:o,key:r}}function j(e){let n=null;if(e&&e.path&&e.path.length>0)if(Array.isArray(e.path))for(let i of e.path)_.existsSync(i)&&(n=i.endsWith(".vault")?i:`${i}.vault`);else n=e.path.endsWith(".vault")?e.path:`${e.path}.vault`;else n=b.resolve(process.cwd(),".env.vault");return _.existsSync(n)?n:null}function N(e){return e[0]==="~"?b.join(B.homedir(),e.slice(1)):e}function Z(e){let n=!!(e&&e.debug),i=e&&"quiet"in e?e.quiet:!0;(n||!i)&&$("Loading env from encrypted .env.vault");let r=d._parseVault(e),f=process.env;return e&&e.processEnv!=null&&(f=e.processEnv),d.populate(f,r,e),{parsed:r}}function ee(e){let n=b.resolve(process.cwd(),".env"),i="utf8",r=!!(e&&e.debug),f=e&&"quiet"in e?e.quiet:!0;e&&e.encoding?i=e.encoding:r&&h("No encoding is specified. UTF-8 is used by default");let c=[n];if(e&&e.path)if(!Array.isArray(e.path))c=[N(e.path)];else{c=[];for(let a of e.path)c.push(N(a))}let o,l={};for(let a of c)try{let s=d.parse(_.readFileSync(a,{encoding:i}));d.populate(l,s,e)}catch(s){r&&h(`Failed to load ${a} ${s.message}`),o=s}let t=process.env;if(e&&e.processEnv!=null&&(t=e.processEnv),d.populate(t,l,e),r||!f){let a=Object.keys(l).length,s=[];for(let u of c)try{let p=b.relative(process.cwd(),u);s.push(p)}catch(p){r&&h(`Failed to load ${u} ${p.message}`),o=p}$(`injecting env (${a}) from ${s.join(",")}`)}return o?{parsed:l,error:o}:{parsed:l}}function te(e){if(k(e).length===0)return d.configDotenv(e);let n=j(e);return n?d._configVault(e):(H(`You set DOTENV_KEY but you are missing a .env.vault file at ${n}. Did you forget to build it?`),d.configDotenv(e))}function ne(e,n){let i=Buffer.from(n.slice(-64),"hex"),r=Buffer.from(e,"base64"),f=r.subarray(0,12),c=r.subarray(-16);r=r.subarray(12,-16);try{let o=J.createDecipheriv("aes-256-gcm",i,f);return o.setAuthTag(c),`${o.update(r)}${o.final()}`}catch(o){let l=o instanceof RangeError,t=o.message==="Invalid key length",a=o.message==="Unsupported state or unable to authenticate data";if(l||t){let s=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw s.code="INVALID_DOTENV_KEY",s}else if(a){let s=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw s.code="DECRYPTION_FAILED",s}else throw o}}function re(e,n,i={}){let r=!!(i&&i.debug),f=!!(i&&i.override);if(typeof n!="object"){let c=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw c.code="OBJECT_REQUIRED",c}for(let c of Object.keys(n))Object.prototype.hasOwnProperty.call(e,c)?(f===!0&&(e[c]=n[c]),r&&h(f===!0?`"${c}" is already defined and WAS overwritten`:`"${c}" is already defined and was NOT overwritten`)):e[c]=n[c]}var d={configDotenv:ee,_configVault:Z,_parseVault:z,config:te,decrypt:ne,parse:Q,populate:re};v.exports.configDotenv=d.configDotenv;v.exports._configVault=d._configVault;v.exports._parseVault=d._parseVault;v.exports.config=d.config;v.exports.decrypt=d.decrypt;v.exports.parse=d.parse;v.exports.populate=d.populate;v.exports=d});var S=y((ge,V)=>{var oe=require("path"),{fileExists:ie}=D();function ae(e=process.cwd()){let n=oe.join(e,".env.local");return ie(n)?(T().config({path:n}),console.log("\u{1F4C4} Loaded .env.local"),!0):!1}function se(e,n=void 0){return process.env[e]||n}function ce(e){return process.env[e]==="true"}V.exports={loadEnvLocal:ae,getEnvVar:se,isEnvTrue:ce}});var I=y((me,C)=>{C.exports=function(n){if(!n)return{};if(typeof n!="object")throw new Error("Config must be an object");return n}});var le=require("tailwindcss/plugin"),x;try{x=require("postcss")}catch{x=null}var g;if(typeof window>"u"&&typeof process<"u"&&process.versions&&process.versions.node){g=require("./lib/core/cache-manager");let{loadEnvLocal:e}=S();e()}function A(e){return Object.fromEntries(Object.entries(e).filter(([n])=>n!=="DEFAULT"))}var fe=le.withOptions(function(e={}){return function({addBase:n,addUtilities:i,theme:r,matchUtilities:f}){if(!g)return;let c=new g(process.cwd());if(!c.exists()){console.warn('[FrontFriend] No cache found. Please run "npx frontfriend init" first.');return}c.isValid()||console.warn('[FrontFriend] Cache is expired. Please run "npx frontfriend init" to refresh.');let o=c.load();if(!o){console.error("[FrontFriend] Failed to load cache.");return}let l={};if(o.variables)for(let[t,a]of Object.entries(o.variables))t.startsWith("--color-")&&!a.startsWith("hsl(")?l[t]=`hsl(${a})`:l[t]=a;if(o.semanticVariables)for(let[t,a]of Object.entries(o.semanticVariables))typeof a=="string"&&!a.startsWith("var(")&&!a.startsWith("hsl(")&&/^\d+\s+\d+%\s+\d+%/.test(a)?l[t]=`hsl(${a})`:l[t]=a;if(n({":root":l}),o.semanticDarkVariables&&Object.keys(o.semanticDarkVariables).length>0){let t={};for(let[a,s]of Object.entries(o.semanticDarkVariables))typeof s=="string"&&!s.startsWith("var(")&&!s.startsWith("hsl(")&&/^\d+\s+\d+%\s+\d+%/.test(s)?t[a]=`hsl(${s})`:t[a]=s;n({":root:not(.light)":t}),n({":root:not(.dark)":l})}if(o.semanticVariables){let t={};for(let[a]of Object.entries(o.semanticVariables)){let s=a.match(/^--(bg|text|border|layer|overlay|icon)-(.+)$/);if(s){let[,u,p]=s,w=`.${u}-${p}`;u==="bg"||u==="layer"||u==="overlay"?t[w]={backgroundColor:`var(${a})`}:u==="text"?t[w]={color:`var(${a})`}:u==="border"?t[w]={borderColor:`var(${a})`}:u==="icon"&&(t[`.text-${u}-${p}`]={color:`var(${a})`},t[`.fill-${u}-${p}`]={fill:`var(${a})`})}}i(t)}if(o.tokens){if(o.tokens.backgroundColor){let t={};for(let[a,s]of Object.entries(o.tokens.backgroundColor))t[`.bg-${a}`]={backgroundColor:s};i(t)}if(o.tokens.textColor){let t={};for(let[a,s]of Object.entries(o.tokens.textColor))t[`.text-${a}`]={color:s};i(t)}if(o.tokens.borderColor){let t={};for(let[a,s]of Object.entries(o.tokens.borderColor))t[`.border-${a}`]={borderColor:s};i(t)}if(o.tokens.fill){let t={},a={};for(let[s,u]of Object.entries(o.tokens.fill))t[`.fill-${s}`]={fill:u},s.startsWith("icon-")&&(a[`.text-${s}`]={color:u});i(t),i(a)}if(o.tokens.fontFamily){let t={};for(let[a,s]of Object.entries(o.tokens.fontFamily))t[`.font-${a}`]={fontFamily:s};i(t)}}if(o.fonts&&o.fonts.length>0&&o.fonts.forEach(t=>{n({"@font-face":t})}),i({"@keyframes enter":r("keyframes.enter"),"@keyframes exit":r("keyframes.exit"),".animate-in":{animationName:"enter",animationDuration:r("animationDuration.DEFAULT"),"--tw-enter-opacity":"initial","--tw-enter-scale":"initial","--tw-enter-rotate":"initial","--tw-enter-translate-x":"initial","--tw-enter-translate-y":"initial"},".animate-out":{animationName:"exit",animationDuration:r("animationDuration.DEFAULT"),"--tw-exit-opacity":"initial","--tw-exit-scale":"initial","--tw-exit-rotate":"initial","--tw-exit-translate-x":"initial","--tw-exit-translate-y":"initial"}}),f({"fade-in":t=>({"--tw-enter-opacity":t}),"fade-out":t=>({"--tw-exit-opacity":t})},{values:r("animationOpacity")}),f({"zoom-in":t=>({"--tw-enter-scale":t}),"zoom-out":t=>({"--tw-exit-scale":t})},{values:r("animationScale")}),f({"spin-in":t=>({"--tw-enter-rotate":t}),"spin-out":t=>({"--tw-exit-rotate":t})},{values:r("animationRotate")}),f({"slide-in-from-top":t=>({"--tw-enter-translate-y":`-${t}`}),"slide-in-from-bottom":t=>({"--tw-enter-translate-y":t}),"slide-in-from-left":t=>({"--tw-enter-translate-x":`-${t}`}),"slide-in-from-right":t=>({"--tw-enter-translate-x":t}),"slide-out-to-top":t=>({"--tw-exit-translate-y":`-${t}`}),"slide-out-to-bottom":t=>({"--tw-exit-translate-y":t}),"slide-out-to-left":t=>({"--tw-exit-translate-x":`-${t}`}),"slide-out-to-right":t=>({"--tw-exit-translate-x":t})},{values:r("animationTranslate")}),f({duration:t=>({animationDuration:t})},{values:A(r("animationDuration"))}),f({delay:t=>({animationDelay:t})},{values:r("animationDelay")}),f({ease:t=>({animationTimingFunction:t})},{values:A(r("animationTimingFunction"))}),i({".running":{animationPlayState:"running"},".paused":{animationPlayState:"paused"}}),i({".px-ff-main":{paddingLeft:"var(--ff-main-px)",paddingRight:"var(--ff-main-px)"},".py-ff-main":{paddingTop:"var(--ff-main-py)",paddingBottom:"var(--ff-main-py)"},".p-ff-main":{paddingLeft:"var(--ff-main-px)",paddingRight:"var(--ff-main-px)",paddingTop:"var(--ff-main-py)",paddingBottom:"var(--ff-main-py)"}}),f({"fill-mode":t=>({animationFillMode:t})},{values:r("animationFillMode")}),f({direction:t=>({animationDirection:t})},{values:r("animationDirection")}),f({repeat:t=>({animationIterationCount:t})},{values:r("animationRepeat")}),o.custom&&o.custom.raw&&typeof o.custom.raw=="string"){let t=o.custom.raw.trim();if(!t){e.verbose&&console.warn("[FrontFriend] Empty custom CSS");return}if(!x){console.warn("[FrontFriend] PostCSS not available - custom CSS will not be added");return}try{let a=x.parse(t),s=[],u=[];a.each(p=>{if(p.type==="atrule"){s.push(p);return}if(p.type==="rule"){typeof p.selector=="string"&&p.selector.trim().startsWith(".")?u.push(p):s.push(p);return}p.type!=="comment"&&s.push(p)}),s.length>0&&n(s),u.length>0&&i(u),e.verbose&&console.log(`[FrontFriend] Added custom CSS: ${s.length} base rules, ${u.length} utility classes`)}catch(a){console.error("[FrontFriend] Failed to parse custom CSS:",a.message)}}else if(!o.custom){let t=require("fs"),s=require("path").join(process.cwd(),"node_modules",".cache","frontfriend","custom.js");t.existsSync(s)&&(console.warn("[FrontFriend] custom.js file exists but failed to load. This may be due to a parsing error or BOM issue."),console.warn("[FrontFriend] Try deleting node_modules/.cache/frontfriend and running `npx frontfriend init` again."))}e.verbose&&(console.log("[FrontFriend] Plugin loaded successfully"),console.log(`[FrontFriend] Colors: ${Object.keys(o.variables||{}).length}`),console.log(`[FrontFriend] Semantic vars: ${Object.keys(o.semanticVariables||{}).length}`),console.log(`[FrontFriend] Fonts: ${(o.fonts||[]).length}`),console.log(`[FrontFriend] Safelist classes: ${Array.isArray(o.safelist)?o.safelist.length:0}`))}},function(e={}){let n=null;if(g){let r=new g(process.cwd());n=r.exists()?r.load():null}let i=["./pages/**/*.{js,ts,jsx,tsx}","./components/**/*.{js,ts,jsx,tsx}","./app/**/*.{js,ts,jsx,tsx}","./src/**/*.{js,ts,jsx,tsx}","./stories/**/*.{js,ts,jsx,tsx}"];return e.verbose&&n&&(console.log("[FrontFriend] Cache loaded successfully"),n.safelist&&Array.isArray(n.safelist)&&console.log(`[FrontFriend] Loading ${n.safelist.length} classes for safelist`)),{theme:{extend:{colors:e.extendColors||{},animation:e.extendAnimations||{},spacing:{18:"4.5rem",88:"22rem",128:"32rem"},boxShadow:{"top-sm":"0 -1px 1px 0 rgba(0, 0, 0, 0.05)"},borderRadius:{"2xl":"1rem"},animationDelay:({theme:r})=>({...r("transitionDelay")}),animationDuration:({theme:r})=>({0:"0ms",...r("transitionDuration")}),animationTimingFunction:({theme:r})=>({...r("transitionTimingFunction")}),animationFillMode:{none:"none",forwards:"forwards",backwards:"backwards",both:"both"},animationDirection:{normal:"normal",reverse:"reverse",alternate:"alternate","alternate-reverse":"alternate-reverse"},animationOpacity:({theme:r})=>({DEFAULT:0,...r("opacity")}),animationTranslate:({theme:r})=>({DEFAULT:"100%",...r("translate")}),animationScale:({theme:r})=>({DEFAULT:0,...r("scale")}),animationRotate:({theme:r})=>({DEFAULT:"30deg",...r("rotate")}),animationRepeat:{0:"0",1:"1",infinite:"infinite"},keyframes:{enter:{from:{opacity:"var(--tw-enter-opacity, 1)",transform:"translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))"}},exit:{to:{opacity:"var(--tw-exit-opacity, 1)",transform:"translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))"}}}}},safelist:[...((n==null?void 0:n.safelist)||[]).filter(r=>typeof r!="string"||!r.startsWith("file:")),{pattern:/(text|fill)-icon-(neutral|positive|negative|warning|info|highlight|interactive|brand|inverse|onpositive|onnegative|onwarning|oninfo|onhighlight|oninteractive|onbrand)-(mid|strong|subtle|low)(-(neutral|hover|active|selected|disabled))?$/},{pattern:/^(layer-(below|surface|raised|popover|dialog|control)|overlay-(mid|strong|subtle|low))$/}],content:e.content||i}});module.exports=fe;Object.defineProperty(module.exports,"config",{get:function(){if(typeof __FF_CONFIG__<"u")return __FF_CONFIG__;if(typeof window<"u"&&window.__FF_CONFIG__)return window.__FF_CONFIG__;if(g)try{let e=new g(process.cwd());if(e.exists()){let n=e.load();if(n)return n.componentsConfig||null}}catch{}return null}});Object.defineProperty(module.exports,"iconSet",{get:function(){if(typeof __FF_ICONS__<"u")return __FF_ICONS__;if(typeof window<"u"&&window.__FF_ICONS__)return window.__FF_ICONS__;if(g)try{let e=new g(process.cwd());if(e.exists()){let n=e.load();if(n)return n.icons||null}}catch{}return null}});module.exports.ffdc=I();
1
+ var v=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var $=v((Ee,D)=>{var q={anyOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"null"}]},R={$id:"https://frontfriend.dev/schemas/components-config.schema.json",type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"},$defs:{classValue:q,classMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/classMap"}]}},propMap:{type:"object",additionalProperties:{anyOf:[{$ref:"#/$defs/classValue"},{$ref:"#/$defs/propMap"}]}},componentEnvelope:{type:"object",additionalProperties:!1,properties:{root:{anyOf:[{type:"string"},{type:"null"}]},variants:{type:"object",additionalProperties:{$ref:"#/$defs/classMap"}},variant:{$ref:"#/$defs/classMap"},size:{$ref:"#/$defs/classMap"},sizes:{$ref:"#/$defs/classMap"},iconPosition:{$ref:"#/$defs/classMap"},color:{$ref:"#/$defs/classMap"},fullwidth:{$ref:"#/$defs/classMap"},slots:{type:"object",additionalProperties:{$ref:"#/$defs/componentEnvelope"}},icon:{$ref:"#/$defs/componentEnvelope"},states:{$ref:"#/$defs/classMap"},compoundVariants:{$ref:"#/$defs/classMap"},defaultVariants:{$ref:"#/$defs/propMap"},props:{$ref:"#/$defs/propMap"}}}}};function K(e){if(typeof e!="string"||e.trim().length===0||/^[0-9]+$/.test(e)||e==="true"||e==="false")return!1;let n=/\s/.test(e),s=/[-:\[\]\/]/.test(e);return!0}D.exports={componentsConfigSchema:R,isCSSClassString:K}});var O=v((_e,S)=>{var m=require("fs");function Y(e){try{let n=m.readFileSync(e,"utf8");return JSON.parse(n)}catch(n){if(n.code==="ENOENT")return null;throw n}}function W(e){try{return m.readFileSync(e,"utf8").replace(/^\uFEFF/,"")}catch(n){if(n.code==="ENOENT")return null;throw n}}function B(e,n,s=2){let r=JSON.stringify(n,null,s);m.writeFileSync(e,r,"utf8")}function J(e,n){m.writeFileSync(e,n,"utf8")}function G(e,n){if(n==null||typeof n=="object"&&Object.keys(n).length===0||Array.isArray(n)&&n.length===0){let r=`module.exports = ${Array.isArray(n)?"[]":"{}"};`;m.writeFileSync(e,r,"utf8")}else{let s=`module.exports = ${JSON.stringify(n,null,2)};`;m.writeFileSync(e,s,"utf8")}}function U(e){return m.existsSync(e)}function z(e){m.mkdirSync(e,{recursive:!0})}function Q(e){m.rmSync(e,{recursive:!0,force:!0})}S.exports={readJsonFileSafe:Y,readFileSafe:W,writeJsonFile:B,writeTextFile:J,writeModuleExportsFile:G,fileExists:U,ensureDirectoryExists:z,removeDirectory:Q}});var N=v((Fe,H)=>{H.exports={name:"dotenv",version:"16.6.1",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard",pretest:"npm run lint && npm run dts-check",test:"tap run --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},homepage:"https://github.com/motdotla/dotenv#readme",funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@types/node":"^18.11.3",decache:"^4.6.2",sinon:"^14.0.1",standard:"^17.0.0","standard-version":"^9.5.0",tap:"^19.2.0",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var T=v((De,g)=>{var E=require("fs"),b=require("path"),X=require("os"),Z=require("crypto"),ee=N(),_=ee.version,te=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function ne(e){let n={},s=e.toString();s=s.replace(/\r\n?/mg,`
2
+ `);let r;for(;(r=te.exec(s))!=null;){let f=r[1],c=r[2]||"";c=c.trim();let o=c[0];c=c.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),o==='"'&&(c=c.replace(/\\n/g,`
3
+ `),c=c.replace(/\\r/g,"\r")),n[f]=c}return n}function re(e){e=e||{};let n=V(e);e.path=n;let s=d.configDotenv(e);if(!s.parsed){let o=new Error(`MISSING_DATA: Cannot parse ${n} for an unknown reason`);throw o.code="MISSING_DATA",o}let r=k(e).split(","),f=r.length,c;for(let o=0;o<f;o++)try{let l=r[o].trim(),t=se(s,l);c=d.decrypt(t.ciphertext,t.key);break}catch(l){if(o+1>=f)throw l}return d.parse(c)}function oe(e){console.log(`[dotenv@${_}][WARN] ${e}`)}function h(e){console.log(`[dotenv@${_}][DEBUG] ${e}`)}function C(e){console.log(`[dotenv@${_}] ${e}`)}function k(e){return e&&e.DOTENV_KEY&&e.DOTENV_KEY.length>0?e.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function se(e,n){let s;try{s=new URL(n)}catch(l){if(l.code==="ERR_INVALID_URL"){let t=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw t.code="INVALID_DOTENV_KEY",t}throw l}let r=s.password;if(!r){let l=new Error("INVALID_DOTENV_KEY: Missing key part");throw l.code="INVALID_DOTENV_KEY",l}let f=s.searchParams.get("environment");if(!f){let l=new Error("INVALID_DOTENV_KEY: Missing environment part");throw l.code="INVALID_DOTENV_KEY",l}let c=`DOTENV_VAULT_${f.toUpperCase()}`,o=e.parsed[c];if(!o){let l=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${c} in your .env.vault file.`);throw l.code="NOT_FOUND_DOTENV_ENVIRONMENT",l}return{ciphertext:o,key:r}}function V(e){let n=null;if(e&&e.path&&e.path.length>0)if(Array.isArray(e.path))for(let s of e.path)E.existsSync(s)&&(n=s.endsWith(".vault")?s:`${s}.vault`);else n=e.path.endsWith(".vault")?e.path:`${e.path}.vault`;else n=b.resolve(process.cwd(),".env.vault");return E.existsSync(n)?n:null}function j(e){return e[0]==="~"?b.join(X.homedir(),e.slice(1)):e}function ae(e){let n=!!(e&&e.debug),s=e&&"quiet"in e?e.quiet:!0;(n||!s)&&C("Loading env from encrypted .env.vault");let r=d._parseVault(e),f=process.env;return e&&e.processEnv!=null&&(f=e.processEnv),d.populate(f,r,e),{parsed:r}}function ie(e){let n=b.resolve(process.cwd(),".env"),s="utf8",r=!!(e&&e.debug),f=e&&"quiet"in e?e.quiet:!0;e&&e.encoding?s=e.encoding:r&&h("No encoding is specified. UTF-8 is used by default");let c=[n];if(e&&e.path)if(!Array.isArray(e.path))c=[j(e.path)];else{c=[];for(let a of e.path)c.push(j(a))}let o,l={};for(let a of c)try{let i=d.parse(E.readFileSync(a,{encoding:s}));d.populate(l,i,e)}catch(i){r&&h(`Failed to load ${a} ${i.message}`),o=i}let t=process.env;if(e&&e.processEnv!=null&&(t=e.processEnv),d.populate(t,l,e),r||!f){let a=Object.keys(l).length,i=[];for(let u of c)try{let p=b.relative(process.cwd(),u);i.push(p)}catch(p){r&&h(`Failed to load ${u} ${p.message}`),o=p}C(`injecting env (${a}) from ${i.join(",")}`)}return o?{parsed:l,error:o}:{parsed:l}}function ce(e){if(k(e).length===0)return d.configDotenv(e);let n=V(e);return n?d._configVault(e):(oe(`You set DOTENV_KEY but you are missing a .env.vault file at ${n}. Did you forget to build it?`),d.configDotenv(e))}function le(e,n){let s=Buffer.from(n.slice(-64),"hex"),r=Buffer.from(e,"base64"),f=r.subarray(0,12),c=r.subarray(-16);r=r.subarray(12,-16);try{let o=Z.createDecipheriv("aes-256-gcm",s,f);return o.setAuthTag(c),`${o.update(r)}${o.final()}`}catch(o){let l=o instanceof RangeError,t=o.message==="Invalid key length",a=o.message==="Unsupported state or unable to authenticate data";if(l||t){let i=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw i.code="INVALID_DOTENV_KEY",i}else if(a){let i=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw i.code="DECRYPTION_FAILED",i}else throw o}}function fe(e,n,s={}){let r=!!(s&&s.debug),f=!!(s&&s.override);if(typeof n!="object"){let c=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw c.code="OBJECT_REQUIRED",c}for(let c of Object.keys(n))Object.prototype.hasOwnProperty.call(e,c)?(f===!0&&(e[c]=n[c]),r&&h(f===!0?`"${c}" is already defined and WAS overwritten`:`"${c}" is already defined and was NOT overwritten`)):e[c]=n[c]}var d={configDotenv:ie,_configVault:ae,_parseVault:re,config:ce,decrypt:le,parse:ne,populate:fe};g.exports.configDotenv=d.configDotenv;g.exports._configVault=d._configVault;g.exports._parseVault=d._parseVault;g.exports.config=d.config;g.exports.decrypt=d.decrypt;g.exports.parse=d.parse;g.exports.populate=d.populate;g.exports=d});var A=v((Se,I)=>{var ue=require("path"),{fileExists:de}=O();function pe(e=process.cwd()){let n=ue.join(e,".env.local");return de(n)?(T().config({path:n}),console.log("\u{1F4C4} Loaded .env.local"),!0):!1}function me(e,n=void 0){return process.env[e]||n}function ge(e){return process.env[e]==="true"}I.exports={loadEnvLocal:pe,getEnvVar:me,isEnvTrue:ge}});var L=v((Oe,M)=>{var{componentsConfigSchema:ye,isCSSClassString:ve}=$();function F(e){if(!e)return{};if(typeof e!="object")throw new Error("Config must be an object");return e}F.componentsConfigSchema=ye;F.isCSSClassString=ve;M.exports=F});var he=require("tailwindcss/plugin"),{componentsConfigSchema:we,isCSSClassString:be}=$(),x;try{x=require("postcss")}catch{x=null}var y;if(typeof window>"u"&&typeof process<"u"&&process.versions&&process.versions.node){y=require("./lib/core/cache-manager");let{loadEnvLocal:e}=A();e()}function P(e){return Object.fromEntries(Object.entries(e).filter(([n])=>n!=="DEFAULT"))}var xe=he.withOptions(function(e={}){return function({addBase:n,addUtilities:s,theme:r,matchUtilities:f}){if(!y)return;let c=new y(process.cwd());if(!c.exists()){console.warn('[FrontFriend] No cache found. Please run "npx frontfriend init" first.');return}c.isValid()||console.warn('[FrontFriend] Cache is expired. Please run "npx frontfriend init" to refresh.');let o=c.load();if(!o){console.error("[FrontFriend] Failed to load cache.");return}let l={};if(o.variables)for(let[t,a]of Object.entries(o.variables))t.startsWith("--color-")&&!a.startsWith("hsl(")?l[t]=`hsl(${a})`:l[t]=a;if(o.semanticVariables)for(let[t,a]of Object.entries(o.semanticVariables))typeof a=="string"&&!a.startsWith("var(")&&!a.startsWith("hsl(")&&/^\d+\s+\d+%\s+\d+%/.test(a)?l[t]=`hsl(${a})`:l[t]=a;if(n({":root":l}),o.semanticDarkVariables&&Object.keys(o.semanticDarkVariables).length>0){let t={};for(let[a,i]of Object.entries(o.semanticDarkVariables))typeof i=="string"&&!i.startsWith("var(")&&!i.startsWith("hsl(")&&/^\d+\s+\d+%\s+\d+%/.test(i)?t[a]=`hsl(${i})`:t[a]=i;n({":root:not(.light)":t}),n({":root:not(.dark)":l})}if(o.semanticVariables){let t={};for(let[a]of Object.entries(o.semanticVariables)){let i=a.match(/^--(bg|text|border|layer|overlay|icon)-(.+)$/);if(i){let[,u,p]=i,w=`.${u}-${p}`;u==="bg"||u==="layer"||u==="overlay"?t[w]={backgroundColor:`var(${a})`}:u==="text"?t[w]={color:`var(${a})`}:u==="border"?t[w]={borderColor:`var(${a})`}:u==="icon"&&(t[`.text-${u}-${p}`]={color:`var(${a})`},t[`.fill-${u}-${p}`]={fill:`var(${a})`})}}s(t)}if(o.tokens){if(o.tokens.backgroundColor){let t={};for(let[a,i]of Object.entries(o.tokens.backgroundColor))t[`.bg-${a}`]={backgroundColor:i};s(t)}if(o.tokens.textColor){let t={};for(let[a,i]of Object.entries(o.tokens.textColor))t[`.text-${a}`]={color:i};s(t)}if(o.tokens.borderColor){let t={};for(let[a,i]of Object.entries(o.tokens.borderColor))t[`.border-${a}`]={borderColor:i};s(t)}if(o.tokens.fill){let t={},a={};for(let[i,u]of Object.entries(o.tokens.fill))t[`.fill-${i}`]={fill:u},i.startsWith("icon-")&&(a[`.text-${i}`]={color:u});s(t),s(a)}if(o.tokens.fontFamily){let t={};for(let[a,i]of Object.entries(o.tokens.fontFamily))t[`.font-${a}`]={fontFamily:i};s(t)}}if(o.fonts&&o.fonts.length>0&&o.fonts.forEach(t=>{n({"@font-face":t})}),s({"@keyframes enter":r("keyframes.enter"),"@keyframes exit":r("keyframes.exit"),".animate-in":{animationName:"enter",animationDuration:r("animationDuration.DEFAULT"),"--tw-enter-opacity":"initial","--tw-enter-scale":"initial","--tw-enter-rotate":"initial","--tw-enter-translate-x":"initial","--tw-enter-translate-y":"initial"},".animate-out":{animationName:"exit",animationDuration:r("animationDuration.DEFAULT"),"--tw-exit-opacity":"initial","--tw-exit-scale":"initial","--tw-exit-rotate":"initial","--tw-exit-translate-x":"initial","--tw-exit-translate-y":"initial"}}),f({"fade-in":t=>({"--tw-enter-opacity":t}),"fade-out":t=>({"--tw-exit-opacity":t})},{values:r("animationOpacity")}),f({"zoom-in":t=>({"--tw-enter-scale":t}),"zoom-out":t=>({"--tw-exit-scale":t})},{values:r("animationScale")}),f({"spin-in":t=>({"--tw-enter-rotate":t}),"spin-out":t=>({"--tw-exit-rotate":t})},{values:r("animationRotate")}),f({"slide-in-from-top":t=>({"--tw-enter-translate-y":`-${t}`}),"slide-in-from-bottom":t=>({"--tw-enter-translate-y":t}),"slide-in-from-left":t=>({"--tw-enter-translate-x":`-${t}`}),"slide-in-from-right":t=>({"--tw-enter-translate-x":t}),"slide-out-to-top":t=>({"--tw-exit-translate-y":`-${t}`}),"slide-out-to-bottom":t=>({"--tw-exit-translate-y":t}),"slide-out-to-left":t=>({"--tw-exit-translate-x":`-${t}`}),"slide-out-to-right":t=>({"--tw-exit-translate-x":t})},{values:r("animationTranslate")}),f({duration:t=>({animationDuration:t})},{values:P(r("animationDuration"))}),f({delay:t=>({animationDelay:t})},{values:r("animationDelay")}),f({ease:t=>({animationTimingFunction:t})},{values:P(r("animationTimingFunction"))}),s({".running":{animationPlayState:"running"},".paused":{animationPlayState:"paused"}}),s({".px-ff-main":{paddingLeft:"var(--ff-main-px)",paddingRight:"var(--ff-main-px)"},".py-ff-main":{paddingTop:"var(--ff-main-py)",paddingBottom:"var(--ff-main-py)"},".p-ff-main":{paddingLeft:"var(--ff-main-px)",paddingRight:"var(--ff-main-px)",paddingTop:"var(--ff-main-py)",paddingBottom:"var(--ff-main-py)"}}),f({"fill-mode":t=>({animationFillMode:t})},{values:r("animationFillMode")}),f({direction:t=>({animationDirection:t})},{values:r("animationDirection")}),f({repeat:t=>({animationIterationCount:t})},{values:r("animationRepeat")}),o.custom&&o.custom.raw&&typeof o.custom.raw=="string"){let t=o.custom.raw.trim();if(!t){e.verbose&&console.warn("[FrontFriend] Empty custom CSS");return}if(!x){console.warn("[FrontFriend] PostCSS not available - custom CSS will not be added");return}try{let a=x.parse(t),i=[],u=[];a.each(p=>{if(p.type==="atrule"){i.push(p);return}if(p.type==="rule"){typeof p.selector=="string"&&p.selector.trim().startsWith(".")?u.push(p):i.push(p);return}p.type!=="comment"&&i.push(p)}),i.length>0&&n(i),u.length>0&&s(u),e.verbose&&console.log(`[FrontFriend] Added custom CSS: ${i.length} base rules, ${u.length} utility classes`)}catch(a){console.error("[FrontFriend] Failed to parse custom CSS:",a.message)}}else if(!o.custom){let t=require("fs"),i=require("path").join(process.cwd(),"node_modules",".cache","frontfriend","custom.js");t.existsSync(i)&&(console.warn("[FrontFriend] custom.js file exists but failed to load. This may be due to a parsing error or BOM issue."),console.warn("[FrontFriend] Try deleting node_modules/.cache/frontfriend and running `npx frontfriend init` again."))}e.verbose&&(console.log("[FrontFriend] Plugin loaded successfully"),console.log(`[FrontFriend] Colors: ${Object.keys(o.variables||{}).length}`),console.log(`[FrontFriend] Semantic vars: ${Object.keys(o.semanticVariables||{}).length}`),console.log(`[FrontFriend] Fonts: ${(o.fonts||[]).length}`),console.log(`[FrontFriend] Safelist classes: ${Array.isArray(o.safelist)?o.safelist.length:0}`))}},function(e={}){let n=null;if(y){let r=new y(process.cwd());n=r.exists()?r.load():null}let s=["./pages/**/*.{js,ts,jsx,tsx}","./components/**/*.{js,ts,jsx,tsx}","./app/**/*.{js,ts,jsx,tsx}","./src/**/*.{js,ts,jsx,tsx}","./stories/**/*.{js,ts,jsx,tsx}"];return e.verbose&&n&&(console.log("[FrontFriend] Cache loaded successfully"),n.safelist&&Array.isArray(n.safelist)&&console.log(`[FrontFriend] Loading ${n.safelist.length} classes for safelist`)),{theme:{extend:{colors:e.extendColors||{},animation:e.extendAnimations||{},spacing:{18:"4.5rem",88:"22rem",128:"32rem"},boxShadow:{"top-sm":"0 -1px 1px 0 rgba(0, 0, 0, 0.05)"},borderRadius:{"2xl":"1rem"},animationDelay:({theme:r})=>({...r("transitionDelay")}),animationDuration:({theme:r})=>({0:"0ms",...r("transitionDuration")}),animationTimingFunction:({theme:r})=>({...r("transitionTimingFunction")}),animationFillMode:{none:"none",forwards:"forwards",backwards:"backwards",both:"both"},animationDirection:{normal:"normal",reverse:"reverse",alternate:"alternate","alternate-reverse":"alternate-reverse"},animationOpacity:({theme:r})=>({DEFAULT:0,...r("opacity")}),animationTranslate:({theme:r})=>({DEFAULT:"100%",...r("translate")}),animationScale:({theme:r})=>({DEFAULT:0,...r("scale")}),animationRotate:({theme:r})=>({DEFAULT:"30deg",...r("rotate")}),animationRepeat:{0:"0",1:"1",infinite:"infinite"},keyframes:{enter:{from:{opacity:"var(--tw-enter-opacity, 1)",transform:"translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))"}},exit:{to:{opacity:"var(--tw-exit-opacity, 1)",transform:"translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))"}}}}},safelist:[...((n==null?void 0:n.safelist)||[]).filter(r=>typeof r!="string"||!r.startsWith("file:")),{pattern:/(text|fill)-icon-(neutral|positive|negative|warning|info|highlight|interactive|brand|inverse|onpositive|onnegative|onwarning|oninfo|onhighlight|oninteractive|onbrand)-(mid|strong|subtle|low)(-(neutral|hover|active|selected|disabled))?$/},{pattern:/^(layer-(below|surface|raised|popover|dialog|control)|overlay-(mid|strong|subtle|low))$/}],content:e.content||s}});module.exports=xe;Object.defineProperty(module.exports,"config",{get:function(){if(typeof __FF_CONFIG__<"u")return __FF_CONFIG__;if(typeof window<"u"&&window.__FF_CONFIG__)return window.__FF_CONFIG__;if(y)try{let e=new y(process.cwd());if(e.exists()){let n=e.load();if(n)return n.componentsConfig||null}}catch{}return null}});Object.defineProperty(module.exports,"iconSet",{get:function(){if(typeof __FF_ICONS__<"u")return __FF_ICONS__;if(typeof window<"u"&&window.__FF_ICONS__)return window.__FF_ICONS__;if(y)try{let e=new y(process.cwd());if(e.exists()){let n=e.load();if(n)return n.icons||null}}catch{}return null}});module.exports.componentsConfigSchema=we;module.exports.isCSSClassString=be;module.exports.ffdc=L();
4
4
  //# sourceMappingURL=index.js.map