@skafform/vite-plugin 0.1.2 → 0.1.4
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/base.css +1 -0
- package/dist/index.js +105 -13
- package/package.json +1 -1
package/base.css
CHANGED
package/dist/index.js
CHANGED
|
@@ -57,10 +57,22 @@ function skafform() {
|
|
|
57
57
|
let root = process.cwd();
|
|
58
58
|
let brickIndex = /* @__PURE__ */ new Set();
|
|
59
59
|
let config = {};
|
|
60
|
+
let themeJsonCache = null;
|
|
61
|
+
let bricksConfigCache = null;
|
|
60
62
|
function getThemeJson(theme) {
|
|
63
|
+
if (themeJsonCache) return themeJsonCache;
|
|
61
64
|
const childPath = resolve(root, `themes/${theme}/child/theme.json`);
|
|
62
65
|
if (!existsSync(childPath)) return {};
|
|
63
|
-
|
|
66
|
+
const parsed = JSON.parse(readFileSync(childPath, "utf-8"));
|
|
67
|
+
themeJsonCache = parsed;
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
function getBricksConfig() {
|
|
71
|
+
if (bricksConfigCache) return bricksConfigCache;
|
|
72
|
+
const path = resolve(root, "skafform-bricks.json");
|
|
73
|
+
if (!existsSync(path)) return null;
|
|
74
|
+
bricksConfigCache = JSON.parse(readFileSync(path, "utf-8"));
|
|
75
|
+
return bricksConfigCache;
|
|
64
76
|
}
|
|
65
77
|
function readCss(path) {
|
|
66
78
|
return readFileSync(path, "utf-8").replace(/^/, "");
|
|
@@ -73,20 +85,92 @@ function skafform() {
|
|
|
73
85
|
${vars}
|
|
74
86
|
}`;
|
|
75
87
|
}
|
|
88
|
+
const TAILWIND_TOKEN_MAP = {
|
|
89
|
+
"primary": "--color-primary",
|
|
90
|
+
"primary-fg": "--color-primary-fg",
|
|
91
|
+
"primary-hover": "--color-primary-hover",
|
|
92
|
+
"background": "--color-background",
|
|
93
|
+
"foreground": "--color-foreground",
|
|
94
|
+
"muted": "--color-muted",
|
|
95
|
+
"muted-fg": "--color-muted-fg",
|
|
96
|
+
"border": "--color-border",
|
|
97
|
+
"border-subtle": "--color-border-subtle",
|
|
98
|
+
"error": "--color-error",
|
|
99
|
+
"font": "--font-sans",
|
|
100
|
+
"font-heading": "--font-heading",
|
|
101
|
+
"font-body": "--font-body",
|
|
102
|
+
"font-size-xs": "--text-xs",
|
|
103
|
+
"font-size-sm": "--text-sm",
|
|
104
|
+
"font-size-base": "--text-base",
|
|
105
|
+
"font-size-lg": "--text-lg",
|
|
106
|
+
"font-size-xl": "--text-xl",
|
|
107
|
+
"font-size-2xl": "--text-2xl",
|
|
108
|
+
"radius": "--radius",
|
|
109
|
+
"radius-sm": "--radius-sm",
|
|
110
|
+
"radius-md": "--radius-md",
|
|
111
|
+
"radius-lg": "--radius-lg",
|
|
112
|
+
"radius-full": "--radius-full",
|
|
113
|
+
"shadow-sm": "--shadow-sm",
|
|
114
|
+
"shadow-md": "--shadow-md",
|
|
115
|
+
"shadow-lg": "--shadow-lg"
|
|
116
|
+
};
|
|
117
|
+
function generateTailwindTheme(tokens) {
|
|
118
|
+
const lines = [];
|
|
119
|
+
for (const key of Object.keys(tokens)) {
|
|
120
|
+
const twVar = TAILWIND_TOKEN_MAP[key];
|
|
121
|
+
if (twVar) lines.push(` ${twVar}: var(--skafform-${key});`);
|
|
122
|
+
}
|
|
123
|
+
if (lines.length === 0) return "";
|
|
124
|
+
return `@theme inline {
|
|
125
|
+
${lines.join("\n")}
|
|
126
|
+
}`;
|
|
127
|
+
}
|
|
128
|
+
function generateDarkTokensCss(darkTokens, lightTokens) {
|
|
129
|
+
const entries = Object.entries(darkTokens);
|
|
130
|
+
if (entries.length === 0) return "";
|
|
131
|
+
const darkVars = entries.map(([k, v]) => ` --skafform-${k}: ${v};`).join("\n");
|
|
132
|
+
const classVars = entries.map(([k, v]) => ` --skafform-${k}: ${v};`).join("\n");
|
|
133
|
+
const lightVars = entries.filter(([k]) => k in lightTokens).map(([k]) => ` --skafform-${k}: ${lightTokens[k]};`).join("\n");
|
|
134
|
+
return [
|
|
135
|
+
`@media (prefers-color-scheme: dark) {
|
|
136
|
+
:root {
|
|
137
|
+
${darkVars}
|
|
138
|
+
}
|
|
139
|
+
}`,
|
|
140
|
+
`.dark {
|
|
141
|
+
${classVars}
|
|
142
|
+
}`,
|
|
143
|
+
lightVars ? `.light {
|
|
144
|
+
${lightVars}
|
|
145
|
+
}` : ""
|
|
146
|
+
].filter(Boolean).join("\n");
|
|
147
|
+
}
|
|
76
148
|
function getCssString() {
|
|
77
149
|
const themeJson = getThemeJson(config.theme);
|
|
78
150
|
const themeCssPath = resolve(root, `themes/${config.theme}/styles/theme.css`);
|
|
79
151
|
const base = readCss(baseCssPath);
|
|
80
152
|
const theme = existsSync(themeCssPath) ? readCss(themeCssPath) : "";
|
|
81
153
|
const tokens = generateTokensCss(themeJson.tokens ?? {});
|
|
82
|
-
|
|
154
|
+
const dark = themeJson.tokens_dark ? generateDarkTokensCss(themeJson.tokens_dark, themeJson.tokens ?? {}) : "";
|
|
155
|
+
const css = base + "\n" + theme + (tokens ? "\n" + tokens : "") + (dark ? "\n" + dark : "");
|
|
156
|
+
if (config.tailwind) {
|
|
157
|
+
const tailwindTheme = generateTailwindTheme(themeJson.tokens ?? {});
|
|
158
|
+
return `@import "tailwindcss";
|
|
159
|
+
|
|
160
|
+
` + css + (tailwindTheme ? "\n" + tailwindTheme : "");
|
|
161
|
+
}
|
|
162
|
+
return css;
|
|
83
163
|
}
|
|
84
164
|
return {
|
|
85
165
|
name: "skafform",
|
|
86
166
|
enforce: "pre",
|
|
87
167
|
configResolved(resolved) {
|
|
88
168
|
root = resolved.root;
|
|
89
|
-
|
|
169
|
+
try {
|
|
170
|
+
config = JSON.parse(readFileSync(resolve(root, "skafform.config.json"), "utf-8"));
|
|
171
|
+
} catch (err) {
|
|
172
|
+
throw new Error(`[skafform] Cannot read skafform.config.json: ${err instanceof Error ? err.message : err}`);
|
|
173
|
+
}
|
|
90
174
|
brickIndex = loadBrickIndex(root);
|
|
91
175
|
writeFileSync(resolve(root, "app/skafform-theme.css"), getCssString(), "utf-8");
|
|
92
176
|
},
|
|
@@ -117,13 +201,13 @@ ${vars}
|
|
|
117
201
|
const themeJson = getThemeJson(config.theme);
|
|
118
202
|
return `export default ${JSON.stringify({
|
|
119
203
|
...config,
|
|
120
|
-
customize: { ...themeJson.customize ?? {}, ...config.customize ?? {} }
|
|
204
|
+
customize: { ...themeJson.customize ?? {}, ...config.customize ?? {} },
|
|
205
|
+
fonts: themeJson.fonts ?? []
|
|
121
206
|
})}`;
|
|
122
207
|
}
|
|
123
208
|
if (id === RESOLVED_ADMIN_SECTIONS) {
|
|
124
|
-
const
|
|
125
|
-
if (!
|
|
126
|
-
const bricksConfig = JSON.parse(readFileSync(bricksConfigPath, "utf-8"));
|
|
209
|
+
const bricksConfig = getBricksConfig();
|
|
210
|
+
if (!bricksConfig) return "export default []";
|
|
127
211
|
const sections = [];
|
|
128
212
|
for (const brick of Object.values(bricksConfig.bricks ?? {})) {
|
|
129
213
|
for (const section of brick.adminSections ?? []) {
|
|
@@ -133,23 +217,31 @@ ${vars}
|
|
|
133
217
|
return `export default ${JSON.stringify(sections)}`;
|
|
134
218
|
}
|
|
135
219
|
if (id === RESOLVED_SERVER_INIT) {
|
|
136
|
-
const
|
|
137
|
-
if (!
|
|
138
|
-
const bricksConfig = JSON.parse(readFileSync(bricksConfigPath, "utf-8"));
|
|
220
|
+
const bricksConfig = getBricksConfig();
|
|
221
|
+
if (!bricksConfig) return "";
|
|
139
222
|
const adapters = bricksConfig.adapters ?? {};
|
|
140
223
|
if (!adapters.auth) return "";
|
|
141
224
|
const adapterPath = resolve(root, adapters.auth).replace(/\\/g, "/");
|
|
142
225
|
return [
|
|
143
226
|
`import { setAdapter } from "@skafform/core/runtime"`,
|
|
144
|
-
`import { authAdapter } from
|
|
227
|
+
`import { authAdapter } from ${JSON.stringify(adapterPath)}`,
|
|
145
228
|
`setAdapter(authAdapter)`
|
|
146
229
|
].join("\n");
|
|
147
230
|
}
|
|
148
231
|
},
|
|
149
232
|
handleHotUpdate({ file, server }) {
|
|
150
|
-
|
|
151
|
-
|
|
233
|
+
const f = norm(file);
|
|
234
|
+
const r = norm(root);
|
|
235
|
+
if (f === `${r}/skafform.config.json` || f.startsWith(`${r}/themes/`) || f.startsWith(`${r}/bricks/`)) {
|
|
236
|
+
try {
|
|
237
|
+
config = JSON.parse(readFileSync(resolve(root, "skafform.config.json"), "utf-8"));
|
|
238
|
+
} catch {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
152
241
|
brickIndex = loadBrickIndex(root);
|
|
242
|
+
themeJsonCache = null;
|
|
243
|
+
bricksConfigCache = null;
|
|
244
|
+
writeFileSync(resolve(root, "app/skafform-theme.css"), getCssString(), "utf-8");
|
|
153
245
|
server.moduleGraph.invalidateAll();
|
|
154
246
|
server.ws.send({ type: "full-reload" });
|
|
155
247
|
}
|