@farming-labs/docs 0.0.2-beta.5 → 0.0.2-beta.7

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.
Files changed (2) hide show
  1. package/dist/cli/index.mjs +120 -52
  2. package/package.json +1 -1
@@ -128,14 +128,65 @@ function spawnAndWaitFor(command, args, cwd, waitFor, timeoutMs = 6e4) {
128
128
 
129
129
  //#endregion
130
130
  //#region src/cli/templates.ts
131
+ const THEME_INFO = {
132
+ fumadocs: {
133
+ factory: "fumadocs",
134
+ nextImport: "@farming-labs/theme",
135
+ svelteImport: "@farming-labs/svelte-theme",
136
+ nextCssImport: "default",
137
+ svelteCssTheme: "fumadocs"
138
+ },
139
+ darksharp: {
140
+ factory: "darksharp",
141
+ nextImport: "@farming-labs/theme/darksharp",
142
+ svelteImport: "@farming-labs/svelte-theme/darksharp",
143
+ nextCssImport: "darksharp",
144
+ svelteCssTheme: "darksharp"
145
+ },
146
+ "pixel-border": {
147
+ factory: "pixelBorder",
148
+ nextImport: "@farming-labs/theme/pixel-border",
149
+ svelteImport: "@farming-labs/svelte-theme/pixel-border",
150
+ nextCssImport: "pixel-border",
151
+ svelteCssTheme: "pixel-border"
152
+ }
153
+ };
154
+ function getThemeInfo(theme) {
155
+ return THEME_INFO[theme] ?? THEME_INFO.fumadocs;
156
+ }
157
+ /** Config import for Next.js app/layout.tsx → root docs.config */
158
+ function nextRootLayoutConfigImport(useAlias) {
159
+ return useAlias ? "@/docs.config" : "../docs.config";
160
+ }
161
+ /** Config import for Next.js app/{entry}/layout.tsx → root docs.config */
162
+ function nextDocsLayoutConfigImport(useAlias) {
163
+ return useAlias ? "@/docs.config" : "../../docs.config";
164
+ }
165
+ /** Config import for SvelteKit src/lib/docs.server.ts → src/lib/docs.config.js */
166
+ function svelteServerConfigImport(useAlias) {
167
+ return useAlias ? "$lib/docs.config.js" : "./docs.config.js";
168
+ }
169
+ /** Config import for SvelteKit src/routes/{entry}/+layout.svelte → src/lib/docs.config.js */
170
+ function svelteLayoutConfigImport(useAlias) {
171
+ return useAlias ? "$lib/docs.config.js" : "../../lib/docs.config.js";
172
+ }
173
+ /** Config import for SvelteKit src/routes/{entry}/[...slug]/+page.svelte → src/lib/docs.config.js */
174
+ function sveltePageConfigImport(useAlias) {
175
+ return useAlias ? "$lib/docs.config.js" : "../../../lib/docs.config.js";
176
+ }
177
+ /** Server import for SvelteKit +layout.server.js → src/lib/docs.server.js */
178
+ function svelteLayoutServerImport(useAlias) {
179
+ return useAlias ? "$lib/docs.server.js" : "../../lib/docs.server.js";
180
+ }
131
181
  function docsConfigTemplate(cfg) {
182
+ const t = getThemeInfo(cfg.theme);
132
183
  return `\
133
184
  import { defineDocs } from "@farming-labs/docs";
134
- import { fumadocs } from "@farming-labs/theme";
185
+ import { ${t.factory} } from "${t.nextImport}";
135
186
 
136
187
  export default defineDocs({
137
188
  entry: "${cfg.entry}",
138
- theme: fumadocs({
189
+ theme: ${t.factory}({
139
190
  ui: {
140
191
  colors: { primary: "#6366f1" },
141
192
  },
@@ -172,7 +223,7 @@ function nextConfigMergedTemplate(existingContent) {
172
223
  }
173
224
  return lines.join("\n");
174
225
  }
175
- function rootLayoutTemplate(globalCssRelPath = "app/globals.css") {
226
+ function rootLayoutTemplate(cfg, globalCssRelPath = "app/globals.css") {
176
227
  let cssImport;
177
228
  if (globalCssRelPath.startsWith("app/")) cssImport = "./" + globalCssRelPath.slice(4);
178
229
  else if (globalCssRelPath.startsWith("src/app/")) cssImport = "./" + globalCssRelPath.slice(8);
@@ -180,7 +231,7 @@ function rootLayoutTemplate(globalCssRelPath = "app/globals.css") {
180
231
  return `\
181
232
  import type { Metadata } from "next";
182
233
  import { RootProvider } from "@farming-labs/theme";
183
- import docsConfig from "@/docs.config";
234
+ import docsConfig from "${nextRootLayoutConfigImport(cfg.useAlias)}";
184
235
  import "${cssImport}";
185
236
 
186
237
  export const metadata: Metadata = {
@@ -209,25 +260,22 @@ export default function RootLayout({
209
260
  function globalCssTemplate(theme) {
210
261
  return `\
211
262
  @import "tailwindcss";
212
- @import "@farming-labs/${theme}/css";
263
+ @import "@farming-labs/theme/${getThemeInfo(theme).nextCssImport}/css";
213
264
  `;
214
265
  }
215
- /**
216
- * Inject the fumadocs CSS import into an existing global.css.
217
- * Returns the modified content, or null if already present.
218
- */
219
266
  function injectCssImport(existingContent, theme) {
220
- const importLine = `@import "@farming-labs/${theme}/css";`;
267
+ const importLine = `@import "@farming-labs/theme/${getThemeInfo(theme).nextCssImport}/css";`;
221
268
  if (existingContent.includes(importLine)) return null;
269
+ if (existingContent.includes("@farming-labs/theme/") && existingContent.includes("/css")) return null;
222
270
  const lines = existingContent.split("\n");
223
271
  const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("@import") ? i : acc, -1);
224
272
  if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
225
273
  else lines.unshift(importLine);
226
274
  return lines.join("\n");
227
275
  }
228
- function docsLayoutTemplate() {
276
+ function docsLayoutTemplate(cfg) {
229
277
  return `\
230
- import docsConfig from "@/docs.config";
278
+ import docsConfig from "${nextDocsLayoutConfigImport(cfg.useAlias)}";
231
279
  import { createDocsLayout } from "@farming-labs/theme";
232
280
 
233
281
  export default createDocsLayout(docsConfig);
@@ -307,6 +355,7 @@ Start by reading the [Installation](/${cfg.entry}/installation) guide, then foll
307
355
  `;
308
356
  }
309
357
  function installationPageTemplate(cfg) {
358
+ const t = getThemeInfo(cfg.theme);
310
359
  return `\
311
360
  ---
312
361
  title: "Installation"
@@ -333,11 +382,11 @@ Your project includes a \`docs.config.ts\` at the root:
333
382
 
334
383
  \`\`\`ts
335
384
  import { defineDocs } from "@farming-labs/docs";
336
- import { fumadocs } from "@farming-labs/theme";
385
+ import { ${t.factory} } from "${t.nextImport}";
337
386
 
338
387
  export default defineDocs({
339
388
  entry: "${cfg.entry}",
340
- theme: fumadocs({
389
+ theme: ${t.factory}({
341
390
  ui: { colors: { primary: "#6366f1" } },
342
391
  }),
343
392
  });
@@ -364,6 +413,7 @@ Head to the [Quickstart](/${cfg.entry}/quickstart) guide to start writing your f
364
413
  `;
365
414
  }
366
415
  function quickstartPageTemplate(cfg) {
416
+ const t = getThemeInfo(cfg.theme);
367
417
  return `\
368
418
  ---
369
419
  title: "Quickstart"
@@ -426,7 +476,7 @@ console.log(greet("World"));
426
476
  Edit \`docs.config.ts\` to change colors, typography, and component defaults:
427
477
 
428
478
  \`\`\`ts
429
- theme: fumadocs({
479
+ theme: ${t.factory}({
430
480
  ui: {
431
481
  colors: { primary: "#22c55e" },
432
482
  },
@@ -445,14 +495,15 @@ Deploy to Vercel, Netlify, or any Node.js hosting platform.
445
495
  `;
446
496
  }
447
497
  function svelteDocsConfigTemplate(cfg) {
498
+ const t = getThemeInfo(cfg.theme);
448
499
  return `\
449
500
  import { defineDocs } from "@farming-labs/docs";
450
- import { fumadocs } from "@farming-labs/svelte-theme";
501
+ import { ${t.factory} } from "${t.svelteImport}";
451
502
 
452
503
  export default defineDocs({
453
504
  entry: "${cfg.entry}",
454
505
  contentDir: "${cfg.entry}",
455
- theme: fumadocs({
506
+ theme: ${t.factory}({
456
507
  ui: {
457
508
  colors: { primary: "#6366f1" },
458
509
  },
@@ -475,7 +526,7 @@ export default defineDocs({
475
526
  function svelteDocsServerTemplate(cfg) {
476
527
  return `\
477
528
  import { createDocsServer } from "@farming-labs/svelte/server";
478
- import config from "../../docs.config.js";
529
+ import config from "${svelteServerConfigImport(cfg.useAlias)}";
479
530
 
480
531
  export const { load, GET, POST } = createDocsServer(config);
481
532
  `;
@@ -484,7 +535,7 @@ function svelteDocsLayoutTemplate(cfg) {
484
535
  return `\
485
536
  <script>
486
537
  import { DocsLayout } from "@farming-labs/svelte-theme";
487
- import config from "../../../docs.config.js";
538
+ import config from "${svelteLayoutConfigImport(cfg.useAlias)}";
488
539
 
489
540
  let { data, children } = $props();
490
541
  <\/script>
@@ -494,16 +545,16 @@ function svelteDocsLayoutTemplate(cfg) {
494
545
  </DocsLayout>
495
546
  `;
496
547
  }
497
- function svelteDocsLayoutServerTemplate() {
548
+ function svelteDocsLayoutServerTemplate(cfg) {
498
549
  return `\
499
- export { load } from "$lib/docs.server.js";
550
+ export { load } from "${svelteLayoutServerImport(cfg.useAlias)}";
500
551
  `;
501
552
  }
502
553
  function svelteDocsPageTemplate(cfg) {
503
554
  return `\
504
555
  <script>
505
556
  import { DocsContent } from "@farming-labs/svelte-theme";
506
- import config from "../../../../docs.config.js";
557
+ import config from "${sveltePageConfigImport(cfg.useAlias)}";
507
558
 
508
559
  let { data } = $props();
509
560
  <\/script>
@@ -573,6 +624,7 @@ Start by reading the [Installation](/${cfg.entry}/installation) guide, then foll
573
624
  `;
574
625
  }
575
626
  function svelteInstallationPageTemplate(cfg) {
627
+ const t = getThemeInfo(cfg.theme);
576
628
  return `\
577
629
  ---
578
630
  title: "Installation"
@@ -596,16 +648,16 @@ pnpm add @farming-labs/docs @farming-labs/svelte @farming-labs/svelte-theme
596
648
 
597
649
  ## Configuration
598
650
 
599
- Your project includes a \`docs.config.ts\` at the root:
651
+ Your project includes a \`docs.config.ts\` in \`src/lib/\`:
600
652
 
601
- \`\`\`ts title="docs.config.ts"
653
+ \`\`\`ts title="src/lib/docs.config.ts"
602
654
  import { defineDocs } from "@farming-labs/docs";
603
- import { fumadocs } from "@farming-labs/svelte-theme";
655
+ import { ${t.factory} } from "${t.svelteImport}";
604
656
 
605
657
  export default defineDocs({
606
658
  entry: "${cfg.entry}",
607
659
  contentDir: "${cfg.entry}",
608
- theme: fumadocs({
660
+ theme: ${t.factory}({
609
661
  ui: { colors: { primary: "#6366f1" } },
610
662
  }),
611
663
  });
@@ -622,6 +674,7 @@ ${cfg.entry}/ # Markdown content
622
674
  page.md # /${cfg.entry}/quickstart
623
675
  src/
624
676
  lib/
677
+ docs.config.ts # Docs configuration
625
678
  docs.server.ts # Server-side docs loader
626
679
  routes/
627
680
  ${cfg.entry}/
@@ -629,7 +682,6 @@ src/
629
682
  +layout.server.js # Layout data loader
630
683
  [...slug]/
631
684
  +page.svelte # Dynamic doc page
632
- docs.config.ts # Docs configuration
633
685
  \`\`\`
634
686
 
635
687
  ## What's Next?
@@ -638,6 +690,7 @@ Head to the [Quickstart](/${cfg.entry}/quickstart) guide to start writing your f
638
690
  `;
639
691
  }
640
692
  function svelteQuickstartPageTemplate(cfg) {
693
+ const t = getThemeInfo(cfg.theme);
641
694
  return `\
642
695
  ---
643
696
  title: "Quickstart"
@@ -685,10 +738,10 @@ console.log(greet("World"));
685
738
 
686
739
  ## Customizing the Theme
687
740
 
688
- Edit \`docs.config.ts\` to change colors, typography, and component defaults:
741
+ Edit \`src/lib/docs.config.ts\` to change colors, typography, and component defaults:
689
742
 
690
- \`\`\`ts title="docs.config.ts"
691
- theme: fumadocs({
743
+ \`\`\`ts title="src/lib/docs.config.ts"
744
+ theme: ${t.factory}({
692
745
  ui: {
693
746
  colors: { primary: "#22c55e" },
694
747
  },
@@ -736,27 +789,39 @@ async function init() {
736
789
  }
737
790
  framework = picked;
738
791
  }
739
- const themeOptions = framework === "sveltekit" ? [{
740
- value: "default",
741
- label: "Default",
742
- hint: "Clean, modern docs theme with sidebar, search, and dark mode"
743
- }, {
744
- value: "pixel-border",
745
- label: "Pixel Border",
746
- hint: "Sharp pixel-art inspired theme with monospace text"
747
- }] : [{
748
- value: "fumadocs",
749
- label: "Fumadocs",
750
- hint: "Clean, modern docs theme with sidebar, search, and dark mode"
751
- }];
752
792
  const theme = await p.select({
753
793
  message: "Which theme would you like to use?",
754
- options: themeOptions
794
+ options: [
795
+ {
796
+ value: "fumadocs",
797
+ label: "Fumadocs (Default)",
798
+ hint: "Clean, modern docs theme with sidebar, search, and dark mode"
799
+ },
800
+ {
801
+ value: "darksharp",
802
+ label: "Darksharp",
803
+ hint: "All-black, sharp edges, zero-radius look"
804
+ },
805
+ {
806
+ value: "pixel-border",
807
+ label: "Pixel Border",
808
+ hint: "Rounded borders, pixel-perfect spacing, refined sidebar"
809
+ }
810
+ ]
755
811
  });
756
812
  if (p.isCancel(theme)) {
757
813
  p.outro(pc.red("Init cancelled."));
758
814
  process.exit(0);
759
815
  }
816
+ const aliasHint = framework === "nextjs" ? `Uses ${pc.cyan("@/")} prefix (requires tsconfig paths)` : `Uses ${pc.cyan("$lib/")} prefix (SvelteKit built-in)`;
817
+ const useAlias = await p.confirm({
818
+ message: `Use path aliases for imports? ${pc.dim(aliasHint)}`,
819
+ initialValue: false
820
+ });
821
+ if (p.isCancel(useAlias)) {
822
+ p.outro(pc.red("Init cancelled."));
823
+ process.exit(0);
824
+ }
760
825
  const entry = await p.text({
761
826
  message: "Where should your docs live?",
762
827
  placeholder: "docs",
@@ -807,12 +872,14 @@ async function init() {
807
872
  }
808
873
  globalCssRelPath = cssPath;
809
874
  }
810
- const pkgJson = JSON.parse(readFileSafe(path.join(cwd, "package.json")));
875
+ const pkgJsonContent = readFileSafe(path.join(cwd, "package.json"));
876
+ const pkgJson = pkgJsonContent ? JSON.parse(pkgJsonContent) : { name: "my-project" };
811
877
  const cfg = {
812
878
  entry: entryPath,
813
879
  theme,
814
880
  projectName: pkgJson.name || "My Project",
815
- framework
881
+ framework,
882
+ useAlias
816
883
  };
817
884
  const s = p.spinner();
818
885
  s.start("Scaffolding docs files");
@@ -918,7 +985,7 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
918
985
  written.push(configFile + " (updated)");
919
986
  } else skipped.push(configFile + " (already configured)");
920
987
  } else write("next.config.ts", nextConfigTemplate());
921
- write("app/layout.tsx", rootLayoutTemplate(globalCssRelPath));
988
+ write("app/layout.tsx", rootLayoutTemplate(cfg, globalCssRelPath));
922
989
  const globalCssAbsPath = path.join(cwd, globalCssRelPath);
923
990
  const existingGlobalCss = readFileSafe(globalCssAbsPath);
924
991
  if (existingGlobalCss) {
@@ -928,7 +995,7 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
928
995
  written.push(globalCssRelPath + " (updated)");
929
996
  } else skipped.push(globalCssRelPath + " (already configured)");
930
997
  } else write(globalCssRelPath, globalCssTemplate(cfg.theme));
931
- write(`app/${cfg.entry}/layout.tsx`, docsLayoutTemplate());
998
+ write(`app/${cfg.entry}/layout.tsx`, docsLayoutTemplate(cfg));
932
999
  write("postcss.config.mjs", postcssConfigTemplate());
933
1000
  if (!fileExists(path.join(cwd, "tsconfig.json"))) write("tsconfig.json", tsconfigTemplate());
934
1001
  write(`app/${cfg.entry}/page.mdx`, welcomePageTemplate(cfg));
@@ -936,18 +1003,19 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
936
1003
  write(`app/${cfg.entry}/quickstart/page.mdx`, quickstartPageTemplate(cfg));
937
1004
  }
938
1005
  function scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written) {
939
- write("docs.config.ts", svelteDocsConfigTemplate(cfg));
1006
+ write("src/lib/docs.config.ts", svelteDocsConfigTemplate(cfg));
940
1007
  write("src/lib/docs.server.ts", svelteDocsServerTemplate(cfg));
941
1008
  write(`src/routes/${cfg.entry}/+layout.svelte`, svelteDocsLayoutTemplate(cfg));
942
- write(`src/routes/${cfg.entry}/+layout.server.js`, svelteDocsLayoutServerTemplate());
1009
+ write(`src/routes/${cfg.entry}/+layout.server.js`, svelteDocsLayoutServerTemplate(cfg));
943
1010
  write(`src/routes/${cfg.entry}/[...slug]/+page.svelte`, svelteDocsPageTemplate(cfg));
944
1011
  if (!readFileSafe(path.join(cwd, "src/routes/+layout.svelte"))) write("src/routes/+layout.svelte", svelteRootLayoutTemplate(globalCssRelPath));
945
1012
  const globalCssAbsPath = path.join(cwd, globalCssRelPath);
946
1013
  const existingGlobalCss = readFileSafe(globalCssAbsPath);
947
1014
  const cssTheme = {
948
- default: "fumadocs",
1015
+ fumadocs: "fumadocs",
1016
+ darksharp: "darksharp",
949
1017
  "pixel-border": "pixel-border",
950
- fumadocs: "fumadocs"
1018
+ default: "fumadocs"
951
1019
  }[cfg.theme] || "fumadocs";
952
1020
  if (existingGlobalCss) {
953
1021
  const injected = injectSvelteCssImport(existingGlobalCss, cssTheme);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.0.2-beta.5",
3
+ "version": "0.0.2-beta.7",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",