@farming-labs/docs 0.0.5-beta.1 → 0.0.5

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.
@@ -1 +1,5 @@
1
- export { };
1
+ //#region src/cli/index.d.ts
2
+ /** Parse flags like --template next, --name my-docs, --theme darksharp, --entry docs, --framework astro (exported for tests). */
3
+ declare function parseFlags(argv: string[]): Record<string, string | undefined>;
4
+ //#endregion
5
+ export { parseFlags };
@@ -286,7 +286,7 @@ function nextConfigMergedTemplate(existingContent) {
286
286
  const lastImportIdx = lines.reduce((acc, l, i) => l.trimStart().startsWith("import ") ? i : acc, -1);
287
287
  if (lastImportIdx >= 0) lines.splice(lastImportIdx + 1, 0, importLine);
288
288
  else lines.unshift(importLine, "");
289
- const adjustedExportIdx = exportIdx + (lastImportIdx >= 0 && exportIdx > lastImportIdx ? 1 : 0);
289
+ const adjustedExportIdx = exportIdx + (lastImportIdx >= 0 ? exportIdx > lastImportIdx ? 1 : 0 : 2);
290
290
  const simpleMatch = lines[adjustedExportIdx].match(/^(\s*export\s+default\s+)(.*?)(;?\s*)$/);
291
291
  if (simpleMatch) {
292
292
  const [, prefix, value, suffix] = simpleMatch;
@@ -328,6 +328,32 @@ export default function RootLayout({
328
328
  }
329
329
  `;
330
330
  }
331
+ /**
332
+ * Injects RootProvider (import + wrapper) into an existing root layout without overwriting.
333
+ * Returns the modified content, or null if RootProvider is already present or injection isn't possible.
334
+ */
335
+ function injectRootProviderIntoLayout(content) {
336
+ if (!content || content.includes("RootProvider")) return null;
337
+ let out = content;
338
+ const themeImport = "import { RootProvider } from \"@farming-labs/theme\";";
339
+ if (!out.includes("@farming-labs/theme")) {
340
+ const lines = out.split("\n");
341
+ let lastImportIdx = -1;
342
+ for (let i = 0; i < lines.length; i++) {
343
+ const trimmed = lines[i].trimStart();
344
+ if (trimmed.startsWith("import ") || trimmed.startsWith("import type ")) lastImportIdx = i;
345
+ }
346
+ if (lastImportIdx >= 0) {
347
+ lines.splice(lastImportIdx + 1, 0, themeImport);
348
+ out = lines.join("\n");
349
+ } else out = themeImport + "\n" + out;
350
+ }
351
+ if (!out.includes("<RootProvider>")) {
352
+ const childrenPattern = /\{children\}/;
353
+ if (childrenPattern.test(out)) out = out.replace(childrenPattern, "<RootProvider>{children}</RootProvider>");
354
+ }
355
+ return out === content ? null : out;
356
+ }
331
357
  function globalCssTemplate(theme) {
332
358
  return `\
333
359
  @import "tailwindcss";
@@ -347,9 +373,19 @@ function injectCssImport(existingContent, theme) {
347
373
  function docsLayoutTemplate(cfg) {
348
374
  return `\
349
375
  import docsConfig from "${nextDocsLayoutConfigImport(cfg.useAlias)}";
350
- import { createDocsLayout } from "@farming-labs/theme";
376
+ import { createDocsLayout, createDocsMetadata } from "@farming-labs/theme";
377
+
378
+ export const metadata = createDocsMetadata(docsConfig);
379
+
380
+ const DocsLayout = createDocsLayout(docsConfig);
351
381
 
352
- export default createDocsLayout(docsConfig);
382
+ export default function Layout({ children }: { children: React.ReactNode }) {
383
+ return (
384
+ <>
385
+ <DocsLayout>{children}</DocsLayout>
386
+ </>
387
+ );
388
+ }
353
389
  `;
354
390
  }
355
391
  function postcssConfigTemplate() {
@@ -1820,7 +1856,7 @@ async function init(options = {}) {
1820
1856
  });
1821
1857
  });
1822
1858
  } catch (err) {
1823
- const manualCmd = framework === "sveltekit" ? "npx vite dev" : framework === "astro" ? "npx astro dev" : framework === "nuxt" ? "npx nuxt dev" : "npx next dev --webpack";
1859
+ const manualCmd = framework === "sveltekit" ? "npx vite dev" : framework === "astro" ? "npx astro dev" : framework === "nuxt" ? "npx nuxt dev" : "pnpm dev";
1824
1860
  p.log.error(`Could not start dev server. Try running manually:
1825
1861
  ${pc.cyan(manualCmd)}`);
1826
1862
  p.outro(pc.yellow("Setup complete. Start the server manually."));
@@ -1838,7 +1874,16 @@ function scaffoldNextJs(cwd, cfg, globalCssRelPath, write, skipped, written) {
1838
1874
  written.push(configFile + " (updated)");
1839
1875
  } else skipped.push(configFile + " (already configured)");
1840
1876
  } else write("next.config.ts", nextConfigTemplate());
1841
- write("app/layout.tsx", rootLayoutTemplate(cfg, globalCssRelPath));
1877
+ const rootLayoutPath = path.join(cwd, "app/layout.tsx");
1878
+ const existingRootLayout = readFileSafe(rootLayoutPath);
1879
+ if (!existingRootLayout) write("app/layout.tsx", rootLayoutTemplate(cfg, globalCssRelPath), true);
1880
+ else if (!existingRootLayout.includes("RootProvider")) {
1881
+ const injected = injectRootProviderIntoLayout(existingRootLayout);
1882
+ if (injected) {
1883
+ writeFileSafe(rootLayoutPath, injected, true);
1884
+ written.push("app/layout.tsx (injected RootProvider)");
1885
+ } else skipped.push("app/layout.tsx (could not inject RootProvider)");
1886
+ } else skipped.push("app/layout.tsx (already has RootProvider)");
1842
1887
  const globalCssAbsPath = path.join(cwd, globalCssRelPath);
1843
1888
  const existingGlobalCss = readFileSafe(globalCssAbsPath);
1844
1889
  if (existingGlobalCss) {
@@ -1988,6 +2033,15 @@ function presetFromFramework(fw) {
1988
2033
  function frameworkFromPreset(preset) {
1989
2034
  return preset === "next" ? "nextjs" : preset;
1990
2035
  }
2036
+ /** Return package list for a framework (for testing and CLI). */
2037
+ function getPackagesForFramework(framework) {
2038
+ return PACKAGES_BY_FRAMEWORK[framework];
2039
+ }
2040
+ /** Build the install command for upgrade (for testing). */
2041
+ function buildUpgradeCommand(framework, tag, pm) {
2042
+ const packagesWithTag = PACKAGES_BY_FRAMEWORK[framework].map((name) => `${name}@${tag}`);
2043
+ return `${installCommand(pm)} ${packagesWithTag.join(" ")}`;
2044
+ }
1991
2045
  async function upgrade(options = {}) {
1992
2046
  const cwd = process.cwd();
1993
2047
  const tag = options.tag ?? "latest";
@@ -2015,9 +2069,9 @@ async function upgrade(options = {}) {
2015
2069
  }
2016
2070
  preset = presetFromFramework(framework);
2017
2071
  }
2018
- const packages = PACKAGES_BY_FRAMEWORK[framework];
2019
- const packagesWithTag = packages.map((name) => `${name}@${tag}`);
2020
- const cmd = `${installCommand(detectPackageManager(cwd))} ${packagesWithTag.join(" ")}`;
2072
+ const pm = detectPackageManager(cwd);
2073
+ const cmd = buildUpgradeCommand(framework, tag, pm);
2074
+ const packages = getPackagesForFramework(framework);
2021
2075
  p.log.step(`Upgrading ${preset} docs packages to ${tag}...`);
2022
2076
  p.log.message(pc.dim(packages.join(", ")));
2023
2077
  try {
@@ -2034,7 +2088,7 @@ async function upgrade(options = {}) {
2034
2088
  //#region src/cli/index.ts
2035
2089
  const args = process.argv.slice(2);
2036
2090
  const command = args[0];
2037
- /** Parse flags like --template next, --name my-docs, --theme darksharp, --entry docs, --framework astro */
2091
+ /** Parse flags like --template next, --name my-docs, --theme darksharp, --entry docs, --framework astro (exported for tests). */
2038
2092
  function parseFlags(argv) {
2039
2093
  const flags = {};
2040
2094
  for (let i = 0; i < argv.length; i++) {
@@ -2110,4 +2164,4 @@ main().catch((err) => {
2110
2164
  });
2111
2165
 
2112
2166
  //#endregion
2113
- export { };
2167
+ export { parseFlags };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.0.5-beta.1",
3
+ "version": "0.0.5",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "keywords": [
6
6
  "docs",
@@ -34,11 +34,14 @@
34
34
  "devDependencies": {
35
35
  "@types/node": "^22.10.0",
36
36
  "tsdown": "^0.20.3",
37
- "typescript": "^5.9.3"
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^3.2.4"
38
39
  },
39
40
  "scripts": {
40
41
  "build": "tsdown",
41
42
  "dev": "tsdown --watch",
42
- "typecheck": "tsc --noEmit"
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest"
43
46
  }
44
47
  }