@farming-labs/docs 0.0.14 → 0.0.16
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/cli/index.mjs +246 -26
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -214,6 +214,49 @@ const THEME_INFO = {
|
|
|
214
214
|
function getThemeInfo(theme) {
|
|
215
215
|
return THEME_INFO[theme] ?? THEME_INFO.fumadocs;
|
|
216
216
|
}
|
|
217
|
+
function getThemeExportName(themeName) {
|
|
218
|
+
const base = themeName.replace(/\.ts$/i, "").trim();
|
|
219
|
+
if (!base) return "customTheme";
|
|
220
|
+
return base.replace(/-([a-z])/g, (_, c) => c.toUpperCase()).replace(/^./, (c) => c.toLowerCase());
|
|
221
|
+
}
|
|
222
|
+
function getCustomThemeCssImportPath(globalCssRelPath, themeName) {
|
|
223
|
+
if (globalCssRelPath.startsWith("app/")) return `../themes/${themeName}.css`;
|
|
224
|
+
if (globalCssRelPath.startsWith("src/")) return `../../themes/${themeName}.css`;
|
|
225
|
+
return `../themes/${themeName}.css`;
|
|
226
|
+
}
|
|
227
|
+
/** Content for themes/{name}.ts - createTheme with the given name */
|
|
228
|
+
function customThemeTsTemplate(themeName) {
|
|
229
|
+
return `\
|
|
230
|
+
import { createTheme } from "@farming-labs/docs";
|
|
231
|
+
|
|
232
|
+
export const ${getThemeExportName(themeName)} = createTheme({
|
|
233
|
+
name: "${themeName.replace(/\.ts$/i, "")}",
|
|
234
|
+
ui: {
|
|
235
|
+
colors: {
|
|
236
|
+
primary: "#e11d48",
|
|
237
|
+
background: "#09090b",
|
|
238
|
+
foreground: "#fafafa",
|
|
239
|
+
muted: "#71717a",
|
|
240
|
+
border: "#27272a",
|
|
241
|
+
},
|
|
242
|
+
radius: "0.5rem",
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
function customThemeCssTemplate(themeName) {
|
|
248
|
+
return `\
|
|
249
|
+
/* Custom theme: ${themeName} - edit variables and selectors as needed */
|
|
250
|
+
@import "@farming-labs/theme/presets/black";
|
|
251
|
+
|
|
252
|
+
.dark {
|
|
253
|
+
--color-fd-primary: #e11d48;
|
|
254
|
+
--color-fd-background: #09090b;
|
|
255
|
+
--color-fd-border: #27272a;
|
|
256
|
+
--radius: 0.5rem;
|
|
257
|
+
}
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
217
260
|
/** Config import for Next.js app/layout.tsx → root docs.config */
|
|
218
261
|
function nextRootLayoutConfigImport(useAlias) {
|
|
219
262
|
return useAlias ? "@/docs.config" : "../docs.config";
|
|
@@ -250,6 +293,27 @@ function astroPageServerImport(useAlias, depth) {
|
|
|
250
293
|
return `${"../".repeat(depth)}lib/docs.server`;
|
|
251
294
|
}
|
|
252
295
|
function docsConfigTemplate(cfg) {
|
|
296
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
297
|
+
const exportName = getThemeExportName(cfg.customThemeName);
|
|
298
|
+
return `\
|
|
299
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
300
|
+
import { ${exportName} } from "${cfg.useAlias ? "@/themes/" + cfg.customThemeName.replace(/\.ts$/i, "") : "./themes/" + cfg.customThemeName.replace(/\.ts$/i, "")}";
|
|
301
|
+
|
|
302
|
+
export default defineDocs({
|
|
303
|
+
entry: "${cfg.entry}",
|
|
304
|
+
theme: ${exportName}({
|
|
305
|
+
ui: {
|
|
306
|
+
colors: { primary: "#6366f1" },
|
|
307
|
+
},
|
|
308
|
+
}),
|
|
309
|
+
|
|
310
|
+
metadata: {
|
|
311
|
+
titleTemplate: "%s – ${cfg.projectName}",
|
|
312
|
+
description: "Documentation for ${cfg.projectName}",
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
253
317
|
const t = getThemeInfo(cfg.theme);
|
|
254
318
|
return `\
|
|
255
319
|
import { defineDocs } from "@farming-labs/docs";
|
|
@@ -354,16 +418,21 @@ function injectRootProviderIntoLayout(content) {
|
|
|
354
418
|
}
|
|
355
419
|
return out === content ? null : out;
|
|
356
420
|
}
|
|
357
|
-
function globalCssTemplate(theme) {
|
|
421
|
+
function globalCssTemplate(theme, customThemeName, globalCssRelPath) {
|
|
422
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `\
|
|
423
|
+
@import "tailwindcss";
|
|
424
|
+
@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";
|
|
425
|
+
`;
|
|
358
426
|
return `\
|
|
359
427
|
@import "tailwindcss";
|
|
360
428
|
@import "@farming-labs/theme/${getThemeInfo(theme).nextCssImport}/css";
|
|
361
429
|
`;
|
|
362
430
|
}
|
|
363
|
-
function injectCssImport(existingContent, theme) {
|
|
364
|
-
const importLine = `@import "@farming-labs/theme/${getThemeInfo(theme).nextCssImport}/css";`;
|
|
431
|
+
function injectCssImport(existingContent, theme, customThemeName, globalCssRelPath) {
|
|
432
|
+
const importLine = theme === "custom" && customThemeName && globalCssRelPath ? `@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";` : `@import "@farming-labs/theme/${getThemeInfo(theme).nextCssImport}/css";`;
|
|
365
433
|
if (existingContent.includes(importLine)) return null;
|
|
366
|
-
if (existingContent.includes("@farming-labs/theme/") && existingContent.includes("/css")) return null;
|
|
434
|
+
if (theme !== "custom" && existingContent.includes("@farming-labs/theme/") && existingContent.includes("/css")) return null;
|
|
435
|
+
if (theme === "custom" && existingContent.includes("themes/") && existingContent.includes(".css")) return null;
|
|
367
436
|
const lines = existingContent.split("\n");
|
|
368
437
|
const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
|
|
369
438
|
if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
|
|
@@ -602,6 +671,34 @@ Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
|
602
671
|
`;
|
|
603
672
|
}
|
|
604
673
|
function svelteDocsConfigTemplate(cfg) {
|
|
674
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
675
|
+
const exportName = getThemeExportName(cfg.customThemeName);
|
|
676
|
+
return `\
|
|
677
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
678
|
+
import { ${exportName} } from "${"../../themes/" + cfg.customThemeName.replace(/\.ts$/i, "")}";
|
|
679
|
+
|
|
680
|
+
export default defineDocs({
|
|
681
|
+
entry: "${cfg.entry}",
|
|
682
|
+
theme: ${exportName}({
|
|
683
|
+
ui: {
|
|
684
|
+
colors: { primary: "#6366f1" },
|
|
685
|
+
},
|
|
686
|
+
}),
|
|
687
|
+
|
|
688
|
+
nav: {
|
|
689
|
+
title: "${cfg.projectName}",
|
|
690
|
+
url: "/${cfg.entry}",
|
|
691
|
+
},
|
|
692
|
+
|
|
693
|
+
breadcrumb: { enabled: true },
|
|
694
|
+
|
|
695
|
+
metadata: {
|
|
696
|
+
titleTemplate: "%s – ${cfg.projectName}",
|
|
697
|
+
description: "Documentation for ${cfg.projectName}",
|
|
698
|
+
},
|
|
699
|
+
});
|
|
700
|
+
`;
|
|
701
|
+
}
|
|
605
702
|
const t = getThemeInfo(cfg.theme);
|
|
606
703
|
return `\
|
|
607
704
|
import { defineDocs } from "@farming-labs/docs";
|
|
@@ -692,17 +789,23 @@ function svelteRootLayoutTemplate(globalCssRelPath) {
|
|
|
692
789
|
{@render children()}
|
|
693
790
|
`;
|
|
694
791
|
}
|
|
695
|
-
function svelteGlobalCssTemplate(theme) {
|
|
792
|
+
function svelteGlobalCssTemplate(theme, customThemeName, globalCssRelPath) {
|
|
793
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `\
|
|
794
|
+
@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";
|
|
795
|
+
`;
|
|
696
796
|
return `\
|
|
697
797
|
@import "@farming-labs/svelte-theme/${theme}/css";
|
|
698
798
|
`;
|
|
699
799
|
}
|
|
700
|
-
function svelteCssImportLine(theme) {
|
|
800
|
+
function svelteCssImportLine(theme, customThemeName, globalCssRelPath) {
|
|
801
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";`;
|
|
701
802
|
return `@import "@farming-labs/svelte-theme/${theme}/css";`;
|
|
702
803
|
}
|
|
703
|
-
function injectSvelteCssImport(existingContent, theme) {
|
|
704
|
-
const importLine = svelteCssImportLine(theme);
|
|
804
|
+
function injectSvelteCssImport(existingContent, theme, customThemeName, globalCssRelPath) {
|
|
805
|
+
const importLine = svelteCssImportLine(theme, customThemeName, globalCssRelPath);
|
|
705
806
|
if (existingContent.includes(importLine)) return null;
|
|
807
|
+
if (theme !== "custom" && existingContent.includes("@farming-labs/svelte-theme/") && existingContent.includes("/css")) return null;
|
|
808
|
+
if (theme === "custom" && existingContent.includes("themes/") && existingContent.includes(".css")) return null;
|
|
706
809
|
const lines = existingContent.split("\n");
|
|
707
810
|
const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
|
|
708
811
|
if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
|
|
@@ -876,6 +979,35 @@ Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
|
876
979
|
`;
|
|
877
980
|
}
|
|
878
981
|
function astroDocsConfigTemplate(cfg) {
|
|
982
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
983
|
+
const exportName = getThemeExportName(cfg.customThemeName);
|
|
984
|
+
return `\
|
|
985
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
986
|
+
import { ${exportName} } from "${"../../themes/" + cfg.customThemeName.replace(/\.ts$/i, "")}";
|
|
987
|
+
|
|
988
|
+
export default defineDocs({
|
|
989
|
+
entry: "${cfg.entry}",
|
|
990
|
+
contentDir: "${cfg.entry}",
|
|
991
|
+
theme: ${exportName}({
|
|
992
|
+
ui: {
|
|
993
|
+
colors: { primary: "#6366f1" },
|
|
994
|
+
},
|
|
995
|
+
}),
|
|
996
|
+
|
|
997
|
+
nav: {
|
|
998
|
+
title: "${cfg.projectName}",
|
|
999
|
+
url: "/${cfg.entry}",
|
|
1000
|
+
},
|
|
1001
|
+
|
|
1002
|
+
breadcrumb: { enabled: true },
|
|
1003
|
+
|
|
1004
|
+
metadata: {
|
|
1005
|
+
titleTemplate: "%s – ${cfg.projectName}",
|
|
1006
|
+
description: "Documentation for ${cfg.projectName}",
|
|
1007
|
+
},
|
|
1008
|
+
});
|
|
1009
|
+
`;
|
|
1010
|
+
}
|
|
879
1011
|
const t = getThemeInfo(cfg.theme);
|
|
880
1012
|
return `\
|
|
881
1013
|
import { defineDocs } from "@farming-labs/docs";
|
|
@@ -1025,17 +1157,23 @@ export const POST: APIRoute = async ({ request }) => {
|
|
|
1025
1157
|
};
|
|
1026
1158
|
`;
|
|
1027
1159
|
}
|
|
1028
|
-
function astroGlobalCssTemplate(theme) {
|
|
1160
|
+
function astroGlobalCssTemplate(theme, customThemeName, globalCssRelPath) {
|
|
1161
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `\
|
|
1162
|
+
@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";
|
|
1163
|
+
`;
|
|
1029
1164
|
return `\
|
|
1030
1165
|
@import "@farming-labs/astro-theme/${theme}/css";
|
|
1031
1166
|
`;
|
|
1032
1167
|
}
|
|
1033
|
-
function astroCssImportLine(theme) {
|
|
1168
|
+
function astroCssImportLine(theme, customThemeName, globalCssRelPath) {
|
|
1169
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";`;
|
|
1034
1170
|
return `@import "@farming-labs/astro-theme/${theme}/css";`;
|
|
1035
1171
|
}
|
|
1036
|
-
function injectAstroCssImport(existingContent, theme) {
|
|
1037
|
-
const importLine = astroCssImportLine(theme);
|
|
1172
|
+
function injectAstroCssImport(existingContent, theme, customThemeName, globalCssRelPath) {
|
|
1173
|
+
const importLine = astroCssImportLine(theme, customThemeName, globalCssRelPath);
|
|
1038
1174
|
if (existingContent.includes(importLine)) return null;
|
|
1175
|
+
if (theme !== "custom" && existingContent.includes("@farming-labs/astro-theme/") && existingContent.includes("/css")) return null;
|
|
1176
|
+
if (theme === "custom" && existingContent.includes("themes/") && existingContent.includes(".css")) return null;
|
|
1039
1177
|
const lines = existingContent.split("\n");
|
|
1040
1178
|
const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
|
|
1041
1179
|
if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
|
|
@@ -1197,6 +1335,35 @@ Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
|
1197
1335
|
`;
|
|
1198
1336
|
}
|
|
1199
1337
|
function nuxtDocsConfigTemplate(cfg) {
|
|
1338
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
1339
|
+
const exportName = getThemeExportName(cfg.customThemeName);
|
|
1340
|
+
return `\
|
|
1341
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
1342
|
+
import { ${exportName} } from "${cfg.useAlias ? "~/themes/" + cfg.customThemeName.replace(/\.ts$/i, "") : "./themes/" + cfg.customThemeName.replace(/\.ts$/i, "")}";
|
|
1343
|
+
|
|
1344
|
+
export default defineDocs({
|
|
1345
|
+
entry: "${cfg.entry}",
|
|
1346
|
+
contentDir: "${cfg.entry}",
|
|
1347
|
+
theme: ${exportName}({
|
|
1348
|
+
ui: {
|
|
1349
|
+
colors: { primary: "#6366f1" },
|
|
1350
|
+
},
|
|
1351
|
+
}),
|
|
1352
|
+
|
|
1353
|
+
nav: {
|
|
1354
|
+
title: "${cfg.projectName}",
|
|
1355
|
+
url: "/${cfg.entry}",
|
|
1356
|
+
},
|
|
1357
|
+
|
|
1358
|
+
breadcrumb: { enabled: true },
|
|
1359
|
+
|
|
1360
|
+
metadata: {
|
|
1361
|
+
titleTemplate: "%s – ${cfg.projectName}",
|
|
1362
|
+
description: "Documentation for ${cfg.projectName}",
|
|
1363
|
+
},
|
|
1364
|
+
});
|
|
1365
|
+
`;
|
|
1366
|
+
}
|
|
1200
1367
|
const t = getThemeInfo(cfg.theme);
|
|
1201
1368
|
return `\
|
|
1202
1369
|
import { defineDocs } from "@farming-labs/docs";
|
|
@@ -1360,7 +1527,7 @@ This documentation was generated by \`@farming-labs/docs\`. Edit the markdown fi
|
|
|
1360
1527
|
- **Markdown Support** — Write docs with standard Markdown
|
|
1361
1528
|
- **Syntax Highlighting** — Code blocks with automatic highlighting
|
|
1362
1529
|
- **Dark Mode** — Built-in theme switching
|
|
1363
|
-
- **Search** — Full-text search across all pages (⌘K)
|
|
1530
|
+
- **Search** — Full-text search across all pages (⌘ K)
|
|
1364
1531
|
- **Responsive** — Works on any screen size
|
|
1365
1532
|
|
|
1366
1533
|
---
|
|
@@ -1496,17 +1663,23 @@ pnpm build
|
|
|
1496
1663
|
Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
1497
1664
|
`;
|
|
1498
1665
|
}
|
|
1499
|
-
function nuxtGlobalCssTemplate(theme) {
|
|
1666
|
+
function nuxtGlobalCssTemplate(theme, customThemeName, globalCssRelPath) {
|
|
1667
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `\
|
|
1668
|
+
@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";
|
|
1669
|
+
`;
|
|
1500
1670
|
return `\
|
|
1501
1671
|
@import "@farming-labs/nuxt-theme/${theme}/css";
|
|
1502
1672
|
`;
|
|
1503
1673
|
}
|
|
1504
|
-
function nuxtCssImportLine(theme) {
|
|
1674
|
+
function nuxtCssImportLine(theme, customThemeName, globalCssRelPath) {
|
|
1675
|
+
if (theme === "custom" && customThemeName && globalCssRelPath) return `@import "${getCustomThemeCssImportPath(globalCssRelPath, customThemeName.replace(/\.css$/i, ""))}";`;
|
|
1505
1676
|
return `@import "@farming-labs/nuxt-theme/${theme}/css";`;
|
|
1506
1677
|
}
|
|
1507
|
-
function injectNuxtCssImport(existingContent, theme) {
|
|
1508
|
-
const importLine = nuxtCssImportLine(theme);
|
|
1678
|
+
function injectNuxtCssImport(existingContent, theme, customThemeName, globalCssRelPath) {
|
|
1679
|
+
const importLine = nuxtCssImportLine(theme, customThemeName, globalCssRelPath);
|
|
1509
1680
|
if (existingContent.includes(importLine)) return null;
|
|
1681
|
+
if (theme !== "custom" && existingContent.includes("@farming-labs/nuxt-theme/") && existingContent.includes("/css")) return null;
|
|
1682
|
+
if (theme === "custom" && existingContent.includes("themes/") && existingContent.includes(".css")) return null;
|
|
1510
1683
|
const lines = existingContent.split("\n");
|
|
1511
1684
|
const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
|
|
1512
1685
|
if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
|
|
@@ -1649,6 +1822,11 @@ async function init(options = {}) {
|
|
|
1649
1822
|
value: "greentree",
|
|
1650
1823
|
label: "GreenTree",
|
|
1651
1824
|
hint: "Emerald green accent, Inter font, Mintlify-inspired"
|
|
1825
|
+
},
|
|
1826
|
+
{
|
|
1827
|
+
value: "custom",
|
|
1828
|
+
label: "Create your own theme",
|
|
1829
|
+
hint: "Scaffold a new theme file + CSS in themes/ (name asked next)"
|
|
1652
1830
|
}
|
|
1653
1831
|
]
|
|
1654
1832
|
});
|
|
@@ -1656,6 +1834,26 @@ async function init(options = {}) {
|
|
|
1656
1834
|
p.outro(pc.red("Init cancelled."));
|
|
1657
1835
|
process.exit(0);
|
|
1658
1836
|
}
|
|
1837
|
+
let customThemeName;
|
|
1838
|
+
if (theme === "custom") {
|
|
1839
|
+
const nameAnswer = await p.text({
|
|
1840
|
+
message: "Theme name? (we'll create themes/<name>.ts and themes/<name>.css)",
|
|
1841
|
+
placeholder: "my-theme",
|
|
1842
|
+
defaultValue: "my-theme",
|
|
1843
|
+
validate: (value) => {
|
|
1844
|
+
const v = (value ?? "").trim().replace(/\.(ts|css)$/i, "");
|
|
1845
|
+
if (!v) return "Theme name is required";
|
|
1846
|
+
if (v.includes("/") || v.includes("\\")) return "Theme name cannot contain path separators";
|
|
1847
|
+
if (v.includes(" ")) return "Theme name cannot contain spaces";
|
|
1848
|
+
if (!/^[a-z0-9_-]+$/i.test(v)) return "Use only letters, numbers, hyphens, and underscores";
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
if (p.isCancel(nameAnswer)) {
|
|
1852
|
+
p.outro(pc.red("Init cancelled."));
|
|
1853
|
+
process.exit(0);
|
|
1854
|
+
}
|
|
1855
|
+
customThemeName = nameAnswer.trim().replace(/\.(ts|css)$/i, "");
|
|
1856
|
+
}
|
|
1659
1857
|
const aliasHint = framework === "nextjs" ? `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)` : framework === "sveltekit" ? `Uses ${pc.cyan("$lib/")} prefix (SvelteKit built-in)` : framework === "nuxt" ? `Uses ${pc.cyan("~/")} prefix (Nuxt built-in)` : `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)`;
|
|
1660
1858
|
const useAlias = await p.confirm({
|
|
1661
1859
|
message: `Use path aliases for imports? ${pc.dim(aliasHint)}`,
|
|
@@ -1748,10 +1946,12 @@ async function init(options = {}) {
|
|
|
1748
1946
|
}
|
|
1749
1947
|
const pkgJsonContent = readFileSafe(path.join(cwd, "package.json"));
|
|
1750
1948
|
const pkgJson = pkgJsonContent ? JSON.parse(pkgJsonContent) : { name: "my-project" };
|
|
1949
|
+
const projectName = pkgJson.name || "My Project";
|
|
1751
1950
|
const cfg = {
|
|
1752
1951
|
entry: entryPath,
|
|
1753
1952
|
theme,
|
|
1754
|
-
|
|
1953
|
+
customThemeName,
|
|
1954
|
+
projectName,
|
|
1755
1955
|
framework,
|
|
1756
1956
|
useAlias,
|
|
1757
1957
|
astroAdapter
|
|
@@ -1864,6 +2064,11 @@ async function init(options = {}) {
|
|
|
1864
2064
|
}
|
|
1865
2065
|
}
|
|
1866
2066
|
function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
2067
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
2068
|
+
const baseName = cfg.customThemeName.replace(/\.(ts|css)$/i, "");
|
|
2069
|
+
write(`themes/${baseName}.ts`, customThemeTsTemplate(baseName));
|
|
2070
|
+
write(`themes/${baseName}.css`, customThemeCssTemplate(baseName));
|
|
2071
|
+
}
|
|
1867
2072
|
write("docs.config.ts", docsConfigTemplate(cfg));
|
|
1868
2073
|
const existingNextConfig = readFileSafe(path.join(cwd, "next.config.ts")) ?? readFileSafe(path.join(cwd, "next.config.mjs")) ?? readFileSafe(path.join(cwd, "next.config.js"));
|
|
1869
2074
|
if (existingNextConfig) {
|
|
@@ -1887,12 +2092,12 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
1887
2092
|
const globalCssAbsPath = path.join(cwd, globalCssRelPath);
|
|
1888
2093
|
const existingGlobalCss = readFileSafe(globalCssAbsPath);
|
|
1889
2094
|
if (existingGlobalCss) {
|
|
1890
|
-
const injected = injectCssImport(existingGlobalCss, cfg.theme);
|
|
2095
|
+
const injected = injectCssImport(existingGlobalCss, cfg.theme, cfg.customThemeName, globalCssRelPath);
|
|
1891
2096
|
if (injected) {
|
|
1892
2097
|
writeFileSafe(globalCssAbsPath, injected, true);
|
|
1893
2098
|
written.push(globalCssRelPath + " (updated)");
|
|
1894
2099
|
} else skipped.push(globalCssRelPath + " (already configured)");
|
|
1895
|
-
} else write(globalCssRelPath, globalCssTemplate(cfg.theme));
|
|
2100
|
+
} else write(globalCssRelPath, globalCssTemplate(cfg.theme, cfg.customThemeName, globalCssRelPath));
|
|
1896
2101
|
write(`app/${cfg.entry}/layout.tsx`, docsLayoutTemplate(cfg));
|
|
1897
2102
|
write("postcss.config.mjs", postcssConfigTemplate());
|
|
1898
2103
|
if (!fileExists(path.join(cwd, "tsconfig.json"))) write("tsconfig.json", tsconfigTemplate(cfg.useAlias));
|
|
@@ -1901,6 +2106,11 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
1901
2106
|
write(`app/${cfg.entry}/quickstart/page.mdx`, quickstartPageTemplate(cfg));
|
|
1902
2107
|
}
|
|
1903
2108
|
function scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
2109
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
2110
|
+
const baseName = cfg.customThemeName.replace(/\.(ts|css)$/i, "");
|
|
2111
|
+
write(`themes/${baseName}.ts`, customThemeTsTemplate(baseName));
|
|
2112
|
+
write(`themes/${baseName}.css`, customThemeCssTemplate(baseName));
|
|
2113
|
+
}
|
|
1904
2114
|
write("src/lib/docs.config.ts", svelteDocsConfigTemplate(cfg));
|
|
1905
2115
|
write("src/lib/docs.server.ts", svelteDocsServerTemplate(cfg));
|
|
1906
2116
|
write(`src/routes/${cfg.entry}/+layout.svelte`, svelteDocsLayoutTemplate(cfg));
|
|
@@ -1920,17 +2130,22 @@ function scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written)
|
|
|
1920
2130
|
default: "fumadocs"
|
|
1921
2131
|
}[cfg.theme] || "fumadocs";
|
|
1922
2132
|
if (existingGlobalCss) {
|
|
1923
|
-
const injected = injectSvelteCssImport(existingGlobalCss, cssTheme);
|
|
2133
|
+
const injected = cfg.theme === "custom" && cfg.customThemeName ? injectSvelteCssImport(existingGlobalCss, "custom", cfg.customThemeName, globalCssRelPath) : injectSvelteCssImport(existingGlobalCss, cssTheme);
|
|
1924
2134
|
if (injected) {
|
|
1925
2135
|
writeFileSafe(globalCssAbsPath, injected, true);
|
|
1926
2136
|
written.push(globalCssRelPath + " (updated)");
|
|
1927
2137
|
} else skipped.push(globalCssRelPath + " (already configured)");
|
|
1928
|
-
} else write(globalCssRelPath, svelteGlobalCssTemplate(cssTheme));
|
|
2138
|
+
} else write(globalCssRelPath, cfg.theme === "custom" && cfg.customThemeName ? svelteGlobalCssTemplate("custom", cfg.customThemeName, globalCssRelPath) : svelteGlobalCssTemplate(cssTheme));
|
|
1929
2139
|
write(`${cfg.entry}/page.md`, svelteWelcomePageTemplate(cfg));
|
|
1930
2140
|
write(`${cfg.entry}/installation/page.md`, svelteInstallationPageTemplate(cfg));
|
|
1931
2141
|
write(`${cfg.entry}/quickstart/page.md`, svelteQuickstartPageTemplate(cfg));
|
|
1932
2142
|
}
|
|
1933
2143
|
function scaffoldAstro(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
2144
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
2145
|
+
const baseName = cfg.customThemeName.replace(/\.(ts|css)$/i, "");
|
|
2146
|
+
write(`themes/${baseName}.ts`, customThemeTsTemplate(baseName));
|
|
2147
|
+
write(`themes/${baseName}.css`, customThemeCssTemplate(baseName));
|
|
2148
|
+
}
|
|
1934
2149
|
write("src/lib/docs.config.ts", astroDocsConfigTemplate(cfg));
|
|
1935
2150
|
write("src/lib/docs.server.ts", astroDocsServerTemplate(cfg));
|
|
1936
2151
|
if (!fileExists(path.join(cwd, "astro.config.mjs")) && !fileExists(path.join(cwd, "astro.config.ts"))) write("astro.config.mjs", astroConfigTemplate(cfg.astroAdapter ?? "vercel"));
|
|
@@ -1950,17 +2165,22 @@ function scaffoldAstro(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
1950
2165
|
default: "fumadocs"
|
|
1951
2166
|
}[cfg.theme] || "fumadocs";
|
|
1952
2167
|
if (existingGlobalCss) {
|
|
1953
|
-
const injected = injectAstroCssImport(existingGlobalCss, cssTheme);
|
|
2168
|
+
const injected = cfg.theme === "custom" && cfg.customThemeName ? injectAstroCssImport(existingGlobalCss, "custom", cfg.customThemeName, globalCssRelPath) : injectAstroCssImport(existingGlobalCss, cssTheme);
|
|
1954
2169
|
if (injected) {
|
|
1955
2170
|
writeFileSafe(globalCssAbsPath, injected, true);
|
|
1956
2171
|
written.push(globalCssRelPath + " (updated)");
|
|
1957
2172
|
} else skipped.push(globalCssRelPath + " (already configured)");
|
|
1958
|
-
} else write(globalCssRelPath, astroGlobalCssTemplate(cssTheme));
|
|
2173
|
+
} else write(globalCssRelPath, cfg.theme === "custom" && cfg.customThemeName ? astroGlobalCssTemplate("custom", cfg.customThemeName, globalCssRelPath) : astroGlobalCssTemplate(cssTheme));
|
|
1959
2174
|
write(`${cfg.entry}/page.md`, astroWelcomePageTemplate(cfg));
|
|
1960
2175
|
write(`${cfg.entry}/installation/page.md`, astroInstallationPageTemplate(cfg));
|
|
1961
2176
|
write(`${cfg.entry}/quickstart/page.md`, astroQuickstartPageTemplate(cfg));
|
|
1962
2177
|
}
|
|
1963
2178
|
function scaffoldNuxt(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
2179
|
+
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
2180
|
+
const baseName = cfg.customThemeName.replace(/\.(ts|css)$/i, "");
|
|
2181
|
+
write(`themes/${baseName}.ts`, customThemeTsTemplate(baseName));
|
|
2182
|
+
write(`themes/${baseName}.css`, customThemeCssTemplate(baseName));
|
|
2183
|
+
}
|
|
1964
2184
|
write("docs.config.ts", nuxtDocsConfigTemplate(cfg));
|
|
1965
2185
|
write("server/utils/docs-server.ts", nuxtDocsServerTemplate(cfg));
|
|
1966
2186
|
write("server/api/docs.get.ts", nuxtServerApiDocsGetTemplate());
|
|
@@ -1982,12 +2202,12 @@ function scaffoldNuxt(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
1982
2202
|
const globalCssAbsPath = path.join(cwd, globalCssRelPath);
|
|
1983
2203
|
const existingGlobalCss = readFileSafe(globalCssAbsPath);
|
|
1984
2204
|
if (existingGlobalCss) {
|
|
1985
|
-
const injected = injectNuxtCssImport(existingGlobalCss, cssTheme);
|
|
2205
|
+
const injected = cfg.theme === "custom" && cfg.customThemeName ? injectNuxtCssImport(existingGlobalCss, "custom", cfg.customThemeName, globalCssRelPath) : injectNuxtCssImport(existingGlobalCss, cssTheme);
|
|
1986
2206
|
if (injected) {
|
|
1987
2207
|
writeFileSafe(globalCssAbsPath, injected, true);
|
|
1988
2208
|
written.push(globalCssRelPath + " (updated)");
|
|
1989
2209
|
} else skipped.push(globalCssRelPath + " (already configured)");
|
|
1990
|
-
} else write(globalCssRelPath, nuxtGlobalCssTemplate(cssTheme));
|
|
2210
|
+
} else write(globalCssRelPath, cfg.theme === "custom" && cfg.customThemeName ? nuxtGlobalCssTemplate("custom", cfg.customThemeName, globalCssRelPath) : nuxtGlobalCssTemplate(cssTheme));
|
|
1991
2211
|
write(`${cfg.entry}/page.md`, nuxtWelcomePageTemplate(cfg));
|
|
1992
2212
|
write(`${cfg.entry}/installation/page.md`, nuxtInstallationPageTemplate(cfg));
|
|
1993
2213
|
write(`${cfg.entry}/quickstart/page.md`, nuxtQuickstartPageTemplate(cfg));
|