@farming-labs/docs 0.0.2-beta.14 → 0.0.2-beta.15
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 +433 -20
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -16,6 +16,7 @@ function detectFramework(cwd) {
|
|
|
16
16
|
};
|
|
17
17
|
if (allDeps["next"]) return "nextjs";
|
|
18
18
|
if (allDeps["@sveltejs/kit"]) return "sveltekit";
|
|
19
|
+
if (allDeps["astro"]) return "astro";
|
|
19
20
|
return null;
|
|
20
21
|
}
|
|
21
22
|
function detectPackageManager(cwd) {
|
|
@@ -133,22 +134,28 @@ const THEME_INFO = {
|
|
|
133
134
|
factory: "fumadocs",
|
|
134
135
|
nextImport: "@farming-labs/theme",
|
|
135
136
|
svelteImport: "@farming-labs/svelte-theme",
|
|
137
|
+
astroImport: "@farming-labs/astro-theme",
|
|
136
138
|
nextCssImport: "default",
|
|
137
|
-
svelteCssTheme: "fumadocs"
|
|
139
|
+
svelteCssTheme: "fumadocs",
|
|
140
|
+
astroCssTheme: "fumadocs"
|
|
138
141
|
},
|
|
139
142
|
darksharp: {
|
|
140
143
|
factory: "darksharp",
|
|
141
144
|
nextImport: "@farming-labs/theme/darksharp",
|
|
142
145
|
svelteImport: "@farming-labs/svelte-theme/darksharp",
|
|
146
|
+
astroImport: "@farming-labs/astro-theme/darksharp",
|
|
143
147
|
nextCssImport: "darksharp",
|
|
144
|
-
svelteCssTheme: "darksharp"
|
|
148
|
+
svelteCssTheme: "darksharp",
|
|
149
|
+
astroCssTheme: "darksharp"
|
|
145
150
|
},
|
|
146
151
|
"pixel-border": {
|
|
147
152
|
factory: "pixelBorder",
|
|
148
153
|
nextImport: "@farming-labs/theme/pixel-border",
|
|
149
154
|
svelteImport: "@farming-labs/svelte-theme/pixel-border",
|
|
155
|
+
astroImport: "@farming-labs/astro-theme/pixel-border",
|
|
150
156
|
nextCssImport: "pixel-border",
|
|
151
|
-
svelteCssTheme: "pixel-border"
|
|
157
|
+
svelteCssTheme: "pixel-border",
|
|
158
|
+
astroCssTheme: "pixel-border"
|
|
152
159
|
}
|
|
153
160
|
};
|
|
154
161
|
function getThemeInfo(theme) {
|
|
@@ -178,6 +185,17 @@ function sveltePageConfigImport(useAlias) {
|
|
|
178
185
|
function svelteLayoutServerImport(useAlias) {
|
|
179
186
|
return useAlias ? "$lib/docs.server" : "../../lib/docs.server";
|
|
180
187
|
}
|
|
188
|
+
function astroServerConfigImport(useAlias) {
|
|
189
|
+
return useAlias ? "@/lib/docs.config" : "./docs.config";
|
|
190
|
+
}
|
|
191
|
+
function astroPageConfigImport(useAlias, depth) {
|
|
192
|
+
if (useAlias) return "@/lib/docs.config";
|
|
193
|
+
return `${"../".repeat(depth)}lib/docs.config`;
|
|
194
|
+
}
|
|
195
|
+
function astroPageServerImport(useAlias, depth) {
|
|
196
|
+
if (useAlias) return "@/lib/docs.server";
|
|
197
|
+
return `${"../".repeat(depth)}lib/docs.server`;
|
|
198
|
+
}
|
|
181
199
|
function docsConfigTemplate(cfg) {
|
|
182
200
|
const t = getThemeInfo(cfg.theme);
|
|
183
201
|
return `\
|
|
@@ -765,6 +783,327 @@ Build your docs for production:
|
|
|
765
783
|
pnpm build
|
|
766
784
|
\`\`\`
|
|
767
785
|
|
|
786
|
+
Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
787
|
+
`;
|
|
788
|
+
}
|
|
789
|
+
function astroDocsConfigTemplate(cfg) {
|
|
790
|
+
const t = getThemeInfo(cfg.theme);
|
|
791
|
+
return `\
|
|
792
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
793
|
+
import { ${t.factory} } from "${t.astroImport}";
|
|
794
|
+
|
|
795
|
+
export default defineDocs({
|
|
796
|
+
entry: "${cfg.entry}",
|
|
797
|
+
contentDir: "${cfg.entry}",
|
|
798
|
+
theme: ${t.factory}({
|
|
799
|
+
ui: {
|
|
800
|
+
colors: { primary: "#6366f1" },
|
|
801
|
+
},
|
|
802
|
+
}),
|
|
803
|
+
|
|
804
|
+
nav: {
|
|
805
|
+
title: "${cfg.projectName}",
|
|
806
|
+
url: "/${cfg.entry}",
|
|
807
|
+
},
|
|
808
|
+
|
|
809
|
+
breadcrumb: { enabled: true },
|
|
810
|
+
|
|
811
|
+
metadata: {
|
|
812
|
+
titleTemplate: "%s – ${cfg.projectName}",
|
|
813
|
+
description: "Documentation for ${cfg.projectName}",
|
|
814
|
+
},
|
|
815
|
+
});
|
|
816
|
+
`;
|
|
817
|
+
}
|
|
818
|
+
function astroDocsServerTemplate(cfg) {
|
|
819
|
+
return `\
|
|
820
|
+
import { createDocsServer } from "@farming-labs/astro/server";
|
|
821
|
+
import config from "${astroServerConfigImport(cfg.useAlias)}";
|
|
822
|
+
|
|
823
|
+
const contentFiles = import.meta.glob("/${cfg.entry ?? "docs"}/**/*.{md,mdx}", {
|
|
824
|
+
query: "?raw",
|
|
825
|
+
import: "default",
|
|
826
|
+
eager: true,
|
|
827
|
+
}) as Record<string, string>;
|
|
828
|
+
|
|
829
|
+
export const { load, GET, POST } = createDocsServer({
|
|
830
|
+
...config,
|
|
831
|
+
_preloadedContent: contentFiles,
|
|
832
|
+
});
|
|
833
|
+
`;
|
|
834
|
+
}
|
|
835
|
+
const ASTRO_ADAPTER_INFO = {
|
|
836
|
+
vercel: {
|
|
837
|
+
pkg: "@astrojs/vercel",
|
|
838
|
+
import: "@astrojs/vercel"
|
|
839
|
+
},
|
|
840
|
+
netlify: {
|
|
841
|
+
pkg: "@astrojs/netlify",
|
|
842
|
+
import: "@astrojs/netlify"
|
|
843
|
+
},
|
|
844
|
+
node: {
|
|
845
|
+
pkg: "@astrojs/node",
|
|
846
|
+
import: "@astrojs/node"
|
|
847
|
+
},
|
|
848
|
+
cloudflare: {
|
|
849
|
+
pkg: "@astrojs/cloudflare",
|
|
850
|
+
import: "@astrojs/cloudflare"
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
function getAstroAdapterPkg(adapter) {
|
|
854
|
+
return ASTRO_ADAPTER_INFO[adapter]?.pkg ?? ASTRO_ADAPTER_INFO.vercel.pkg;
|
|
855
|
+
}
|
|
856
|
+
function astroConfigTemplate(adapter = "vercel") {
|
|
857
|
+
const info = ASTRO_ADAPTER_INFO[adapter] ?? ASTRO_ADAPTER_INFO.vercel;
|
|
858
|
+
const adapterCall = adapter === "node" ? `${adapter}({ mode: "standalone" })` : `${adapter}()`;
|
|
859
|
+
return `\
|
|
860
|
+
import { defineConfig } from "astro/config";
|
|
861
|
+
import ${adapter} from "${info.import}";
|
|
862
|
+
|
|
863
|
+
export default defineConfig({
|
|
864
|
+
output: "server",
|
|
865
|
+
adapter: ${adapterCall},
|
|
866
|
+
});
|
|
867
|
+
`;
|
|
868
|
+
}
|
|
869
|
+
function astroDocsPageTemplate(cfg) {
|
|
870
|
+
return `\
|
|
871
|
+
---
|
|
872
|
+
import DocsLayout from "@farming-labs/astro-theme/src/components/DocsLayout.astro";
|
|
873
|
+
import DocsContent from "@farming-labs/astro-theme/src/components/DocsContent.astro";
|
|
874
|
+
import SearchDialog from "@farming-labs/astro-theme/src/components/SearchDialog.astro";
|
|
875
|
+
import config from "${astroPageConfigImport(cfg.useAlias, 2)}";
|
|
876
|
+
import { load } from "${astroPageServerImport(cfg.useAlias, 2)}";
|
|
877
|
+
import "${`@farming-labs/astro-theme/${getThemeInfo(cfg.theme).astroCssTheme}/css`}";
|
|
878
|
+
|
|
879
|
+
const data = await load(Astro.url.pathname);
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
<html lang="en">
|
|
883
|
+
<head>
|
|
884
|
+
<meta charset="utf-8" />
|
|
885
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
886
|
+
<title>{data.title} – Docs</title>
|
|
887
|
+
</head>
|
|
888
|
+
<body>
|
|
889
|
+
<DocsLayout tree={data.tree} config={config}>
|
|
890
|
+
<DocsContent data={data} config={config} />
|
|
891
|
+
</DocsLayout>
|
|
892
|
+
<SearchDialog config={config} />
|
|
893
|
+
</body>
|
|
894
|
+
</html>
|
|
895
|
+
`;
|
|
896
|
+
}
|
|
897
|
+
function astroDocsIndexTemplate(cfg) {
|
|
898
|
+
return `\
|
|
899
|
+
---
|
|
900
|
+
import DocsLayout from "@farming-labs/astro-theme/src/components/DocsLayout.astro";
|
|
901
|
+
import DocsContent from "@farming-labs/astro-theme/src/components/DocsContent.astro";
|
|
902
|
+
import SearchDialog from "@farming-labs/astro-theme/src/components/SearchDialog.astro";
|
|
903
|
+
import config from "${astroPageConfigImport(cfg.useAlias, 2)}";
|
|
904
|
+
import { load } from "${astroPageServerImport(cfg.useAlias, 2)}";
|
|
905
|
+
import "${`@farming-labs/astro-theme/${getThemeInfo(cfg.theme).astroCssTheme}/css`}";
|
|
906
|
+
|
|
907
|
+
const data = await load(Astro.url.pathname);
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
<html lang="en">
|
|
911
|
+
<head>
|
|
912
|
+
<meta charset="utf-8" />
|
|
913
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
914
|
+
<title>{data.title} – Docs</title>
|
|
915
|
+
</head>
|
|
916
|
+
<body>
|
|
917
|
+
<DocsLayout tree={data.tree} config={config}>
|
|
918
|
+
<DocsContent data={data} config={config} />
|
|
919
|
+
</DocsLayout>
|
|
920
|
+
<SearchDialog config={config} />
|
|
921
|
+
</body>
|
|
922
|
+
</html>
|
|
923
|
+
`;
|
|
924
|
+
}
|
|
925
|
+
function astroApiRouteTemplate(cfg) {
|
|
926
|
+
return `\
|
|
927
|
+
import type { APIRoute } from "astro";
|
|
928
|
+
import { GET as docsGET, POST as docsPOST } from "${astroPageServerImport(cfg.useAlias, 2)}";
|
|
929
|
+
|
|
930
|
+
export const GET: APIRoute = async ({ request }) => {
|
|
931
|
+
return docsGET({ request });
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
export const POST: APIRoute = async ({ request }) => {
|
|
935
|
+
return docsPOST({ request });
|
|
936
|
+
};
|
|
937
|
+
`;
|
|
938
|
+
}
|
|
939
|
+
function astroGlobalCssTemplate(theme) {
|
|
940
|
+
return `\
|
|
941
|
+
@import "@farming-labs/astro-theme/${theme}/css";
|
|
942
|
+
`;
|
|
943
|
+
}
|
|
944
|
+
function astroCssImportLine(theme) {
|
|
945
|
+
return `@import "@farming-labs/astro-theme/${theme}/css";`;
|
|
946
|
+
}
|
|
947
|
+
function injectAstroCssImport(existingContent, theme) {
|
|
948
|
+
const importLine = astroCssImportLine(theme);
|
|
949
|
+
if (existingContent.includes(importLine)) return null;
|
|
950
|
+
const lines = existingContent.split("\n");
|
|
951
|
+
const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
|
|
952
|
+
if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
|
|
953
|
+
else lines.unshift(importLine);
|
|
954
|
+
return lines.join("\n");
|
|
955
|
+
}
|
|
956
|
+
function astroWelcomePageTemplate(cfg) {
|
|
957
|
+
return `\
|
|
958
|
+
---
|
|
959
|
+
title: "Documentation"
|
|
960
|
+
description: "Welcome to ${cfg.projectName} documentation"
|
|
961
|
+
---
|
|
962
|
+
|
|
963
|
+
# Welcome to ${cfg.projectName}
|
|
964
|
+
|
|
965
|
+
Get started with our documentation. Browse the pages on the left to learn more.
|
|
966
|
+
|
|
967
|
+
## Overview
|
|
968
|
+
|
|
969
|
+
This documentation was generated by \`@farming-labs/docs\`. Edit the markdown files in \`${cfg.entry}/\` to customize.
|
|
970
|
+
|
|
971
|
+
## Features
|
|
972
|
+
|
|
973
|
+
- **Markdown Support** — Write docs with standard Markdown
|
|
974
|
+
- **Syntax Highlighting** — Code blocks with automatic highlighting
|
|
975
|
+
- **Dark Mode** — Built-in theme switching
|
|
976
|
+
- **Search** — Full-text search across all pages
|
|
977
|
+
- **Responsive** — Works on any screen size
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
## Next Steps
|
|
982
|
+
|
|
983
|
+
Start by reading the [Installation](/${cfg.entry}/installation) guide, then follow the [Quickstart](/${cfg.entry}/quickstart) to build something.
|
|
984
|
+
`;
|
|
985
|
+
}
|
|
986
|
+
function astroInstallationPageTemplate(cfg) {
|
|
987
|
+
const t = getThemeInfo(cfg.theme);
|
|
988
|
+
return `\
|
|
989
|
+
---
|
|
990
|
+
title: "Installation"
|
|
991
|
+
description: "How to install and set up ${cfg.projectName}"
|
|
992
|
+
---
|
|
993
|
+
|
|
994
|
+
# Installation
|
|
995
|
+
|
|
996
|
+
Follow these steps to install and configure ${cfg.projectName}.
|
|
997
|
+
|
|
998
|
+
## Prerequisites
|
|
999
|
+
|
|
1000
|
+
- Node.js 18+
|
|
1001
|
+
- A package manager (pnpm, npm, or yarn)
|
|
1002
|
+
|
|
1003
|
+
## Install Dependencies
|
|
1004
|
+
|
|
1005
|
+
\\\`\\\`\\\`bash
|
|
1006
|
+
pnpm add @farming-labs/docs @farming-labs/astro @farming-labs/astro-theme
|
|
1007
|
+
\\\`\\\`\\\`
|
|
1008
|
+
|
|
1009
|
+
## Configuration
|
|
1010
|
+
|
|
1011
|
+
Your project includes a \\\`docs.config.ts\\\` in \\\`src/lib/\\\`:
|
|
1012
|
+
|
|
1013
|
+
\\\`\\\`\\\`ts title="src/lib/docs.config.ts"
|
|
1014
|
+
import { defineDocs } from "@farming-labs/docs";
|
|
1015
|
+
import { ${t.factory} } from "${t.astroImport}";
|
|
1016
|
+
|
|
1017
|
+
export default defineDocs({
|
|
1018
|
+
entry: "${cfg.entry}",
|
|
1019
|
+
contentDir: "${cfg.entry}",
|
|
1020
|
+
theme: ${t.factory}({
|
|
1021
|
+
ui: { colors: { primary: "#6366f1" } },
|
|
1022
|
+
}),
|
|
1023
|
+
});
|
|
1024
|
+
\\\`\\\`\\\`
|
|
1025
|
+
|
|
1026
|
+
## Project Structure
|
|
1027
|
+
|
|
1028
|
+
\\\`\\\`\\\`
|
|
1029
|
+
${cfg.entry}/ # Markdown content
|
|
1030
|
+
page.md # /${cfg.entry}
|
|
1031
|
+
installation/
|
|
1032
|
+
page.md # /${cfg.entry}/installation
|
|
1033
|
+
quickstart/
|
|
1034
|
+
page.md # /${cfg.entry}/quickstart
|
|
1035
|
+
src/
|
|
1036
|
+
lib/
|
|
1037
|
+
docs.config.ts # Docs configuration
|
|
1038
|
+
docs.server.ts # Server-side docs loader
|
|
1039
|
+
pages/
|
|
1040
|
+
${cfg.entry}/
|
|
1041
|
+
index.astro # Docs index page
|
|
1042
|
+
[...slug].astro # Dynamic doc page
|
|
1043
|
+
api/
|
|
1044
|
+
${cfg.entry}.ts # Search/AI API route
|
|
1045
|
+
\\\`\\\`\\\`
|
|
1046
|
+
|
|
1047
|
+
## What's Next?
|
|
1048
|
+
|
|
1049
|
+
Head to the [Quickstart](/${cfg.entry}/quickstart) guide to start writing your first page.
|
|
1050
|
+
`;
|
|
1051
|
+
}
|
|
1052
|
+
function astroQuickstartPageTemplate(cfg) {
|
|
1053
|
+
const t = getThemeInfo(cfg.theme);
|
|
1054
|
+
return `\
|
|
1055
|
+
---
|
|
1056
|
+
title: "Quickstart"
|
|
1057
|
+
description: "Get up and running in minutes"
|
|
1058
|
+
---
|
|
1059
|
+
|
|
1060
|
+
# Quickstart
|
|
1061
|
+
|
|
1062
|
+
This guide walks you through creating your first documentation page.
|
|
1063
|
+
|
|
1064
|
+
## Creating a Page
|
|
1065
|
+
|
|
1066
|
+
Create a new folder under \\\`${cfg.entry}/\\\` with a \\\`page.md\\\` file:
|
|
1067
|
+
|
|
1068
|
+
\\\`\\\`\\\`bash
|
|
1069
|
+
mkdir -p ${cfg.entry}/my-page
|
|
1070
|
+
\\\`\\\`\\\`
|
|
1071
|
+
|
|
1072
|
+
Then create \\\`${cfg.entry}/my-page/page.md\\\`:
|
|
1073
|
+
|
|
1074
|
+
\\\`\\\`\\\`md
|
|
1075
|
+
---
|
|
1076
|
+
title: "My Page"
|
|
1077
|
+
description: "A custom documentation page"
|
|
1078
|
+
---
|
|
1079
|
+
|
|
1080
|
+
# My Page
|
|
1081
|
+
|
|
1082
|
+
Write your content here using **Markdown**.
|
|
1083
|
+
\\\`\\\`\\\`
|
|
1084
|
+
|
|
1085
|
+
Your page is now available at \\\`/${cfg.entry}/my-page\\\`.
|
|
1086
|
+
|
|
1087
|
+
## Customizing the Theme
|
|
1088
|
+
|
|
1089
|
+
Edit \\\`src/lib/docs.config.ts\\\` to change colors, typography, and component defaults:
|
|
1090
|
+
|
|
1091
|
+
\\\`\\\`\\\`ts title="src/lib/docs.config.ts"
|
|
1092
|
+
theme: ${t.factory}({
|
|
1093
|
+
ui: {
|
|
1094
|
+
colors: { primary: "#22c55e" },
|
|
1095
|
+
},
|
|
1096
|
+
}),
|
|
1097
|
+
\\\`\\\`\\\`
|
|
1098
|
+
|
|
1099
|
+
## Deploying
|
|
1100
|
+
|
|
1101
|
+
Build your docs for production:
|
|
1102
|
+
|
|
1103
|
+
\\\`\\\`\\\`bash
|
|
1104
|
+
pnpm build
|
|
1105
|
+
\\\`\\\`\\\`
|
|
1106
|
+
|
|
768
1107
|
Deploy to Vercel, Netlify, or any Node.js hosting platform.
|
|
769
1108
|
`;
|
|
770
1109
|
}
|
|
@@ -776,21 +1115,29 @@ async function init() {
|
|
|
776
1115
|
p.intro(pc.bgCyan(pc.black(" @farming-labs/docs ")));
|
|
777
1116
|
let framework = detectFramework(cwd);
|
|
778
1117
|
if (framework) {
|
|
779
|
-
const frameworkName = framework === "nextjs" ? "Next.js" : "SvelteKit";
|
|
1118
|
+
const frameworkName = framework === "nextjs" ? "Next.js" : framework === "sveltekit" ? "SvelteKit" : "Astro";
|
|
780
1119
|
p.log.success(`Detected framework: ${pc.cyan(frameworkName)}`);
|
|
781
1120
|
} else {
|
|
782
1121
|
p.log.warn("Could not auto-detect a framework from " + pc.cyan("package.json") + ".");
|
|
783
1122
|
const picked = await p.select({
|
|
784
1123
|
message: "Which framework are you using?",
|
|
785
|
-
options: [
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
1124
|
+
options: [
|
|
1125
|
+
{
|
|
1126
|
+
value: "nextjs",
|
|
1127
|
+
label: "Next.js",
|
|
1128
|
+
hint: "React framework with App Router"
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
value: "sveltekit",
|
|
1132
|
+
label: "SvelteKit",
|
|
1133
|
+
hint: "Svelte framework with file-based routing"
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
value: "astro",
|
|
1137
|
+
label: "Astro",
|
|
1138
|
+
hint: "Content-focused framework with island architecture"
|
|
1139
|
+
}
|
|
1140
|
+
]
|
|
794
1141
|
});
|
|
795
1142
|
if (p.isCancel(picked)) {
|
|
796
1143
|
p.outro(pc.red("Init cancelled."));
|
|
@@ -822,7 +1169,7 @@ async function init() {
|
|
|
822
1169
|
p.outro(pc.red("Init cancelled."));
|
|
823
1170
|
process.exit(0);
|
|
824
1171
|
}
|
|
825
|
-
const aliasHint = framework === "nextjs" ? `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)` : `Uses ${pc.cyan("$lib/")} prefix (SvelteKit built-in)`;
|
|
1172
|
+
const aliasHint = framework === "nextjs" ? `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)` : framework === "sveltekit" ? `Uses ${pc.cyan("$lib/")} prefix (SvelteKit built-in)` : `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)`;
|
|
826
1173
|
const useAlias = await p.confirm({
|
|
827
1174
|
message: `Use path aliases for imports? ${pc.dim(aliasHint)}`,
|
|
828
1175
|
initialValue: false
|
|
@@ -831,6 +1178,37 @@ async function init() {
|
|
|
831
1178
|
p.outro(pc.red("Init cancelled."));
|
|
832
1179
|
process.exit(0);
|
|
833
1180
|
}
|
|
1181
|
+
let astroAdapter;
|
|
1182
|
+
if (framework === "astro") {
|
|
1183
|
+
const adapter = await p.select({
|
|
1184
|
+
message: "Where will you deploy?",
|
|
1185
|
+
options: [
|
|
1186
|
+
{
|
|
1187
|
+
value: "vercel",
|
|
1188
|
+
label: "Vercel",
|
|
1189
|
+
hint: "Recommended for most projects"
|
|
1190
|
+
},
|
|
1191
|
+
{
|
|
1192
|
+
value: "netlify",
|
|
1193
|
+
label: "Netlify"
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
value: "cloudflare",
|
|
1197
|
+
label: "Cloudflare Pages"
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
value: "node",
|
|
1201
|
+
label: "Node.js / Docker",
|
|
1202
|
+
hint: "Self-hosted standalone server"
|
|
1203
|
+
}
|
|
1204
|
+
]
|
|
1205
|
+
});
|
|
1206
|
+
if (p.isCancel(adapter)) {
|
|
1207
|
+
p.outro(pc.red("Init cancelled."));
|
|
1208
|
+
process.exit(0);
|
|
1209
|
+
}
|
|
1210
|
+
astroAdapter = adapter;
|
|
1211
|
+
}
|
|
834
1212
|
const entry = await p.text({
|
|
835
1213
|
message: "Where should your docs live?",
|
|
836
1214
|
placeholder: "docs",
|
|
@@ -848,7 +1226,7 @@ async function init() {
|
|
|
848
1226
|
const entryPath = entry;
|
|
849
1227
|
const detectedCssFiles = detectGlobalCssFiles(cwd);
|
|
850
1228
|
let globalCssRelPath;
|
|
851
|
-
const defaultCssPath = framework === "sveltekit" ? "src/app.css" : "app/globals.css";
|
|
1229
|
+
const defaultCssPath = framework === "sveltekit" ? "src/app.css" : framework === "astro" ? "src/styles/global.css" : "app/globals.css";
|
|
852
1230
|
if (detectedCssFiles.length === 1) {
|
|
853
1231
|
globalCssRelPath = detectedCssFiles[0];
|
|
854
1232
|
p.log.info(`Found global CSS at ${pc.cyan(globalCssRelPath)}`);
|
|
@@ -888,7 +1266,8 @@ async function init() {
|
|
|
888
1266
|
theme,
|
|
889
1267
|
projectName: pkgJson.name || "My Project",
|
|
890
1268
|
framework,
|
|
891
|
-
useAlias
|
|
1269
|
+
useAlias,
|
|
1270
|
+
astroAdapter
|
|
892
1271
|
};
|
|
893
1272
|
const s = p.spinner();
|
|
894
1273
|
s.start("Scaffolding docs files");
|
|
@@ -899,6 +1278,7 @@ async function init() {
|
|
|
899
1278
|
else skipped.push(rel);
|
|
900
1279
|
}
|
|
901
1280
|
if (framework === "sveltekit") scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written);
|
|
1281
|
+
else if (framework === "astro") scaffoldAstro(cwd, cfg, globalCssRelPath, write, skipped, written);
|
|
902
1282
|
else scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written);
|
|
903
1283
|
s.stop("Files scaffolded");
|
|
904
1284
|
if (written.length > 0) p.log.success(`Created ${written.length} file${written.length > 1 ? "s" : ""}:\n` + written.map((f) => ` ${pc.green("+")} ${f}`).join("\n"));
|
|
@@ -909,7 +1289,10 @@ async function init() {
|
|
|
909
1289
|
s2.start("Installing dependencies");
|
|
910
1290
|
try {
|
|
911
1291
|
if (framework === "sveltekit") exec(`${installCommand(pm)} @farming-labs/docs @farming-labs/svelte @farming-labs/svelte-theme`, cwd);
|
|
912
|
-
else {
|
|
1292
|
+
else if (framework === "astro") {
|
|
1293
|
+
const adapterPkg = getAstroAdapterPkg(cfg.astroAdapter ?? "vercel");
|
|
1294
|
+
exec(`${installCommand(pm)} @farming-labs/docs @farming-labs/astro @farming-labs/astro-theme ${adapterPkg}`, cwd);
|
|
1295
|
+
} else {
|
|
913
1296
|
exec(`${installCommand(pm)} @farming-labs/docs @farming-labs/next @farming-labs/theme`, cwd);
|
|
914
1297
|
const devDeps = [
|
|
915
1298
|
"@tailwindcss/postcss",
|
|
@@ -948,6 +1331,10 @@ async function init() {
|
|
|
948
1331
|
cmd: "npx",
|
|
949
1332
|
args: ["vite", "dev"],
|
|
950
1333
|
waitFor: "ready"
|
|
1334
|
+
} : framework === "astro" ? {
|
|
1335
|
+
cmd: "npx",
|
|
1336
|
+
args: ["astro", "dev"],
|
|
1337
|
+
waitFor: "ready"
|
|
951
1338
|
} : {
|
|
952
1339
|
cmd: "npx",
|
|
953
1340
|
args: [
|
|
@@ -957,7 +1344,7 @@ async function init() {
|
|
|
957
1344
|
],
|
|
958
1345
|
waitFor: "Ready"
|
|
959
1346
|
};
|
|
960
|
-
const defaultPort = framework === "sveltekit" ? "5173" : "3000";
|
|
1347
|
+
const defaultPort = framework === "sveltekit" ? "5173" : framework === "astro" ? "4321" : "3000";
|
|
961
1348
|
try {
|
|
962
1349
|
const child = await spawnAndWaitFor(devCommand.cmd, devCommand.args, cwd, devCommand.waitFor, 6e4);
|
|
963
1350
|
const url = `http://localhost:${defaultPort}/${entryPath}`;
|
|
@@ -976,7 +1363,7 @@ async function init() {
|
|
|
976
1363
|
});
|
|
977
1364
|
});
|
|
978
1365
|
} catch (err) {
|
|
979
|
-
const manualCmd = framework === "sveltekit" ? "npx vite dev" : "npx next dev --webpack";
|
|
1366
|
+
const manualCmd = framework === "sveltekit" ? "npx vite dev" : framework === "astro" ? "npx astro dev" : "npx next dev --webpack";
|
|
980
1367
|
p.log.error(`Could not start dev server. Try running manually:
|
|
981
1368
|
${pc.cyan(manualCmd)}`);
|
|
982
1369
|
p.outro(pc.yellow("Setup complete. Start the server manually."));
|
|
@@ -1037,6 +1424,32 @@ function scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written)
|
|
|
1037
1424
|
write(`${cfg.entry}/installation/page.md`, svelteInstallationPageTemplate(cfg));
|
|
1038
1425
|
write(`${cfg.entry}/quickstart/page.md`, svelteQuickstartPageTemplate(cfg));
|
|
1039
1426
|
}
|
|
1427
|
+
function scaffoldAstro(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
1428
|
+
write("src/lib/docs.config.ts", astroDocsConfigTemplate(cfg));
|
|
1429
|
+
write("src/lib/docs.server.ts", astroDocsServerTemplate(cfg));
|
|
1430
|
+
if (!fileExists(path.join(cwd, "astro.config.mjs")) && !fileExists(path.join(cwd, "astro.config.ts"))) write("astro.config.mjs", astroConfigTemplate(cfg.astroAdapter ?? "vercel"));
|
|
1431
|
+
write(`src/pages/${cfg.entry}/index.astro`, astroDocsIndexTemplate(cfg));
|
|
1432
|
+
write(`src/pages/${cfg.entry}/[...slug].astro`, astroDocsPageTemplate(cfg));
|
|
1433
|
+
write(`src/pages/api/${cfg.entry}.ts`, astroApiRouteTemplate(cfg));
|
|
1434
|
+
const globalCssAbsPath = path.join(cwd, globalCssRelPath);
|
|
1435
|
+
const existingGlobalCss = readFileSafe(globalCssAbsPath);
|
|
1436
|
+
const cssTheme = {
|
|
1437
|
+
fumadocs: "fumadocs",
|
|
1438
|
+
darksharp: "darksharp",
|
|
1439
|
+
"pixel-border": "pixel-border",
|
|
1440
|
+
default: "fumadocs"
|
|
1441
|
+
}[cfg.theme] || "fumadocs";
|
|
1442
|
+
if (existingGlobalCss) {
|
|
1443
|
+
const injected = injectAstroCssImport(existingGlobalCss, cssTheme);
|
|
1444
|
+
if (injected) {
|
|
1445
|
+
writeFileSafe(globalCssAbsPath, injected, true);
|
|
1446
|
+
written.push(globalCssRelPath + " (updated)");
|
|
1447
|
+
} else skipped.push(globalCssRelPath + " (already configured)");
|
|
1448
|
+
} else write(globalCssRelPath, astroGlobalCssTemplate(cssTheme));
|
|
1449
|
+
write(`${cfg.entry}/page.md`, astroWelcomePageTemplate(cfg));
|
|
1450
|
+
write(`${cfg.entry}/installation/page.md`, astroInstallationPageTemplate(cfg));
|
|
1451
|
+
write(`${cfg.entry}/quickstart/page.md`, astroQuickstartPageTemplate(cfg));
|
|
1452
|
+
}
|
|
1040
1453
|
|
|
1041
1454
|
//#endregion
|
|
1042
1455
|
//#region src/cli/index.ts
|
|
@@ -1063,7 +1476,7 @@ ${pc.dim("Commands:")}
|
|
|
1063
1476
|
${pc.cyan("init")} Scaffold docs in your project (default)
|
|
1064
1477
|
|
|
1065
1478
|
${pc.dim("Supported frameworks:")}
|
|
1066
|
-
Next.js, SvelteKit
|
|
1479
|
+
Next.js, SvelteKit, Astro
|
|
1067
1480
|
|
|
1068
1481
|
${pc.dim("Options:")}
|
|
1069
1482
|
${pc.cyan("-h, --help")} Show this help message
|