@frontfriend/tailwind 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +35 -0
- package/README.md +231 -0
- package/dist/cli.js +20 -0
- package/dist/ffdc.js +2 -0
- package/dist/ffdc.js.map +7 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +7 -0
- package/dist/lib/config/cache-manager.js +180 -0
- package/dist/lib/config/config-loader.js +129 -0
- package/dist/lib/core/api-client.js +2 -0
- package/dist/lib/core/api-client.js.map +7 -0
- package/dist/lib/core/component-downloader.js +2 -0
- package/dist/lib/core/component-downloader.js.map +7 -0
- package/dist/lib/core/constants.js +2 -0
- package/dist/lib/core/constants.js.map +7 -0
- package/dist/lib/core/errors.js +2 -0
- package/dist/lib/core/errors.js.map +7 -0
- package/dist/lib/core/token-processor.js +2 -0
- package/dist/lib/core/token-processor.js.map +7 -0
- package/dist/lib/react/utils.mjs +2 -0
- package/dist/lib/react/utils.mjs.map +7 -0
- package/dist/lib/vue/utils.mjs +2 -0
- package/dist/lib/vue/utils.mjs.map +7 -0
- package/dist/next.js +2 -0
- package/dist/next.js.map +7 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +7 -0
- package/dist/types/index.d.ts +249 -0
- package/dist/vite.js +17 -0
- package/dist/vite.js.map +7 -0
- package/dist/vite.mjs +2 -0
- package/dist/vite.mjs.map +7 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
FrontFriend Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 FrontFriend
|
|
4
|
+
|
|
5
|
+
All Rights Reserved.
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") are the
|
|
8
|
+
proprietary and confidential property of FrontFriend.
|
|
9
|
+
|
|
10
|
+
LICENSE GRANT:
|
|
11
|
+
Subject to the terms and conditions of this license, FrontFriend grants you
|
|
12
|
+
a limited, non-exclusive, non-transferable, non-sublicensable license to use
|
|
13
|
+
the Software solely for your internal business purposes as a FrontFriend client.
|
|
14
|
+
|
|
15
|
+
RESTRICTIONS:
|
|
16
|
+
You may not:
|
|
17
|
+
- Distribute, sublicense, lease, rent, or lend the Software
|
|
18
|
+
- Modify, reverse engineer, decompile, or disassemble the Software
|
|
19
|
+
- Remove or alter any proprietary notices or labels on the Software
|
|
20
|
+
- Use the Software for any purpose other than as specifically authorized
|
|
21
|
+
|
|
22
|
+
TERMINATION:
|
|
23
|
+
This license is effective until terminated. Your rights under this license
|
|
24
|
+
will terminate automatically without notice if you fail to comply with any
|
|
25
|
+
term(s) of this license.
|
|
26
|
+
|
|
27
|
+
DISCLAIMER:
|
|
28
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
29
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
30
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
31
|
+
FRONTFRIEND BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
32
|
+
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
33
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
34
|
+
|
|
35
|
+
For licensing inquiries, please contact: license@frontfriend.com
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# @frontfriend/tailwind
|
|
2
|
+
|
|
3
|
+
Design token management for Tailwind CSS. Seamlessly integrate your FrontFriend design system with Tailwind.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Design Tokens**: Automatically sync colors, fonts, and animations from FrontFriend
|
|
8
|
+
- 🌓 **Dark Mode**: Built-in support for light and dark themes
|
|
9
|
+
- ⚡ **Performance**: 7-day cache with automatic refresh
|
|
10
|
+
- 🔧 **Framework Support**: Works with Next.js, Vite, React, Vue, and vanilla JS
|
|
11
|
+
- 📦 **Component Configs**: Access design system component configurations
|
|
12
|
+
- 🛠️ **TypeScript**: Full TypeScript support with type definitions
|
|
13
|
+
- 🏗️ **CLI Tools**: Manage tokens and download components
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @frontfriend/tailwind
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Create Configuration File
|
|
24
|
+
|
|
25
|
+
Create a `frontfriend.config.js` in your project root:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
module.exports = {
|
|
29
|
+
'ff-id': 'your-frontfriend-id'
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Initialize Design Tokens
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx frontfriend init
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This fetches your design tokens from FrontFriend and caches them locally.
|
|
40
|
+
|
|
41
|
+
### 3. Configure Tailwind
|
|
42
|
+
|
|
43
|
+
Add the plugin to your `tailwind.config.js`:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
module.exports = {
|
|
47
|
+
content: ['./src/**/*.{js,jsx,ts,tsx,vue}'],
|
|
48
|
+
plugins: [
|
|
49
|
+
require('@frontfriend/tailwind')()
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Framework Integration
|
|
55
|
+
|
|
56
|
+
### Vite Plugin
|
|
57
|
+
|
|
58
|
+
For Vite projects (React, Vue, etc.):
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
// vite.config.js
|
|
62
|
+
import { defineConfig } from 'vite';
|
|
63
|
+
import frontfriend from '@frontfriend/tailwind/vite';
|
|
64
|
+
|
|
65
|
+
export default defineConfig({
|
|
66
|
+
plugins: [
|
|
67
|
+
frontfriend(),
|
|
68
|
+
// ... other plugins
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Next.js Plugin
|
|
74
|
+
|
|
75
|
+
For Next.js projects:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
// next.config.js
|
|
79
|
+
const withFrontFriend = require('@frontfriend/tailwind/next');
|
|
80
|
+
|
|
81
|
+
module.exports = withFrontFriend({
|
|
82
|
+
// Your Next.js config
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Usage
|
|
87
|
+
|
|
88
|
+
### Design Tokens
|
|
89
|
+
|
|
90
|
+
Once configured, use your design tokens as Tailwind utilities:
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<!-- Semantic tokens -->
|
|
94
|
+
<div class="bg-brand-mid text-brand-strong">
|
|
95
|
+
Semantic colors
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<!-- Animations -->
|
|
99
|
+
<div class="animate-fadeIn">
|
|
100
|
+
Animated content
|
|
101
|
+
</div>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## CLI Commands
|
|
105
|
+
|
|
106
|
+
### Initialize/Update Tokens
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx frontfriend init [options]
|
|
110
|
+
|
|
111
|
+
Options:
|
|
112
|
+
--force Force refresh even if cache is valid
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Check Status
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx frontfriend status
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Shows current configuration and cache status.
|
|
122
|
+
|
|
123
|
+
### Download Components
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx frontfriend download <components...> [options]
|
|
127
|
+
|
|
128
|
+
Options:
|
|
129
|
+
-f, --framework <framework> Framework to download for (react/vue)
|
|
130
|
+
-o, --output <path> Output directory for components
|
|
131
|
+
--overwrite Overwrite existing files
|
|
132
|
+
|
|
133
|
+
Examples:
|
|
134
|
+
npx frontfriend download button card # Download specific components
|
|
135
|
+
npx frontfriend download all -f react # Download all React components
|
|
136
|
+
npx frontfriend download all -f vue -o ./src # Download all Vue components to src/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Clean Cache
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx frontfriend clean
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Removes cached design tokens.
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
### Plugin Options
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
require('@frontfriend/tailwind')({
|
|
153
|
+
// Enable verbose logging
|
|
154
|
+
verbose: true,
|
|
155
|
+
|
|
156
|
+
// Extend Tailwind colors (merged with FrontFriend colors)
|
|
157
|
+
extendColors: {
|
|
158
|
+
custom: '#FF0000'
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
// Extend animations
|
|
162
|
+
extendAnimations: {
|
|
163
|
+
spin: 'spin 1s linear infinite'
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
// Content paths for PurgeCSS
|
|
167
|
+
content: ['./src/**/*.{js,jsx,ts,tsx,vue}']
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Configuration File
|
|
172
|
+
|
|
173
|
+
The `frontfriend.config.js` file supports both CommonJS and ES modules:
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
// CommonJS
|
|
177
|
+
module.exports = {
|
|
178
|
+
'ff-id': 'your-frontfriend-id'
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// ES Module
|
|
182
|
+
export default {
|
|
183
|
+
'ff-id': 'your-frontfriend-id'
|
|
184
|
+
};
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## TypeScript
|
|
188
|
+
|
|
189
|
+
Full TypeScript support is included:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import plugin from '@frontfriend/tailwind';
|
|
193
|
+
import { cn } from '@frontfriend/tailwind/lib/react/utils';
|
|
194
|
+
import type { PluginOptions } from '@frontfriend/tailwind';
|
|
195
|
+
|
|
196
|
+
const options: PluginOptions = {
|
|
197
|
+
verbose: true
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
### Cache not found
|
|
204
|
+
```bash
|
|
205
|
+
npx frontfriend init
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Cache expired
|
|
209
|
+
```bash
|
|
210
|
+
npx frontfriend init --force
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### ff-id not found
|
|
214
|
+
Ensure your `frontfriend.config.js` includes:
|
|
215
|
+
```js
|
|
216
|
+
module.exports = {
|
|
217
|
+
'ff-id': 'your-frontfriend-id'
|
|
218
|
+
};
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Components not downloading
|
|
222
|
+
1. Check your ff-id is correct
|
|
223
|
+
2. Ensure you have access to the components
|
|
224
|
+
3. Try specifying framework: `npx frontfriend download button -f react`
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
This is proprietary software. Usage is restricted to licensed FrontFriend clients only.
|
|
229
|
+
See LICENSE file for details.
|
|
230
|
+
|
|
231
|
+
© 2024 FrontFriend. All rights reserved.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var{Command:y}=require("commander"),p=require("./lib/config/config-loader"),m=require("./lib/config/cache-manager"),{APIClient:v}=require("./lib/core/api-client"),{ComponentDownloader:x}=require("./lib/core/component-downloader"),D=require("./lib/core/token-processor"),{ConfigError:g,APIError:I,CacheError:u}=require("./lib/core/errors"),S=require("path"),i=new y;i.name("frontfriend").description("FrontFriend Tailwind CLI - Manage design tokens and cache").version("2.0.0");i.command("init").description("Initialize FrontFriend configuration and fetch from API").option("--force","Force refresh even if cache is valid").action(async o=>{var a,s;try{console.log("\u{1F527} FrontFriend Setup"),console.log(`==================
|
|
3
|
+
`);let n=await new p().load();if(!n.ffId)throw new g(`ff-id not found in frontfriend.config.js
|
|
4
|
+
Please add "ff-id" to your frontfriend.config.js file`,"ff-id");console.log("\u{1F4CB} Configuration loaded"),console.log(` FF_ID: ${n.ffId}`),console.log(` App Root: ${n.appRoot}
|
|
5
|
+
`);let l=new m(n.appRoot);!o.force&&l.exists()&&l.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..."),o.force?console.log(` Force refresh requested
|
|
6
|
+
`):l.exists()?console.log(` Cache expired
|
|
7
|
+
`):console.log(` No cache found
|
|
8
|
+
`),console.log("\u{1F310} Fetching configuration...");let c=new v(n.ffId),[t,f,w,C,d,k]=await Promise.all([c.fetchTokens(),c.fetchComponentsConfig(),c.fetchFonts(),c.fetchIcons(),c.fetchVersion(),c.fetchCustomCss()]);console.log(" \u2713 Tokens fetched"),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
|
|
9
|
+
`),console.log("\u2699\uFE0F Processing tokens...");let h=new D,r=await h.process({colors:((a=t.colors)==null?void 0:a.colors)||((s=t.global)==null?void 0:s.colors)||t.colors||t.global,semantic:t.semantic,semanticDark:t.semanticDark,fonts:w,globalTokens:t.global,animations:t.animations,version:d==null?void 0:d.version,ffId:n.ffId,customCss:k});console.log(" \u2713 Colors processed"),console.log(" \u2713 Semantic tokens processed"),r.fontFaces.length>0&&console.log(` \u2713 ${r.fontFaces.length} font faces processed`),Object.keys(r.animations).length>0&&console.log(` \u2713 ${Object.keys(r.animations).length} animations processed`),console.log(`
|
|
10
|
+
`);let F=h.extractClassesFromComponentsConfig(f),$={tokens:r.utilities,variables:r.variables,semanticVariables:r.semanticVariables,semanticDarkVariables:r.semanticDarkVariables,fonts:r.fontFaces,icons:C,componentsConfig:f,keyframes:r.keyframes,animations:r.animations,safelist:r.safelist,version:d,metadata:r.metadata,cls:F||[],custom:r.custom};console.log("\u{1F4BE} Saving cache..."),l.save($),console.log(` \u2713 Cache saved successfully
|
|
11
|
+
`),console.log("\u2705 Setup complete!"),console.log(" Your FrontFriend configuration has been cached."),console.log(" The Tailwind plugin will now use this cached data."),process.exit(0)}catch(e){e instanceof g?console.error("\u274C Configuration Error:",e.message):e instanceof I?(console.error("\u274C API Error:",e.message),console.error(` Status: ${e.statusCode}`),console.error(` URL: ${e.url}`)):e instanceof u?(console.error("\u274C Cache Error:",e.message),console.error(` Operation: ${e.operation}`)):console.error("\u274C Setup failed:",e.message),process.exit(1)}});i.command("clean").description("Remove cached configuration").action(async()=>{try{console.log(`\u{1F9F9} Cleaning FrontFriend cache...
|
|
12
|
+
`);let a=new p().load(),s=new m(a.appRoot);s.exists()?(s.clear(),console.log("\u2705 Cache cleared successfully")):console.log("\u2139\uFE0F No cache found"),process.exit(0)}catch(o){o instanceof u?(console.error("\u274C Cache Error:",o.message),console.error(` Operation: ${o.operation}`)):console.error("\u274C Clean failed:",o.message),process.exit(1)}});i.command("status").description("Show cache status and configuration").action(async()=>{try{console.log("\u{1F4CA} FrontFriend Status"),console.log(`===================
|
|
13
|
+
`);let a=await new p().load();console.log("Configuration:"),console.log(` FF_ID: ${a.ffId||"Not set"}`),console.log(` App Root: ${a.appRoot}
|
|
14
|
+
`);let s=new m(a.appRoot),e=s.getCacheDir();if(console.log("Cache:"),console.log(` Directory: ${S.relative(process.cwd(),e)}`),s.exists()){console.log(` Status: ${s.isValid()?"\u2705 Valid":"\u26A0\uFE0F Expired"}`);let n=s.load();if(n&&n.metadata){let l=new Date(n.metadata.timestamp);console.log(` Created: ${l.toLocaleString()}`),console.log(` Version: ${n.metadata.version||"Unknown"}`)}}else console.log(" Status: \u274C Not found");process.exit(0)}catch(o){o instanceof g?console.error("\u274C Configuration Error:",o.message):o instanceof u?(console.error("\u274C Cache Error:",o.message),console.error(` Operation: ${o.operation}`)):console.error("\u274C Status check failed:",o.message),process.exit(1)}});i.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(o,a)=>{try{console.log(`\u{1F4E6} Downloading components...
|
|
15
|
+
`);let e=await new p().load();if(!e.ffId)throw new g(`ff-id not found in frontfriend.config.js
|
|
16
|
+
Please add "ff-id" to your frontfriend.config.js file`,"ff-id");let n=new x({appRoot:e.appRoot,config:e,framework:a.framework,outputPath:a.output,overwrite:a.overwrite}),l=o;if(o.length===1&&o[0].toLowerCase()==="all"){let t=await n.getAllComponents(),f=await n.getCustomComponents();t.length===0&&(console.error("\u274C Failed to fetch component list"),process.exit(1)),l=[...t,...f],console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${n.framework}`),console.log(` Output: ${n.outputPath}`),console.log(` Components: All ${t.length} standard components`),f.length>0&&console.log(` Custom: ${f.length} custom components for ff-id: ${e.ffId||e["ff-id"]}`),console.log("")}else console.log("\u{1F4CB} Configuration"),console.log(` Framework: ${n.framework}`),console.log(` Output: ${n.outputPath}`),console.log(` Components: ${o.join(", ")}
|
|
17
|
+
`);let c=await n.downloadComponents(l);c.successful.length>0&&(console.log(`
|
|
18
|
+
\u2705 Download complete!`),console.log(` Downloaded: ${c.successful.length} components`)),c.failed.length>0&&(console.log(""),c.failed.forEach(t=>{t.error.includes("not found")?console.log(`\u274C ${t.error}`):console.log(`\u274C Failed to download ${t.component}: ${t.error}`)})),c.successful.length>0&&c.dependencies.length>0&&(console.log(`
|
|
19
|
+
\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(s){s instanceof g?(console.error("\u274C Configuration Error:",s.message),s.missingKey&&console.error(` Missing key: ${s.missingKey}`)):console.error("\u274C Download failed:",s.message),process.exit(1)}});i.parse(process.argv);process.argv.slice(2).length||(i.outputHelp(),process.exit(0));
|
|
20
|
+
//# sourceMappingURL=cli-temp.js.map
|
package/dist/ffdc.js
ADDED
package/dist/ffdc.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
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 throw new Error('Config is required');\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,MAAM,IAAI,MAAM,oBAAoB,EAGtC,GAAI,OAAOA,GAAW,SACpB,MAAM,IAAI,MAAM,0BAA0B,EAG5C,OAAOA,CACT",
|
|
6
|
+
"names": ["config"]
|
|
7
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var k=(s,o)=>()=>(o||s((o={exports:{}}).exports,o),o.exports);var g=k(($,x)=>{x.exports=function(o){if(!o)throw new Error("Config is required");if(typeof o!="object")throw new Error("Config must be an object");return o}});var _=require("tailwindcss/plugin"),d=require("./lib/config/cache-manager");function v(s){return Object.fromEntries(Object.entries(s).filter(([o])=>o!=="DEFAULT"))}var j=_.withOptions(function(s={}){return function({addBase:o,addUtilities:i,theme:l,matchUtilities:a}){let w=new d(process.cwd());if(!w.exists()){console.warn('[FrontFriend] No cache found. Please run "npx frontfriend setup" first.');return}w.isValid()||console.warn('[FrontFriend] Cache is expired. Please run "npx frontfriend setup" to refresh.');let e=w.load();if(!e){console.error("[FrontFriend] Failed to load cache.");return}let m={};if(e.variables)for(let[t,n]of Object.entries(e.variables))t.startsWith("--color-")&&!n.startsWith("hsl(")?m[t]=`hsl(${n})`:m[t]=n;if(e.semanticVariables)for(let[t,n]of Object.entries(e.semanticVariables))m[t]=n;if(o({":root":m}),e.semanticDarkVariables&&Object.keys(e.semanticDarkVariables).length>0&&(o({":root:not(.light)":e.semanticDarkVariables}),o({":root:not(.dark)":e.semanticVariables})),e.semanticVariables){let t={};for(let[n]of Object.entries(e.semanticVariables)){let r=n.match(/^--(bg|text|border|layer|overlay|icon)-(.+)$/);if(r){let[,c,f]=r,u=`.${c}-${f}`;c==="bg"||c==="layer"||c==="overlay"?t[u]={backgroundColor:`var(${n})`}:c==="text"?t[u]={color:`var(${n})`}:c==="border"?t[u]={borderColor:`var(${n})`}:c==="icon"&&(t[`.text-${c}-${f}`]={color:`var(${n})`},t[`.fill-${c}-${f}`]={fill:`var(${n})`})}}i(t)}if(e.tokens){if(e.tokens.backgroundColor){let t={};for(let[n,r]of Object.entries(e.tokens.backgroundColor))t[`.bg-${n}`]={backgroundColor:r};i(t)}if(e.tokens.textColor){let t={};for(let[n,r]of Object.entries(e.tokens.textColor))t[`.text-${n}`]={color:r};i(t)}if(e.tokens.borderColor){let t={};for(let[n,r]of Object.entries(e.tokens.borderColor))t[`.border-${n}`]={borderColor:r};i(t)}if(e.tokens.fill){let t={};for(let[n,r]of Object.entries(e.tokens.fill))t[`.fill-${n}`]={fill:r};i(t)}if(e.tokens.fontFamily){let t={};for(let[n,r]of Object.entries(e.tokens.fontFamily))t[`.font-${n}`]={fontFamily:r};i(t)}}if(e.fonts&&e.fonts.length>0&&e.fonts.forEach(t=>{o({"@font-face":t})}),e.keyframes&&Object.keys(e.keyframes).length>0){let t={};for(let[n,r]of Object.entries(e.keyframes))t[`@keyframes ${n}`]=r;o(t)}if(e.animations&&Object.keys(e.animations).length>0){let t={};for(let[n,r]of Object.entries(e.animations))t[`.animate-${n}`]={animation:r};i(t)}if(i({"@keyframes enter":l("keyframes.enter"),"@keyframes exit":l("keyframes.exit"),".animate-in":{animationName:"enter",animationDuration:l("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:l("animationDuration.DEFAULT"),"--tw-exit-opacity":"initial","--tw-exit-scale":"initial","--tw-exit-rotate":"initial","--tw-exit-translate-x":"initial","--tw-exit-translate-y":"initial"}}),a({"fade-in":t=>({"--tw-enter-opacity":t}),"fade-out":t=>({"--tw-exit-opacity":t})},{values:l("animationOpacity")}),a({"zoom-in":t=>({"--tw-enter-scale":t}),"zoom-out":t=>({"--tw-exit-scale":t})},{values:l("animationScale")}),a({"spin-in":t=>({"--tw-enter-rotate":t}),"spin-out":t=>({"--tw-exit-rotate":t})},{values:l("animationRotate")}),a({"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:l("animationTranslate")}),a({duration:t=>({animationDuration:t})},{values:v(l("animationDuration"))}),a({delay:t=>({animationDelay:t})},{values:l("animationDelay")}),a({ease:t=>({animationTimingFunction:t})},{values:v(l("animationTimingFunction"))}),i({".running":{animationPlayState:"running"},".paused":{animationPlayState:"paused"}}),a({"fill-mode":t=>({animationFillMode:t})},{values:l("animationFillMode")}),a({direction:t=>({animationDirection:t})},{values:l("animationDirection")}),a({repeat:t=>({animationIterationCount:t})},{values:l("animationRepeat")}),e.custom)if(e.custom.raw&&typeof e.custom.raw=="string"){let t=e.custom.raw.replace(/theme\(['"](.*?)['"]\)/g,(n,r)=>{let c=r.split("."),f=l(c[0]);for(let u=1;u<c.length;u++)if(f&&f[c[u]])f=f[c[u]];else{f=null;break}return f||n});o({...t.split("}").filter(n=>n.trim().length>0).map(n=>{let r=n.split("{");if(r.length===2){let c=r[0].trim(),f=r[1].trim(),u={};return f.split(";").filter(y=>y.trim().length>0).forEach(y=>{let[b,p]=y.split(":").map(F=>F.trim());b&&p&&(u[b]=p)}),{[c]:u}}return{}}).reduce((n,r)=>({...n,...r}),{})})}else typeof e.custom=="object"&&o(e.custom);s.verbose&&(console.log("[FrontFriend] Plugin loaded successfully"),console.log(`[FrontFriend] Colors: ${Object.keys(e.variables||{}).length}`),console.log(`[FrontFriend] Semantic vars: ${Object.keys(e.semanticVariables||{}).length}`),console.log(`[FrontFriend] Fonts: ${(e.fonts||[]).length}`),console.log(`[FrontFriend] Animations: ${Object.keys(e.animations||{}).length}`),console.log(`[FrontFriend] Additional classes: ${Array.isArray(e.cls)?e.cls.length:0}`))}},function(s={}){let o=new d(process.cwd()),i=o.exists()?o.load():null,l=["./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 s.verbose&&i&&(console.log("[FrontFriend] Cache loaded successfully"),i.cls&&Array.isArray(i.cls)&&console.log(`[FrontFriend] Loading ${i.cls.length} additional classes for safelist`)),{theme:{extend:{colors:s.extendColors||{},animation:s.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:a})=>({...a("transitionDelay")}),animationDuration:({theme:a})=>({0:"0ms",...a("transitionDuration")}),animationTimingFunction:({theme:a})=>({...a("transitionTimingFunction")}),animationFillMode:{none:"none",forwards:"forwards",backwards:"backwards",both:"both"},animationDirection:{normal:"normal",reverse:"reverse",alternate:"alternate","alternate-reverse":"alternate-reverse"},animationOpacity:({theme:a})=>({DEFAULT:0,...a("opacity")}),animationTranslate:({theme:a})=>({DEFAULT:"100%",...a("translate")}),animationScale:({theme:a})=>({DEFAULT:0,...a("scale")}),animationRotate:({theme:a})=>({DEFAULT:"30deg",...a("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:[...(i==null?void 0:i.safelist)||[],{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))$/},...(i==null?void 0:i.cls)||[]],content:s.content||l}});module.exports=j;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__;try{let s=new d(process.cwd());if(s.exists()){let o=s.load();if(o)return o.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__;try{let s=new d(process.cwd());if(s.exists()){let o=s.load();if(o)return o.icons||null}}catch{}return null}});module.exports.ffdc=g();
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../ffdc.js", "../index.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 throw new Error('Config is required');\n }\n \n if (typeof config !== 'object') {\n throw new Error('Config must be an object');\n }\n \n return config;\n};", "const plugin = require('tailwindcss/plugin');\nconst CacheManager = require('./lib/config/cache-manager');\n\nfunction filterDefault(values) {\n return Object.fromEntries(\n Object.entries(values).filter(([key]) => key !== \"DEFAULT\"),\n );\n}\n\nconst pluginExport = plugin.withOptions(\n function(options = {}) {\n return function({ addBase, addUtilities, theme, matchUtilities }) {\n // 1. Load cache with CacheManager\n const cacheManager = new CacheManager(process.cwd());\n \n if (!cacheManager.exists()) {\n console.warn('[FrontFriend] No cache found. Please run \"npx frontfriend setup\" first.');\n return;\n }\n\n if (!cacheManager.isValid()) {\n console.warn('[FrontFriend] Cache is expired. Please run \"npx frontfriend setup\" to refresh.');\n }\n\n const cache = cacheManager.load();\n if (!cache) {\n console.error('[FrontFriend] Failed to load cache.');\n return;\n }\n\n // 2. Add CSS variables to :root\n const rootVars = {};\n \n // Add color variables\n if (cache.variables) {\n // Wrap HSL values in hsl() function\n for (const [key, value] of Object.entries(cache.variables)) {\n // Check if it's a color variable (contains HSL values)\n if (key.startsWith('--color-') && !value.startsWith('hsl(')) {\n rootVars[key] = `hsl(${value})`;\n } else {\n rootVars[key] = value;\n }\n }\n }\n \n // Add semantic variables (light mode)\n if (cache.semanticVariables) {\n for (const [key, value] of Object.entries(cache.semanticVariables)) {\n // Semantic variables point to color variables using var()\n // so we don't need to wrap them in hsl()\n rootVars[key] = value;\n }\n }\n \n // Add root styles\n addBase({\n ':root': rootVars\n });\n\n // 3. Add dark mode support\n if (cache.semanticDarkVariables && Object.keys(cache.semanticDarkVariables).length > 0) {\n addBase({\n ':root:not(.light)': cache.semanticDarkVariables\n });\n addBase({\n ':root:not(.dark)': cache.semanticVariables\n });\n }\n\n\n // 4. Generate semantic color utilities from semantic variables\n if (cache.semanticVariables) {\n const semanticUtilities = {};\n \n // Process semantic variables into utility classes\n for (const [cssVar] of Object.entries(cache.semanticVariables)) {\n // Convert CSS variable to utility class name\n // --bg-brand-mid-default -> bg-brand-mid\n // --text-brand-strong -> text-brand-strong\n // --border-neutral-subtle-hover -> border-neutral-subtle-hover\n \n const match = cssVar.match(/^--(bg|text|border|layer|overlay|icon)-(.+)$/);\n if (match) {\n const [, prefix, name] = match;\n const className = `.${prefix}-${name}`;\n \n if (prefix === 'bg' || prefix === 'layer' || prefix === 'overlay') {\n semanticUtilities[className] = {\n backgroundColor: `var(${cssVar})`\n };\n } else if (prefix === 'text') {\n semanticUtilities[className] = {\n color: `var(${cssVar})`\n };\n } else if (prefix === 'border') {\n semanticUtilities[className] = {\n borderColor: `var(${cssVar})`\n };\n } else if (prefix === 'icon') {\n // Icon tokens map to both text color and fill\n semanticUtilities[`.text-${prefix}-${name}`] = {\n color: `var(${cssVar})`\n };\n semanticUtilities[`.fill-${prefix}-${name}`] = {\n fill: `var(${cssVar})`\n };\n }\n }\n }\n \n addUtilities(semanticUtilities);\n }\n\n // 5. Generate utilities from tokens (semantic-based utilities)\n if (cache.tokens) {\n // Background colors\n if (cache.tokens.backgroundColor) {\n const bgUtilities = {};\n for (const [name, value] of Object.entries(cache.tokens.backgroundColor)) {\n // The value already contains hsl() wrapper from the processor\n bgUtilities[`.bg-${name}`] = {\n backgroundColor: value\n };\n }\n addUtilities(bgUtilities);\n }\n\n // Text colors\n if (cache.tokens.textColor) {\n const textUtilities = {};\n for (const [name, value] of Object.entries(cache.tokens.textColor)) {\n textUtilities[`.text-${name}`] = {\n color: value\n };\n }\n addUtilities(textUtilities);\n }\n\n // Border colors\n if (cache.tokens.borderColor) {\n const borderUtilities = {};\n for (const [name, value] of Object.entries(cache.tokens.borderColor)) {\n borderUtilities[`.border-${name}`] = {\n borderColor: value\n };\n }\n addUtilities(borderUtilities);\n }\n\n // Fill colors (for SVG icons)\n if (cache.tokens.fill) {\n const fillUtilities = {};\n for (const [name, value] of Object.entries(cache.tokens.fill)) {\n fillUtilities[`.fill-${name}`] = {\n fill: value\n };\n }\n addUtilities(fillUtilities);\n }\n\n // Font family utilities\n if (cache.tokens.fontFamily) {\n const fontUtilities = {};\n for (const [name, value] of Object.entries(cache.tokens.fontFamily)) {\n fontUtilities[`.font-${name}`] = {\n fontFamily: value\n };\n }\n addUtilities(fontUtilities);\n }\n }\n\n // 6. Add font faces\n if (cache.fonts && cache.fonts.length > 0) {\n // Convert font objects to Tailwind-compatible format\n cache.fonts.forEach(fontFace => {\n // Tailwind expects each @font-face as a separate rule\n addBase({\n '@font-face': fontFace\n });\n });\n }\n\n // 7. Add keyframes\n if (cache.keyframes && Object.keys(cache.keyframes).length > 0) {\n const keyframeRules = {};\n for (const [name, frames] of Object.entries(cache.keyframes)) {\n keyframeRules[`@keyframes ${name}`] = frames;\n }\n addBase(keyframeRules);\n }\n\n // 8. Add animation utilities\n if (cache.animations && Object.keys(cache.animations).length > 0) {\n const animationUtilities = {};\n for (const [name, value] of Object.entries(cache.animations)) {\n animationUtilities[`.animate-${name}`] = {\n animation: value\n };\n }\n addUtilities(animationUtilities);\n }\n\n // 9. Add enter/exit animation utilities\n addUtilities({\n \"@keyframes enter\": theme(\"keyframes.enter\"),\n \"@keyframes exit\": theme(\"keyframes.exit\"),\n \".animate-in\": {\n animationName: \"enter\",\n animationDuration: theme(\"animationDuration.DEFAULT\"),\n \"--tw-enter-opacity\": \"initial\",\n \"--tw-enter-scale\": \"initial\",\n \"--tw-enter-rotate\": \"initial\",\n \"--tw-enter-translate-x\": \"initial\",\n \"--tw-enter-translate-y\": \"initial\",\n },\n \".animate-out\": {\n animationName: \"exit\",\n animationDuration: theme(\"animationDuration.DEFAULT\"),\n \"--tw-exit-opacity\": \"initial\",\n \"--tw-exit-scale\": \"initial\",\n \"--tw-exit-rotate\": \"initial\",\n \"--tw-exit-translate-x\": \"initial\",\n \"--tw-exit-translate-y\": \"initial\",\n },\n });\n\n // 10. Add animation match utilities\n matchUtilities(\n {\n \"fade-in\": (value) => ({ \"--tw-enter-opacity\": value }),\n \"fade-out\": (value) => ({ \"--tw-exit-opacity\": value }),\n },\n { values: theme(\"animationOpacity\") }\n );\n\n matchUtilities(\n {\n \"zoom-in\": (value) => ({ \"--tw-enter-scale\": value }),\n \"zoom-out\": (value) => ({ \"--tw-exit-scale\": value }),\n },\n { values: theme(\"animationScale\") }\n );\n\n matchUtilities(\n {\n \"spin-in\": (value) => ({ \"--tw-enter-rotate\": value }),\n \"spin-out\": (value) => ({ \"--tw-exit-rotate\": value }),\n },\n { values: theme(\"animationRotate\") }\n );\n\n matchUtilities(\n {\n \"slide-in-from-top\": (value) => ({\n \"--tw-enter-translate-y\": `-${value}`,\n }),\n \"slide-in-from-bottom\": (value) => ({\n \"--tw-enter-translate-y\": value,\n }),\n \"slide-in-from-left\": (value) => ({\n \"--tw-enter-translate-x\": `-${value}`,\n }),\n \"slide-in-from-right\": (value) => ({\n \"--tw-enter-translate-x\": value,\n }),\n \"slide-out-to-top\": (value) => ({\n \"--tw-exit-translate-y\": `-${value}`,\n }),\n \"slide-out-to-bottom\": (value) => ({\n \"--tw-exit-translate-y\": value,\n }),\n \"slide-out-to-left\": (value) => ({\n \"--tw-exit-translate-x\": `-${value}`,\n }),\n \"slide-out-to-right\": (value) => ({\n \"--tw-exit-translate-x\": value,\n }),\n },\n { values: theme(\"animationTranslate\") }\n );\n\n // 11. Add animation control utilities\n matchUtilities(\n { duration: (value) => ({ animationDuration: value }) },\n { values: filterDefault(theme(\"animationDuration\")) }\n );\n\n matchUtilities(\n { delay: (value) => ({ animationDelay: value }) },\n { values: theme(\"animationDelay\") }\n );\n\n matchUtilities(\n { ease: (value) => ({ animationTimingFunction: value }) },\n { values: filterDefault(theme(\"animationTimingFunction\")) }\n );\n\n addUtilities({\n \".running\": { animationPlayState: \"running\" },\n \".paused\": { animationPlayState: \"paused\" },\n });\n\n matchUtilities(\n { \"fill-mode\": (value) => ({ animationFillMode: value }) },\n { values: theme(\"animationFillMode\") }\n );\n\n matchUtilities(\n { direction: (value) => ({ animationDirection: value }) },\n { values: theme(\"animationDirection\") }\n );\n\n matchUtilities(\n { repeat: (value) => ({ animationIterationCount: value }) },\n { values: theme(\"animationRepeat\") }\n );\n\n // 12. Add custom CSS\n if (cache.custom) {\n if (cache.custom.raw && typeof cache.custom.raw === 'string') {\n // Process the raw CSS string\n const processedCss = cache.custom.raw.replace(\n /theme\\(['\"](.*?)['\"]\\)/g, \n (match, themePath) => {\n // Split the theme path (e.g., 'colors.orange.300' -> ['colors', 'orange', '300'])\n const parts = themePath.split('.');\n \n // Get the value from theme\n let value = theme(parts[0]);\n for (let i = 1; i < parts.length; i++) {\n if (value && value[parts[i]]) {\n value = value[parts[i]];\n } else {\n value = null;\n break;\n }\n }\n \n return value || match; // Return the theme value or original if not found\n }\n );\n \n // Add the processed CSS\n addBase({\n // Using a style object with selectors\n ...processedCss.split('}')\n .filter(rule => rule.trim().length > 0)\n .map(rule => {\n const parts = rule.split('{');\n if (parts.length === 2) {\n const selector = parts[0].trim();\n const styles = parts[1].trim();\n \n // Convert CSS properties to object\n const styleObj = {};\n styles.split(';')\n .filter(prop => prop.trim().length > 0)\n .forEach(prop => {\n const [key, value] = prop.split(':').map(p => p.trim());\n if (key && value) {\n styleObj[key] = value;\n }\n });\n \n return { [selector]: styleObj };\n }\n return {};\n })\n .reduce((acc, item) => ({ ...acc, ...item }), {})\n });\n } else if (typeof cache.custom === 'object') {\n // Handle object format\n addBase(cache.custom);\n }\n }\n\n // Log success\n if (options.verbose) {\n console.log('[FrontFriend] Plugin loaded successfully');\n console.log(`[FrontFriend] Colors: ${Object.keys(cache.variables || {}).length}`);\n console.log(`[FrontFriend] Semantic vars: ${Object.keys(cache.semanticVariables || {}).length}`);\n console.log(`[FrontFriend] Fonts: ${(cache.fonts || []).length}`);\n console.log(`[FrontFriend] Animations: ${Object.keys(cache.animations || {}).length}`);\n console.log(`[FrontFriend] Additional classes: ${Array.isArray(cache.cls) ? cache.cls.length : 0}`);\n }\n };\n },\n function(options = {}) {\n // Return theme configuration\n const cacheManager = new CacheManager(process.cwd());\n const cache = cacheManager.exists() ? cacheManager.load() : null;\n \n // Default content paths matching the current-plugin approach\n const defaultContent = [\n './pages/**/*.{js,ts,jsx,tsx}',\n './components/**/*.{js,ts,jsx,tsx}',\n './app/**/*.{js,ts,jsx,tsx}',\n './src/**/*.{js,ts,jsx,tsx}',\n './stories/**/*.{js,ts,jsx,tsx}'\n ];\n \n // Log cache loading\n if (options.verbose && cache) {\n console.log('[FrontFriend] Cache loaded successfully');\n if (cache.cls && Array.isArray(cache.cls)) {\n console.log(`[FrontFriend] Loading ${cache.cls.length} additional classes for safelist`);\n }\n }\n\n return {\n theme: {\n extend: {\n // Extend colors if needed\n colors: options.extendColors || {},\n // Extend animations if needed\n animation: options.extendAnimations || {},\n // Add custom spacing values\n spacing: {\n '18': '4.5rem',\n '88': '22rem',\n '128': '32rem'\n },\n // Add custom box shadows\n boxShadow: {\n 'top-sm': '0 -1px 1px 0 rgba(0, 0, 0, 0.05)'\n },\n // Add border radius values\n borderRadius: {\n '2xl': '1rem'\n },\n // Animation extensions\n animationDelay: ({ theme }) => ({\n ...theme(\"transitionDelay\"),\n }),\n animationDuration: ({ theme }) => ({\n 0: \"0ms\",\n ...theme(\"transitionDuration\"),\n }),\n animationTimingFunction: ({ theme }) => ({\n ...theme(\"transitionTimingFunction\"),\n }),\n animationFillMode: {\n none: \"none\",\n forwards: \"forwards\",\n backwards: \"backwards\",\n both: \"both\",\n },\n animationDirection: {\n normal: \"normal\",\n reverse: \"reverse\",\n alternate: \"alternate\",\n \"alternate-reverse\": \"alternate-reverse\",\n },\n animationOpacity: ({ theme }) => ({\n DEFAULT: 0,\n ...theme(\"opacity\"),\n }),\n animationTranslate: ({ theme }) => ({\n DEFAULT: \"100%\",\n ...theme(\"translate\"),\n }),\n animationScale: ({ theme }) => ({\n DEFAULT: 0,\n ...theme(\"scale\"),\n }),\n animationRotate: ({ theme }) => ({\n DEFAULT: \"30deg\",\n ...theme(\"rotate\"),\n }),\n animationRepeat: {\n 0: \"0\",\n 1: \"1\",\n infinite: \"infinite\",\n },\n keyframes: {\n enter: {\n from: {\n opacity: \"var(--tw-enter-opacity, 1)\",\n transform:\n \"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))\",\n },\n },\n exit: {\n to: {\n opacity: \"var(--tw-exit-opacity, 1)\",\n transform:\n \"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))\",\n },\n },\n },\n }\n },\n // Include safelist from cache and additional classes\n safelist: [\n ...(cache?.safelist || []),\n {\n 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))?$/,\n },\n {\n pattern: /^(layer-(below|surface|raised|popover|dialog|control)|overlay-(mid|strong|subtle|low))$/,\n },\n ...(cache?.cls || []),\n ],\n // Set content paths - merge options with defaults\n content: options.content || defaultContent\n };\n }\n);\n\n// Default export is the plugin\nmodule.exports = pluginExport;\n\n// Export components config and icons with getter functions\n// This allows dynamic resolution at runtime\n\n// Create getter for config\nObject.defineProperty(module.exports, 'config', {\n get: function() {\n // Check for webpack-injected global variable\n if (typeof __FF_CONFIG__ !== 'undefined') {\n return __FF_CONFIG__;\n }\n \n // Check if we're in a browser environment\n if (typeof window !== 'undefined' && window.__FF_CONFIG__) {\n return window.__FF_CONFIG__;\n }\n \n // Node.js: load from cache\n try {\n const cacheManager = new CacheManager(process.cwd());\n if (cacheManager.exists()) {\n const cache = cacheManager.load();\n if (cache) {\n return cache.componentsConfig || null;\n }\n }\n } catch (error) {\n // Config not available\n }\n \n return null;\n }\n});\n\n// Create getter for iconSet\nObject.defineProperty(module.exports, 'iconSet', {\n get: function() {\n // Check for webpack-injected global variable\n if (typeof __FF_ICONS__ !== 'undefined') {\n return __FF_ICONS__;\n }\n \n // Check if we're in a browser environment\n if (typeof window !== 'undefined' && window.__FF_ICONS__) {\n return window.__FF_ICONS__;\n }\n \n // Node.js: load from cache\n try {\n const cacheManager = new CacheManager(process.cwd());\n if (cacheManager.exists()) {\n const cache = cacheManager.load();\n if (cache) {\n return cache.icons || null;\n }\n }\n } catch (error) {\n // Icons not available\n }\n \n return null;\n }\n});\n\n// Export ffdc utility\nmodule.exports.ffdc = require('./ffdc.js');"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["require_ffdc", "__commonJSMin", "exports", "module", "config", "plugin", "CacheManager", "filterDefault", "values", "key", "pluginExport", "options", "addBase", "addUtilities", "theme", "matchUtilities", "cacheManager", "cache", "rootVars", "value", "semanticUtilities", "cssVar", "match", "prefix", "name", "className", "bgUtilities", "textUtilities", "borderUtilities", "fillUtilities", "fontUtilities", "fontFace", "keyframeRules", "frames", "animationUtilities", "processedCss", "themePath", "parts", "i", "rule", "selector", "styles", "styleObj", "prop", "p", "acc", "item", "defaultContent"]
|
|
7
|
+
}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var o=typeof window<"u"&&typeof window.document<"u",w=typeof process<"u"&&process.versions&&process.versions.node,u=function(){return o&&console.warn("[FrontFriend] The Tailwind plugin cannot be used directly in browser environments"),{}};function F(n){return!n||typeof n!="object"?new Proxy({},{get(e,i){return new Proxy({},{get(_,s){return new Proxy({},{get(){return""}})}})}}):n}var r=null,t=null;function f(){return typeof __FF_CONFIG__<"u"?__FF_CONFIG__:o&&window.__FF_CONFIG__?window.__FF_CONFIG__:null}function d(){return typeof __FF_ICONS__<"u"?__FF_ICONS__:o&&window.__FF_ICONS__?window.__FF_ICONS__:null}var c=new Proxy({},{get(n,e){return r||(r=f()),r&&e in r?r[e]:new Proxy({},{get(i,_){return new Proxy({},{get(){return""}})}})}}),l=new Proxy({},{get(n,e){return t||(t=d()),t&&e in t?t[e]:null}}),g=u;export{c as config,g as default,F as ffdc,l as iconSet};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../index.mjs"],
|
|
4
|
+
"sourcesContent": ["// ES Module wrapper for frontfriend-tailwind\n// This file provides ES module exports for browser environments\n\n// Determine environment\nconst isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nconst isNode = typeof process !== 'undefined' && process.versions && process.versions.node;\n\n// Default plugin stub for browser\nconst plugin = function() {\n if (isBrowser) {\n console.warn('[FrontFriend] The Tailwind plugin cannot be used directly in browser environments');\n }\n return {};\n};\n\n// The ffdc function - with graceful fallback for SSR\nexport function ffdc(config) {\n // During SSR or initial load, config might not be available yet\n // Return a proxy that provides empty objects/strings for any property access\n if (!config || typeof config !== 'object') {\n return new Proxy({}, {\n get(target, prop) {\n // Return another proxy for nested property access\n return new Proxy({}, {\n get(target2, prop2) {\n // For deeply nested properties, return empty string or another proxy\n return new Proxy({}, {\n get() {\n return '';\n }\n });\n }\n });\n }\n });\n }\n \n return config;\n}\n\n// In browser environments, config and iconSet must be provided by the build system\n// (e.g., Vite plugin, webpack plugin, etc.) or loaded from a global variable\nlet _config = null;\nlet _iconSet = null;\n\n// Function to get config - tries multiple sources\nfunction getConfig() {\n // Try global variable first (webpack DefinePlugin)\n if (typeof __FF_CONFIG__ !== 'undefined') {\n return __FF_CONFIG__;\n }\n // Try window global\n if (isBrowser && window.__FF_CONFIG__) {\n return window.__FF_CONFIG__;\n }\n return null;\n}\n\n// Function to get icons - tries multiple sources\nfunction getIcons() {\n // Try global variable first (webpack DefinePlugin)\n if (typeof __FF_ICONS__ !== 'undefined') {\n return __FF_ICONS__;\n }\n // Try window global\n if (isBrowser && window.__FF_ICONS__) {\n return window.__FF_ICONS__;\n }\n return null;\n}\n\n// Export config - returns empty object if not loaded\nexport const config = new Proxy({}, {\n get(target, prop) {\n // Try to get config if not already loaded\n if (!_config) {\n _config = getConfig();\n }\n \n if (_config && prop in _config) {\n return _config[prop];\n }\n \n // Return a proxy that provides empty objects for any nested access\n // This prevents errors when accessing nested properties during SSR\n return new Proxy({}, {\n get(target2, prop2) {\n return new Proxy({}, {\n get() {\n return '';\n }\n });\n }\n });\n }\n});\n\n// Export iconSet - returns null if not loaded\nexport const iconSet = new Proxy({}, {\n get(target, prop) {\n // Try to get icons if not already loaded\n if (!_iconSet) {\n _iconSet = getIcons();\n }\n \n if (_iconSet && prop in _iconSet) {\n return _iconSet[prop];\n }\n return null;\n }\n});\n\n// Default export\nexport default plugin;"],
|
|
5
|
+
"mappings": "AAIA,IAAMA,EAAY,OAAO,OAAW,KAAe,OAAO,OAAO,SAAa,IACxEC,EAAS,OAAO,QAAY,KAAe,QAAQ,UAAY,QAAQ,SAAS,KAGhFC,EAAS,UAAW,CACxB,OAAIF,GACF,QAAQ,KAAK,mFAAmF,EAE3F,CAAC,CACV,EAGO,SAASG,EAAKC,EAAQ,CAG3B,MAAI,CAACA,GAAU,OAAOA,GAAW,SACxB,IAAI,MAAM,CAAC,EAAG,CACnB,IAAIC,EAAQC,EAAM,CAEhB,OAAO,IAAI,MAAM,CAAC,EAAG,CACnB,IAAIC,EAASC,EAAO,CAElB,OAAO,IAAI,MAAM,CAAC,EAAG,CACnB,KAAM,CACJ,MAAO,EACT,CACF,CAAC,CACH,CACF,CAAC,CACH,CACF,CAAC,EAGIJ,CACT,CAIA,IAAIK,EAAU,KACVC,EAAW,KAGf,SAASC,GAAY,CAEnB,OAAI,OAAO,cAAkB,IACpB,cAGLX,GAAa,OAAO,cACf,OAAO,cAET,IACT,CAGA,SAASY,GAAW,CAElB,OAAI,OAAO,aAAiB,IACnB,aAGLZ,GAAa,OAAO,aACf,OAAO,aAET,IACT,CAGO,IAAMI,EAAS,IAAI,MAAM,CAAC,EAAG,CAClC,IAAIC,EAAQC,EAAM,CAMhB,OAJKG,IACHA,EAAUE,EAAU,GAGlBF,GAAWH,KAAQG,EACdA,EAAQH,CAAI,EAKd,IAAI,MAAM,CAAC,EAAG,CACnB,IAAIC,EAASC,EAAO,CAClB,OAAO,IAAI,MAAM,CAAC,EAAG,CACnB,KAAM,CACJ,MAAO,EACT,CACF,CAAC,CACH,CACF,CAAC,CACH,CACF,CAAC,EAGYK,EAAU,IAAI,MAAM,CAAC,EAAG,CACnC,IAAIR,EAAQC,EAAM,CAMhB,OAJKI,IACHA,EAAWE,EAAS,GAGlBF,GAAYJ,KAAQI,EACfA,EAASJ,CAAI,EAEf,IACT,CACF,CAAC,EAGMQ,EAAQZ",
|
|
6
|
+
"names": ["isBrowser", "isNode", "plugin", "ffdc", "config", "target", "prop", "target2", "prop2", "_config", "_iconSet", "getConfig", "getIcons", "iconSet", "frontfriend_tailwind_default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { CACHE_DIR_NAME, CACHE_TTL_MS, CACHE_FILES } = require('../core/constants');
|
|
4
|
+
const { CacheError } = require('../core/errors');
|
|
5
|
+
|
|
6
|
+
class CacheManager {
|
|
7
|
+
constructor(appRoot = process.cwd()) {
|
|
8
|
+
this.appRoot = appRoot;
|
|
9
|
+
this.cacheDir = path.join(appRoot, 'node_modules', CACHE_DIR_NAME);
|
|
10
|
+
this.metadataFile = path.join(this.cacheDir, 'metadata.json');
|
|
11
|
+
this.maxAge = CACHE_TTL_MS;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get the cache directory path
|
|
16
|
+
* @returns {string} Cache directory path
|
|
17
|
+
*/
|
|
18
|
+
getCacheDir() {
|
|
19
|
+
return this.cacheDir;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check if cache directory exists
|
|
24
|
+
* @returns {boolean} True if cache exists
|
|
25
|
+
*/
|
|
26
|
+
exists() {
|
|
27
|
+
return fs.existsSync(this.cacheDir);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if cache is valid (exists and not expired)
|
|
32
|
+
* @returns {boolean} True if cache is valid
|
|
33
|
+
*/
|
|
34
|
+
isValid() {
|
|
35
|
+
if (!this.exists()) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
if (!fs.existsSync(this.metadataFile)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const metadata = JSON.parse(fs.readFileSync(this.metadataFile, 'utf-8'));
|
|
45
|
+
const timestamp = new Date(metadata.timestamp).getTime();
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
|
|
48
|
+
return (now - timestamp) < this.maxAge;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Load all cached data
|
|
56
|
+
* @returns {Object|null} Cached data object or null if not found
|
|
57
|
+
*/
|
|
58
|
+
load() {
|
|
59
|
+
if (!this.exists()) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const data = {};
|
|
65
|
+
|
|
66
|
+
// Load all .js files
|
|
67
|
+
for (const file of CACHE_FILES.JS) {
|
|
68
|
+
const filePath = path.join(this.cacheDir, file);
|
|
69
|
+
if (fs.existsSync(filePath)) {
|
|
70
|
+
// Remove .js extension for key
|
|
71
|
+
const key = file.replace('.js', '');
|
|
72
|
+
try {
|
|
73
|
+
// Use a more secure approach - parse the exported data
|
|
74
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
75
|
+
// Create a safe evaluation context
|
|
76
|
+
const moduleExports = {};
|
|
77
|
+
const fakeModule = { exports: moduleExports };
|
|
78
|
+
|
|
79
|
+
// Use Function constructor to evaluate in isolated scope
|
|
80
|
+
const evalFunc = new Function('module', 'exports', content);
|
|
81
|
+
evalFunc(fakeModule, moduleExports);
|
|
82
|
+
|
|
83
|
+
data[key] = fakeModule.exports;
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// Skip files that can't be parsed
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Load all .json files
|
|
91
|
+
for (const file of CACHE_FILES.JSON) {
|
|
92
|
+
const filePath = path.join(this.cacheDir, file);
|
|
93
|
+
if (fs.existsSync(filePath)) {
|
|
94
|
+
const key = file.replace('.json', '');
|
|
95
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
96
|
+
data[key] = JSON.parse(content);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Rename components-config to componentsConfig for consistency
|
|
101
|
+
if (data['components-config']) {
|
|
102
|
+
data.componentsConfig = data['components-config'];
|
|
103
|
+
delete data['components-config'];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return data;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
throw new CacheError(`Failed to load cache: ${error.message}`, 'read');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Save data to cache
|
|
114
|
+
* @param {Object} data - Data object to save
|
|
115
|
+
* @throws {Error} If save operation fails
|
|
116
|
+
*/
|
|
117
|
+
save(data) {
|
|
118
|
+
try {
|
|
119
|
+
// Create cache directory
|
|
120
|
+
fs.mkdirSync(this.cacheDir, { recursive: true });
|
|
121
|
+
|
|
122
|
+
// Save metadata first
|
|
123
|
+
const metadata = {
|
|
124
|
+
timestamp: new Date().toISOString(),
|
|
125
|
+
version: data.metadata?.version || '2.0.0',
|
|
126
|
+
ffId: data.metadata?.ffId
|
|
127
|
+
};
|
|
128
|
+
fs.writeFileSync(
|
|
129
|
+
this.metadataFile,
|
|
130
|
+
JSON.stringify(metadata, null, 2)
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Save .js files
|
|
134
|
+
const jsFiles = [
|
|
135
|
+
'tokens',
|
|
136
|
+
'variables',
|
|
137
|
+
'semanticVariables',
|
|
138
|
+
'semanticDarkVariables',
|
|
139
|
+
'cls',
|
|
140
|
+
'custom'
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
for (const key of jsFiles) {
|
|
144
|
+
if (data[key] !== undefined) {
|
|
145
|
+
const filePath = path.join(this.cacheDir, `${key}.js`);
|
|
146
|
+
const content = `module.exports = ${JSON.stringify(data[key], null, 2)};`;
|
|
147
|
+
fs.writeFileSync(filePath, content);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Save .json files
|
|
152
|
+
const jsonData = {
|
|
153
|
+
fonts: data.fonts,
|
|
154
|
+
icons: data.icons || data.iconSet,
|
|
155
|
+
'components-config': data.componentsConfig,
|
|
156
|
+
version: data.version
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
for (const [key, value] of Object.entries(jsonData)) {
|
|
160
|
+
if (value !== undefined) {
|
|
161
|
+
const filePath = path.join(this.cacheDir, `${key}.json`);
|
|
162
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
throw new CacheError(`Failed to save cache: ${error.message}`, 'write');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Clear the cache directory
|
|
172
|
+
*/
|
|
173
|
+
clear() {
|
|
174
|
+
if (this.exists()) {
|
|
175
|
+
fs.rmSync(this.cacheDir, { recursive: true, force: true });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = CacheManager;
|