@upstart.gg/vite-plugins 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vite-plugin-upstart-attrs.d.ts +29 -0
- package/dist/vite-plugin-upstart-attrs.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-attrs.js +323 -0
- package/dist/vite-plugin-upstart-attrs.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/plugin.d.ts +15 -0
- package/dist/vite-plugin-upstart-editor/plugin.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/plugin.js +55 -0
- package/dist/vite-plugin-upstart-editor/plugin.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.d.ts +12 -0
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.js +57 -0
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.d.ts +12 -0
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js +91 -0
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/index.d.ts +22 -0
- package/dist/vite-plugin-upstart-editor/runtime/index.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/index.js +62 -0
- package/dist/vite-plugin-upstart-editor/runtime/index.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.d.ts +15 -0
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.js +292 -0
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/types.d.ts +126 -0
- package/dist/vite-plugin-upstart-editor/runtime/types.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/types.js +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/utils.d.ts +15 -0
- package/dist/vite-plugin-upstart-editor/runtime/utils.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/utils.js +26 -0
- package/dist/vite-plugin-upstart-editor/runtime/utils.js.map +1 -0
- package/dist/vite-plugin-upstart-theme.d.ts +22 -0
- package/dist/vite-plugin-upstart-theme.d.ts.map +1 -0
- package/dist/vite-plugin-upstart-theme.js +179 -0
- package/dist/vite-plugin-upstart-theme.js.map +1 -0
- package/package.json +63 -0
- package/src/tests/fixtures/routes/default-layout.tsx +10 -0
- package/src/tests/fixtures/routes/dynamic-route.tsx +10 -0
- package/src/tests/fixtures/routes/missing-attributes.tsx +8 -0
- package/src/tests/fixtures/routes/missing-path.tsx +9 -0
- package/src/tests/fixtures/routes/valid-full.tsx +15 -0
- package/src/tests/fixtures/routes/valid-minimal.tsx +10 -0
- package/src/tests/fixtures/routes/with-comments.tsx +12 -0
- package/src/tests/fixtures/routes/with-nested-objects.tsx +15 -0
- package/src/tests/upstart-editor-api.test.ts +367 -0
- package/src/tests/vite-plugin-upstart-attrs.test.ts +1189 -0
- package/src/tests/vite-plugin-upstart-editor.test.ts +81 -0
- package/src/upstart-editor-api.ts +204 -0
- package/src/vite-plugin-upstart-attrs.ts +708 -0
- package/src/vite-plugin-upstart-editor/PLAN.md +1391 -0
- package/src/vite-plugin-upstart-editor/plugin.ts +73 -0
- package/src/vite-plugin-upstart-editor/runtime/click-handler.ts +80 -0
- package/src/vite-plugin-upstart-editor/runtime/hover-overlay.ts +135 -0
- package/src/vite-plugin-upstart-editor/runtime/index.ts +90 -0
- package/src/vite-plugin-upstart-editor/runtime/text-editor.ts +401 -0
- package/src/vite-plugin-upstart-editor/runtime/types.ts +120 -0
- package/src/vite-plugin-upstart-editor/runtime/utils.ts +34 -0
- package/src/vite-plugin-upstart-theme.ts +314 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EditorMessage } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/vite-plugin-upstart-editor/runtime/utils.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Send a message to the parent window.
|
|
7
|
+
*/
|
|
8
|
+
declare function sendToParent(message: EditorMessage): void;
|
|
9
|
+
/**
|
|
10
|
+
* Check if running inside an iframe.
|
|
11
|
+
*/
|
|
12
|
+
declare function isInIframe(): boolean;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { isInIframe, sendToParent };
|
|
15
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/vite-plugin-upstart-editor/runtime/utils.ts"],"sourcesContent":[],"mappings":";;;;;;AAKA;AAsBgB,iBAtBA,YAAA,CAsBU,OAAA,EAtBY,aAsBZ,CAAA,EAAA,IAAA;;;;iBAAV,UAAA,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/vite-plugin-upstart-editor/runtime/utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Send a message to the parent window.
|
|
4
|
+
*/
|
|
5
|
+
function sendToParent(message) {
|
|
6
|
+
if (typeof window === "undefined") return;
|
|
7
|
+
if (window.parent === window) {
|
|
8
|
+
console.warn("[Upstart Editor] Not running in iframe, cannot send message:", message);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
window.parent.postMessage({
|
|
12
|
+
source: "upstart-editor",
|
|
13
|
+
...message
|
|
14
|
+
}, "*");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if running inside an iframe.
|
|
18
|
+
*/
|
|
19
|
+
function isInIframe() {
|
|
20
|
+
if (typeof window === "undefined") return false;
|
|
21
|
+
return window.parent !== window;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
export { isInIframe, sendToParent };
|
|
26
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/vite-plugin-upstart-editor/runtime/utils.ts"],"sourcesContent":["import type { EditorMessage } from \"./types\";\n\n/**\n * Send a message to the parent window.\n */\nexport function sendToParent(message: EditorMessage): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n if (window.parent === window) {\n console.warn(\"[Upstart Editor] Not running in iframe, cannot send message:\", message);\n return;\n }\n\n window.parent.postMessage(\n {\n source: \"upstart-editor\",\n ...message,\n },\n \"*\",\n );\n}\n\n/**\n * Check if running inside an iframe.\n */\nexport function isInIframe(): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n\n return window.parent !== window;\n}\n"],"mappings":";;;;AAKA,SAAgB,aAAa,SAA8B;AACzD,KAAI,OAAO,WAAW,YACpB;AAGF,KAAI,OAAO,WAAW,QAAQ;AAC5B,UAAQ,KAAK,gEAAgE,QAAQ;AACrF;;AAGF,QAAO,OAAO,YACZ;EACE,QAAQ;EACR,GAAG;EACJ,EACD,IACD;;;;;AAMH,SAAgB,aAAsB;AACpC,KAAI,OAAO,WAAW,YACpB,QAAO;AAGT,QAAO,OAAO,WAAW"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as unplugin0 from "unplugin";
|
|
2
|
+
import { Theme } from "@upstart.gg/sdk/themes/theme";
|
|
3
|
+
|
|
4
|
+
//#region src/vite-plugin-upstart-theme.d.ts
|
|
5
|
+
interface PluginOptions {
|
|
6
|
+
themes: {
|
|
7
|
+
light: Theme;
|
|
8
|
+
dark?: Theme;
|
|
9
|
+
default: "light" | "dark";
|
|
10
|
+
};
|
|
11
|
+
outputPath: string;
|
|
12
|
+
/** Google Fonts display parameter (default: 'swap') */
|
|
13
|
+
fontsDisplay?: "auto" | "block" | "swap" | "fallback" | "optional";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Unplugin-based theme generator
|
|
17
|
+
*/
|
|
18
|
+
declare const upstartTheme: unplugin0.UnpluginInstance<PluginOptions, boolean>;
|
|
19
|
+
declare const _default: (options: PluginOptions) => unplugin0.VitePlugin<any> | unplugin0.VitePlugin<any>[];
|
|
20
|
+
//#endregion
|
|
21
|
+
export { _default as default, upstartTheme };
|
|
22
|
+
//# sourceMappingURL=vite-plugin-upstart-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin-upstart-theme.d.ts","names":[],"sources":["../src/vite-plugin-upstart-theme.ts"],"sourcesContent":[],"mappings":";;;;UAWU,aAAA;;WAEC;IAFD,IAAA,CAAA,EAGC,KAHY;IA2OV,OAAA,EAAA,OAiEX,GAAA,MAjEuB;EAiEtB,CAAA;;;;;;;;cAjEU,cAAY,SAAA,CAAA,iBAAA;cAiEtB"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { createUnplugin } from "unplugin";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fontStacksFonts, processTheme } from "@upstart.gg/sdk/themes/theme";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
|
|
6
|
+
//#region src/vite-plugin-upstart-theme.ts
|
|
7
|
+
/**
|
|
8
|
+
* Collects Google Fonts from a theme's typography configuration
|
|
9
|
+
*/
|
|
10
|
+
function collectGoogleFonts(theme) {
|
|
11
|
+
const { typography } = theme;
|
|
12
|
+
if (!typography) return [];
|
|
13
|
+
const googleFonts = [];
|
|
14
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15
|
+
const addFont = (font) => {
|
|
16
|
+
if (font?.type === "google" && !seen.has(font.family)) {
|
|
17
|
+
seen.add(font.family);
|
|
18
|
+
googleFonts.push(font);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
addFont(typography.sans);
|
|
22
|
+
addFont(typography.serif);
|
|
23
|
+
if (typography.others) Object.values(typography.others).forEach(addFont);
|
|
24
|
+
return googleFonts;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generates the fonts.css file content with Google Fonts imports
|
|
28
|
+
*/
|
|
29
|
+
function generateFontsCSS(lightTheme, darkTheme = null, display = "swap") {
|
|
30
|
+
const allFonts = /* @__PURE__ */ new Map();
|
|
31
|
+
for (const font of collectGoogleFonts(lightTheme)) allFonts.set(font.family, font);
|
|
32
|
+
if (darkTheme) for (const font of collectGoogleFonts(darkTheme)) allFonts.set(font.family, font);
|
|
33
|
+
if (allFonts.size === 0) return "/* No Google Fonts to import */\n";
|
|
34
|
+
return `/* Google Fonts - Auto-generated by vite-plugin-upstart-theme */\n@import url("${`https://fonts.googleapis.com/css2?${Array.from(allFonts.values()).map((font) => {
|
|
35
|
+
const name = font.family.replace(/ /g, "+");
|
|
36
|
+
if (font.weights && font.weights.length > 1 && font.weights[0] !== font.weights.at(-1)) return `family=${name}:wght@${font.weights[0]}..${font.weights.at(-1)}`;
|
|
37
|
+
return `family=${name}`;
|
|
38
|
+
}).join("&")}&display=${display}`}");\n`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Converts a font definition to a CSS font-family string
|
|
42
|
+
*/
|
|
43
|
+
function fontToCss(font) {
|
|
44
|
+
if (!font) return "";
|
|
45
|
+
if (font.type === "stack") return fontStacksFonts[font.family];
|
|
46
|
+
if (font.type === "google") return `"${font.family}", system-ui, sans-serif`;
|
|
47
|
+
return "";
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Converts camelCase to kebab-case
|
|
51
|
+
*/
|
|
52
|
+
function camelToKebab(str) {
|
|
53
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generates @theme block with font definitions
|
|
57
|
+
*/
|
|
58
|
+
function generateThemeBlock(lightTheme, darkTheme = null, defaultTheme = "light") {
|
|
59
|
+
const fontDefinitions = /* @__PURE__ */ new Map();
|
|
60
|
+
const lightTypography = lightTheme.typography;
|
|
61
|
+
if (lightTypography.sans) {
|
|
62
|
+
const fontCss = fontToCss(lightTypography.sans);
|
|
63
|
+
if (fontCss) fontDefinitions.set("sans", fontCss);
|
|
64
|
+
}
|
|
65
|
+
if (lightTypography.serif) {
|
|
66
|
+
const fontCss = fontToCss(lightTypography.serif);
|
|
67
|
+
if (fontCss) fontDefinitions.set("serif", fontCss);
|
|
68
|
+
}
|
|
69
|
+
if (lightTypography.others) for (const [name, font] of Object.entries(lightTypography.others)) {
|
|
70
|
+
const fontCss = fontToCss(font);
|
|
71
|
+
if (fontCss) fontDefinitions.set(name, fontCss);
|
|
72
|
+
}
|
|
73
|
+
if (darkTheme) {
|
|
74
|
+
const darkTypography = darkTheme.typography;
|
|
75
|
+
if (darkTypography.sans) {
|
|
76
|
+
const fontCss = fontToCss(darkTypography.sans);
|
|
77
|
+
if (fontCss) fontDefinitions.set("sans", fontCss);
|
|
78
|
+
}
|
|
79
|
+
if (darkTypography.serif) {
|
|
80
|
+
const fontCss = fontToCss(darkTypography.serif);
|
|
81
|
+
if (fontCss) fontDefinitions.set("serif", fontCss);
|
|
82
|
+
}
|
|
83
|
+
if (darkTypography.others) for (const [name, font] of Object.entries(darkTypography.others)) {
|
|
84
|
+
const fontCss = fontToCss(font);
|
|
85
|
+
if (fontCss) fontDefinitions.set(name, fontCss);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return `/* Fonts in the tailwind @theme block */
|
|
89
|
+
@theme {
|
|
90
|
+
${Array.from(fontDefinitions.entries()).map(([name, value]) => ` --font-${name}: ${value};`).join("\n")}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Exclude properties since it produce warnings and is not important */
|
|
94
|
+
@plugin "daisyui" {
|
|
95
|
+
exclude: properties;
|
|
96
|
+
themes: ${lightTheme.id} ${defaultTheme === "light" || !darkTheme ? "--default" : ""}${darkTheme?.id && darkTheme?.id !== lightTheme.id ? `, ${darkTheme.id} ${defaultTheme === "dark" ? "--default" : "--prefersdark"}` : ""};
|
|
97
|
+
logs: true;
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Generates @theme block for a single theme with colors and layout variables
|
|
103
|
+
*/
|
|
104
|
+
function generateThemeVariables(theme, type, defaultTheme) {
|
|
105
|
+
const processed = processTheme(theme);
|
|
106
|
+
const lines = [
|
|
107
|
+
` name: "${processed.id}";`,
|
|
108
|
+
` color-scheme: ${processed.browserColorScheme};`,
|
|
109
|
+
...defaultTheme === "dark" && theme.browserColorScheme === "dark" || defaultTheme === "light" && theme.browserColorScheme === "light" ? [` default: true;`] : []
|
|
110
|
+
];
|
|
111
|
+
for (const [colorKey, colorValue] of Object.entries(processed.colors)) {
|
|
112
|
+
const kebabKey = [
|
|
113
|
+
"base100",
|
|
114
|
+
"base200",
|
|
115
|
+
"base300"
|
|
116
|
+
].includes(colorKey) ? colorKey.replace("base", "base-") : camelToKebab(colorKey);
|
|
117
|
+
lines.push(` --color-${kebabKey}: ${colorValue};`);
|
|
118
|
+
}
|
|
119
|
+
lines.push("");
|
|
120
|
+
lines.push(` --radius-selector: ${processed.radiusSelector};`);
|
|
121
|
+
lines.push(` --radius-field: ${processed.radiusField};`);
|
|
122
|
+
lines.push(` --radius-box: ${processed.radiusBox};`);
|
|
123
|
+
lines.push(` --size-selector: ${processed.sizeSelector};`);
|
|
124
|
+
lines.push(` --size-field: ${processed.sizeField};`);
|
|
125
|
+
lines.push(` --border: ${processed.border};`);
|
|
126
|
+
lines.push(` --depth: ${processed.depth ? 1 : 0};`);
|
|
127
|
+
lines.push(` --noise: 0;`);
|
|
128
|
+
return lines.join("\n");
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Unplugin-based theme generator
|
|
132
|
+
*/
|
|
133
|
+
const upstartTheme = createUnplugin((opts) => {
|
|
134
|
+
let generated = false;
|
|
135
|
+
return {
|
|
136
|
+
name: "unplugin-theme-generator",
|
|
137
|
+
apply: "serve",
|
|
138
|
+
vite: { configResolved() {
|
|
139
|
+
if (generated) return;
|
|
140
|
+
generated = true;
|
|
141
|
+
if (!opts?.themes?.light) {
|
|
142
|
+
console.warn("No light theme provided to unplugin-theme-generator. A light theme is required.");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const outputDir = path.dirname(opts.outputPath);
|
|
146
|
+
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
147
|
+
const { themes, fontsDisplay = "swap" } = opts;
|
|
148
|
+
const fontsCSS = generateFontsCSS(themes.light, themes.dark, fontsDisplay);
|
|
149
|
+
const fontsCSSPath = path.join(outputDir, "fonts.css");
|
|
150
|
+
fs.writeFileSync(fontsCSSPath, fontsCSS);
|
|
151
|
+
console.log(`✓ Generated fonts CSS: ${fontsCSSPath}`);
|
|
152
|
+
const output = [];
|
|
153
|
+
output.push(generateThemeBlock(themes.light, themes.dark));
|
|
154
|
+
output.push("");
|
|
155
|
+
if (themes.dark) {
|
|
156
|
+
output.push("/* Dark theme variables */");
|
|
157
|
+
output.push("@plugin \"daisyui/theme\" {");
|
|
158
|
+
output.push(generateThemeVariables(themes.dark, "dark", themes.default));
|
|
159
|
+
output.push("}");
|
|
160
|
+
output.push("");
|
|
161
|
+
}
|
|
162
|
+
if (themes.light?.id !== themes.dark?.id) {
|
|
163
|
+
output.push("/* Light theme variables */");
|
|
164
|
+
output.push("@plugin \"daisyui/theme\" {");
|
|
165
|
+
output.push(generateThemeVariables(themes.light, "light", themes.default));
|
|
166
|
+
output.push("}");
|
|
167
|
+
output.push("");
|
|
168
|
+
}
|
|
169
|
+
const cssContent = output.join("\n");
|
|
170
|
+
fs.writeFileSync(opts.outputPath, cssContent);
|
|
171
|
+
console.log(`✓ Generated theme CSS: ${opts.outputPath}`);
|
|
172
|
+
} }
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
var vite_plugin_upstart_theme_default = upstartTheme.vite;
|
|
176
|
+
|
|
177
|
+
//#endregion
|
|
178
|
+
export { vite_plugin_upstart_theme_default as default, upstartTheme };
|
|
179
|
+
//# sourceMappingURL=vite-plugin-upstart-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin-upstart-theme.js","names":["googleFonts: Array<GoogleFont>","lines: string[]","output: string[]"],"sources":["../src/vite-plugin-upstart-theme.ts"],"sourcesContent":["import { createUnplugin } from \"unplugin\";\nimport {\n GenericFont,\n GoogleFont,\n type Theme,\n fontStacksFonts,\n processTheme,\n} from \"@upstart.gg/sdk/themes/theme\";\nimport fs from \"fs\";\nimport path from \"path\";\n\ninterface PluginOptions {\n themes: {\n light: Theme;\n dark?: Theme;\n default: \"light\" | \"dark\";\n };\n outputPath: string;\n /** Google Fonts display parameter (default: 'swap') */\n fontsDisplay?: \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\";\n}\n\n/**\n * Collects Google Fonts from a theme's typography configuration\n */\nfunction collectGoogleFonts(theme: Theme) {\n const { typography } = theme;\n if (!typography) return [];\n\n const googleFonts: Array<GoogleFont> = [];\n const seen = new Set<string>();\n\n const addFont = (font?: GenericFont) => {\n if (font?.type === \"google\" && !seen.has(font.family)) {\n seen.add(font.family);\n googleFonts.push(font);\n }\n };\n\n addFont(typography.sans);\n addFont(typography.serif);\n if (typography.others) {\n Object.values(typography.others).forEach(addFont);\n }\n\n return googleFonts;\n}\n\n/**\n * Generates the fonts.css file content with Google Fonts imports\n */\nfunction generateFontsCSS(\n lightTheme: Theme,\n darkTheme: Theme | null = null,\n display: \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\" = \"swap\",\n): string {\n // Collect fonts from both themes\n const allFonts = new Map<string, GoogleFont>();\n\n for (const font of collectGoogleFonts(lightTheme)) {\n allFonts.set(font.family, font);\n }\n\n if (darkTheme) {\n for (const font of collectGoogleFonts(darkTheme)) {\n allFonts.set(font.family, font);\n }\n }\n\n if (allFonts.size === 0) {\n return \"/* No Google Fonts to import */\\n\";\n }\n\n // Build the Google Fonts URL\n const families = Array.from(allFonts.values()).map((font) => {\n const name = font.family.replace(/ /g, \"+\");\n if (font.weights && font.weights.length > 1 && font.weights[0] !== font.weights.at(-1)) {\n return `family=${name}:wght@${font.weights[0]}..${font.weights.at(-1)}`;\n }\n return `family=${name}`;\n });\n\n const url = `https://fonts.googleapis.com/css2?${families.join(\"&\")}&display=${display}`;\n\n return `/* Google Fonts - Auto-generated by vite-plugin-upstart-theme */\\n@import url(\"${url}\");\\n`;\n}\n\n/**\n * Converts a font definition to a CSS font-family string\n */\nfunction fontToCss(font: Theme[\"typography\"][\"sans\"]): string {\n if (!font) return \"\";\n\n if (font.type === \"stack\") {\n return fontStacksFonts[font.family];\n }\n\n if (font.type === \"google\") {\n // For Google fonts, we just use the family name\n // The actual font loading will be handled separately\n return `\"${font.family}\", system-ui, sans-serif`;\n }\n\n return \"\";\n}\n\n/**\n * Converts camelCase to kebab-case\n */\nfunction camelToKebab(str: string): string {\n return str.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n\n/**\n * Generates @theme block with font definitions\n */\nfunction generateThemeBlock(\n lightTheme: Theme,\n darkTheme: Theme | null = null,\n defaultTheme: \"light\" | \"dark\" = \"light\",\n): string {\n const fontDefinitions = new Map<string, string>();\n\n // Process light theme fonts\n const lightTypography = lightTheme.typography;\n\n // Add sans font\n if (lightTypography.sans) {\n const fontCss = fontToCss(lightTypography.sans);\n if (fontCss) {\n fontDefinitions.set(\"sans\", fontCss);\n }\n }\n\n // Add serif font\n if (lightTypography.serif) {\n const fontCss = fontToCss(lightTypography.serif);\n if (fontCss) {\n fontDefinitions.set(\"serif\", fontCss);\n }\n }\n\n // Add other fonts\n if (lightTypography.others) {\n for (const [name, font] of Object.entries(lightTypography.others)) {\n const fontCss = fontToCss(font);\n if (fontCss) {\n fontDefinitions.set(name, fontCss);\n }\n }\n }\n\n // Process dark theme fonts if provided\n if (darkTheme) {\n const darkTypography = darkTheme.typography;\n\n if (darkTypography.sans) {\n const fontCss = fontToCss(darkTypography.sans);\n if (fontCss) {\n fontDefinitions.set(\"sans\", fontCss);\n }\n }\n\n if (darkTypography.serif) {\n const fontCss = fontToCss(darkTypography.serif);\n if (fontCss) {\n fontDefinitions.set(\"serif\", fontCss);\n }\n }\n\n if (darkTypography.others) {\n for (const [name, font] of Object.entries(darkTypography.others)) {\n const fontCss = fontToCss(font);\n if (fontCss) {\n fontDefinitions.set(name, fontCss);\n }\n }\n }\n }\n\n const fontLines = Array.from(fontDefinitions.entries())\n .map(([name, value]) => ` --font-${name}: ${value};`)\n .join(\"\\n\");\n\n return `/* Fonts in the tailwind @theme block */\n@theme {\n ${fontLines}\n}\n\n/* Exclude properties since it produce warnings and is not important */\n@plugin \"daisyui\" {\n exclude: properties;\n themes: ${lightTheme.id} ${defaultTheme === \"light\" || !darkTheme ? \"--default\" : \"\"}${darkTheme?.id && darkTheme?.id !== lightTheme.id ? `, ${darkTheme.id} ${defaultTheme === \"dark\" ? \"--default\" : \"--prefersdark\"}` : \"\"};\n logs: true;\n}\n`;\n}\n\n//\n\n/**\n * Generates @theme block for a single theme with colors and layout variables\n */\nfunction generateThemeVariables(\n theme: Theme,\n type: \"light\" | \"dark\",\n defaultTheme: \"light\" | \"dark\",\n): string {\n const processed = processTheme(theme);\n const lines: string[] = [\n ` name: \"${processed.id}\";`,\n ` color-scheme: ${processed.browserColorScheme};`,\n ...((defaultTheme === \"dark\" && theme.browserColorScheme === \"dark\") ||\n (defaultTheme === \"light\" && theme.browserColorScheme === \"light\")\n ? [` default: true;`]\n : []),\n // ...(type === \"dark\" && defaultTheme !== \"dark\" ? [` prefersdark: true;`] : [` prefersdark: false;`]),\n ];\n\n // Color variables\n for (const [colorKey, colorValue] of Object.entries(processed.colors)) {\n const kebabKey = [\"base100\", \"base200\", \"base300\"].includes(colorKey)\n ? colorKey.replace(\"base\", \"base-\")\n : camelToKebab(colorKey);\n lines.push(` --color-${kebabKey}: ${colorValue};`);\n }\n\n lines.push(\"\");\n\n // Layout variables\n lines.push(` --radius-selector: ${processed.radiusSelector};`);\n lines.push(` --radius-field: ${processed.radiusField};`);\n lines.push(` --radius-box: ${processed.radiusBox};`);\n lines.push(` --size-selector: ${processed.sizeSelector};`);\n lines.push(` --size-field: ${processed.sizeField};`);\n lines.push(` --border: ${processed.border};`);\n lines.push(` --depth: ${processed.depth ? 1 : 0};`);\n lines.push(` --noise: 0;`);\n\n // return the generated lines\n return lines.join(\"\\n\");\n}\n\n/**\n * Unplugin-based theme generator\n */\nexport const upstartTheme = createUnplugin<PluginOptions>((opts) => {\n let generated = false;\n\n return {\n name: \"unplugin-theme-generator\",\n apply: \"serve\",\n\n vite: {\n configResolved() {\n // Generate the CSS file once when config is resolved\n if (generated) return;\n generated = true;\n\n if (!opts?.themes?.light) {\n console.warn(\"No light theme provided to unplugin-theme-generator. A light theme is required.\");\n return;\n }\n\n const outputDir = path.dirname(opts.outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n const { themes, fontsDisplay = \"swap\" } = opts;\n\n // Generate fonts.css file\n const fontsCSS = generateFontsCSS(themes.light, themes.dark, fontsDisplay);\n const fontsCSSPath = path.join(outputDir, \"fonts.css\");\n fs.writeFileSync(fontsCSSPath, fontsCSS);\n console.log(`✓ Generated fonts CSS: ${fontsCSSPath}`);\n\n const output: string[] = [];\n\n // Generate @theme block with fonts from both themes\n output.push(generateThemeBlock(themes.light, themes.dark));\n output.push(\"\");\n\n // IMPORTANT; Place dark theme first OTHERWISE daisyUI will not apply it correctly\n // @see https://github.com/saadeghi/daisyui/issues/3921#issuecomment-3059524563\n // Generate @theme block for dark theme if present\n if (themes.dark) {\n output.push(\"/* Dark theme variables */\");\n output.push('@plugin \"daisyui/theme\" {');\n output.push(generateThemeVariables(themes.dark, \"dark\", themes.default));\n output.push(\"}\");\n output.push(\"\");\n }\n\n // Generate @theme block for light theme\n if (themes.light?.id !== themes.dark?.id) {\n output.push(\"/* Light theme variables */\");\n output.push('@plugin \"daisyui/theme\" {');\n output.push(generateThemeVariables(themes.light, \"light\", themes.default));\n output.push(\"}\");\n output.push(\"\");\n }\n\n // Write the generated CSS file\n const cssContent = output.join(\"\\n\");\n fs.writeFileSync(opts.outputPath, cssContent);\n\n console.log(`✓ Generated theme CSS: ${opts.outputPath}`);\n },\n },\n };\n});\n\nexport default upstartTheme.vite;\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@upstart.gg/vite-plugins",
|
|
3
|
+
"version": "0.0.37",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"src"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/upstart-gg/monorepo.git",
|
|
12
|
+
"directory": "packages/vite-plugins"
|
|
13
|
+
},
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@oxc-parser/binding-linux-arm64-gnu": "^0.101.0",
|
|
17
|
+
"@oxc-parser/binding-linux-x64-gnu": "^0.101.0",
|
|
18
|
+
"@tiptap/core": "^2.27.1",
|
|
19
|
+
"@tiptap/extension-bubble-menu": "^2.27.1",
|
|
20
|
+
"@tiptap/extension-placeholder": "^2.27.2",
|
|
21
|
+
"@tiptap/starter-kit": "^2.27.1",
|
|
22
|
+
"magic-string": "^0.30.21",
|
|
23
|
+
"oxc-parser": "^0.101.0",
|
|
24
|
+
"unplugin": "^2.3.11",
|
|
25
|
+
"zimmerframe": "^1.1.4",
|
|
26
|
+
"@upstart.gg/sdk": "^0.0.37"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/bun": "1.3.5",
|
|
30
|
+
"@types/estree": "^1.0.8",
|
|
31
|
+
"@types/estree-jsx": "1.0.5",
|
|
32
|
+
"@types/node": "^24.10.0",
|
|
33
|
+
"@types/react": "19.1.13",
|
|
34
|
+
"tsdown": "0.18.3",
|
|
35
|
+
"vitest": "4.0.16",
|
|
36
|
+
"@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.53",
|
|
37
|
+
"@rolldown/binding-linux-x64-gnu": "1.0.0-beta.53"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
"./vite-plugin-upstart-attrs": "./dist/vite-plugin-upstart-attrs.js",
|
|
41
|
+
"./vite-plugin-upstart-editor/plugin": "./dist/vite-plugin-upstart-editor/plugin.js",
|
|
42
|
+
"./vite-plugin-upstart-editor/runtime": "./dist/vite-plugin-upstart-editor/runtime/index.js",
|
|
43
|
+
"./vite-plugin-upstart-editor/runtime/click-handler": "./dist/vite-plugin-upstart-editor/runtime/click-handler.js",
|
|
44
|
+
"./vite-plugin-upstart-editor/runtime/hover-overlay": "./dist/vite-plugin-upstart-editor/runtime/hover-overlay.js",
|
|
45
|
+
"./vite-plugin-upstart-editor/runtime/text-editor": "./dist/vite-plugin-upstart-editor/runtime/text-editor.js",
|
|
46
|
+
"./vite-plugin-upstart-editor/runtime/types": "./dist/vite-plugin-upstart-editor/runtime/types.js",
|
|
47
|
+
"./vite-plugin-upstart-editor/runtime/utils": "./dist/vite-plugin-upstart-editor/runtime/utils.js",
|
|
48
|
+
"./vite-plugin-upstart-theme": "./dist/vite-plugin-upstart-theme.js",
|
|
49
|
+
"./package.json": "./package.json"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@upstart.gg/sdk": "^0.0.37"
|
|
53
|
+
},
|
|
54
|
+
"author": "Upstart",
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"test": "vitest --run",
|
|
60
|
+
"test:bun": "bun test",
|
|
61
|
+
"build": "tsdown"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* biome-ignore lint: test fixture */
|
|
3
|
+
import { definePageAttributes } from "@upstart.gg/sdk";
|
|
4
|
+
|
|
5
|
+
export const attributes = definePageAttributes({
|
|
6
|
+
path: "/contact",
|
|
7
|
+
label: "Contact Us",
|
|
8
|
+
title: "Contact Our Team",
|
|
9
|
+
description: "Get in touch with our team",
|
|
10
|
+
keywords: "contact, email, support",
|
|
11
|
+
layout: "sidebar",
|
|
12
|
+
tags: ["navbar", "important"],
|
|
13
|
+
robotsIndexing: true,
|
|
14
|
+
language: "en",
|
|
15
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* biome-ignore lint: test fixture */
|
|
3
|
+
import { definePageAttributes } from "@upstart.gg/sdk";
|
|
4
|
+
|
|
5
|
+
export const attributes = definePageAttributes({
|
|
6
|
+
path: "/services",
|
|
7
|
+
label: "Services",
|
|
8
|
+
title: "Our Services",
|
|
9
|
+
layout: "default",
|
|
10
|
+
description: "Check out our services",
|
|
11
|
+
tags: ["navbar", "featured"],
|
|
12
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* biome-ignore lint: test fixture */
|
|
3
|
+
import { definePageAttributes } from "@upstart.gg/sdk";
|
|
4
|
+
|
|
5
|
+
export const attributes = definePageAttributes({
|
|
6
|
+
path: "/advanced",
|
|
7
|
+
label: "Advanced Page",
|
|
8
|
+
title: "Advanced Features",
|
|
9
|
+
layout: "default",
|
|
10
|
+
tags: ["admin", "advanced"],
|
|
11
|
+
additionalTags: {
|
|
12
|
+
headTags: "<meta name='custom' content='value' />",
|
|
13
|
+
bodyTags: "<script>console.log('test')</script>",
|
|
14
|
+
},
|
|
15
|
+
});
|