docstra 1.7.2 → 1.7.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.
package/README.md CHANGED
@@ -2,136 +2,10 @@
2
2
 
3
3
  **The Modern Documentation Framework for Next.js**
4
4
 
5
- Docstra is a powerful, type-safe, and easy-to-use documentation framework built for Next.js 15+ App Router. It provides a beautiful default theme, MDX support, and flexible components to build your documentation site in minutes.
5
+ Docstra is a powerful and easy-to-use documentation framework built for Next.js App Router. It provides a beautiful default theme, MDX support and flexible components to build your documentation site in minutes.
6
6
 
7
7
  ---
8
8
 
9
- ## 🚀 Quick Start
9
+ See Our [Website](https://docstra.sudhucodes.com) for more documentation.
10
10
 
11
- ### 1. Installation
12
-
13
- Install `docstra` and its peer dependencies:
14
-
15
- ```bash
16
- npm install docstra
17
- ```
18
-
19
- ### 2. Configuration
20
-
21
- Create `docstra.config.ts` in your project root:
22
-
23
- ```ts
24
- import { DocstraConfig } from "docstra/config";
25
-
26
- const config: DocstraConfig = {
27
- title: "My Docs",
28
- description: "Documentation for my project",
29
- github: {
30
- user: "myuser",
31
- repo: "myrepo",
32
- },
33
- sidebar: {
34
- // ... sidebar entries
35
- }
36
- };
37
-
38
- export default config;
39
- ```
40
-
41
- ### 3. Source Setup
42
-
43
- Create `src/lib/source.ts` (or `lib/source.ts`) to manage your content:
44
-
45
- ```ts
46
- import { createSource } from "docstra/server";
47
- import { docs } from "../.docstra"; // Generated at build time
48
-
49
- export const source = createSource(docs);
50
- ```
51
-
52
- ### 4. Component Mapping (Important!)
53
-
54
- Create `mdx-components.tsx` in your project root. This is critical for getting the default components (like code blocks) working correctly.
55
-
56
- ```tsx
57
- import { defaultMdxComponents } from "docstra/server";
58
- import { DocstraCodeBlock } from "docstra";
59
-
60
- export function useMDXComponents() {
61
- return {
62
- ...defaultMdxComponents(),
63
- pre: DocstraCodeBlock, // Manually map to avoid server/client bundle conflicts
64
- };
65
- }
66
- ```
67
-
68
- ### 5. Create the Page
69
-
70
- Create your catch-all route at `app/docs/[[...slug]]/page.tsx`:
71
-
72
- ```tsx
73
- import { source } from "@/lib/source";
74
- import { notFound } from "next/navigation";
75
- import { DocstraProvider, DocstraPage, DocstraBody, DocstraHeader } from "docstra";
76
- import { useMDXComponents } from "@/mdx-components";
77
- import config from "@/docstra.config";
78
-
79
- export default async function Page({ params }: { params: Promise<{ slug?: string[] }> }) {
80
- const { slug } = await params;
81
-
82
- // 1. Get page data
83
- const page = source.getPage(slug);
84
- if (!page) return notFound();
85
-
86
- // 2. Destructure info (safe JSON) and body (MDX Component)
87
- const { info, body: MDX } = page;
88
-
89
- // 3. Render
90
- return (
91
- <DocstraProvider docstraConfig={config} docs={source.files} pageData={info}>
92
- <DocstraHeader />
93
- <DocstraPage>
94
- <DocstraBody>
95
- <MDX components={useMDXComponents()} />
96
- </DocstraBody>
97
- </DocstraPage>
98
- </DocstraProvider>
99
- );
100
- }
101
-
102
- // Generate static params for SSG
103
- export function generateStaticParams() {
104
- return source.generateStaticParams();
105
- }
106
-
107
- // Generate metadata
108
- export async function generateMetadata({ params }: { params: Promise<{ slug?: string[] }> }) {
109
- const { slug } = await params;
110
- const page = source.getPage(slug);
111
- if (!page) return notFound();
112
- return {
113
- title: page.info.data.metadata.title,
114
- description: page.info.data.metadata.description,
115
- };
116
- }
117
- ```
118
-
119
- ### 6. Build
120
-
121
- Update your `next.config.ts` or `with-docstra` setup (if applicable) and run:
122
-
123
- ```bash
124
- npm run build
125
- ```
126
-
127
- Docstra will generate the `.docstra/index.ts` file manifest, and your docs will be live!
128
-
129
- ---
130
-
131
- ## 🛠 Features
132
-
133
- - **MDX Support**: Write documentation in Markdown/MDX.
134
- - **Auto Sidebar/TOC**: `DocstraPage` automatically handles layouts.
135
- - **Search**: Built-in search (requires configuration).
136
- - **Code Highlighting**: Powered by Prism with copy support.
137
- - **Type Safe**: Full TypeScript support.
11
+ Thanks for using Docstra! Happy Documentation :)
package/cli/index.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ const package = require("../package.json");
4
+ const command = process.argv[2];
5
+
6
+ if (command === "init") {
7
+ console.log(`
8
+ Docstra CLI ${package.version}
9
+ ${package.description}
10
+
11
+ Thank you for trying the Docstra CLI.
12
+ We are actively working on the \`init\` command and it will be
13
+ available in an upcoming release.
14
+
15
+ Stay tuned!
16
+ `);
17
+ } else {
18
+ console.log(`
19
+ Usage:
20
+ docstra init
21
+
22
+ Description:
23
+ Initializes Docstra in your project (coming soon).
24
+ `);
25
+ }
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React$1 from 'react';
3
- import { D as DocstraConfig, p as pageDataContent, a as DocstraContextType } from '../types-BTnHEZBE.mjs';
3
+ import { D as DocstraConfig, p as pageDataContent, a as DocstraContextType } from '../types-CvrHe34X.mjs';
4
4
 
5
5
  declare function DocstraProvider({ children, docstraConfig, docs, pageData: initialPageData, slug }: {
6
6
  children: React$1.ReactNode;
@@ -13,8 +13,6 @@ declare function useDocstra(): DocstraContextType;
13
13
 
14
14
  declare function DocstraHeader(): react_jsx_runtime.JSX.Element;
15
15
 
16
- declare function DocstraSidebar(): react_jsx_runtime.JSX.Element;
17
-
18
16
  interface DocstraPageProps {
19
17
  children: React.ReactNode;
20
18
  toc?: boolean;
@@ -27,10 +25,6 @@ interface Props {
27
25
  }
28
26
  declare function DocstraBody({ children }: Props): react_jsx_runtime.JSX.Element;
29
27
 
30
- declare function DocstraTOC(): react_jsx_runtime.JSX.Element;
31
-
32
28
  declare function DocstraCodeBlock(props: any): react_jsx_runtime.JSX.Element;
33
29
 
34
- declare function DocstraSearchBox(): react_jsx_runtime.JSX.Element;
35
-
36
- export { DocstraBody, DocstraCodeBlock, DocstraHeader, DocstraPage, DocstraProvider, DocstraSearchBox, DocstraSidebar, DocstraTOC, useDocstra };
30
+ export { DocstraBody, DocstraCodeBlock, DocstraHeader, DocstraPage, DocstraProvider, useDocstra };
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React$1 from 'react';
3
- import { D as DocstraConfig, p as pageDataContent, a as DocstraContextType } from '../types-BTnHEZBE.js';
3
+ import { D as DocstraConfig, p as pageDataContent, a as DocstraContextType } from '../types-CvrHe34X.js';
4
4
 
5
5
  declare function DocstraProvider({ children, docstraConfig, docs, pageData: initialPageData, slug }: {
6
6
  children: React$1.ReactNode;
@@ -13,8 +13,6 @@ declare function useDocstra(): DocstraContextType;
13
13
 
14
14
  declare function DocstraHeader(): react_jsx_runtime.JSX.Element;
15
15
 
16
- declare function DocstraSidebar(): react_jsx_runtime.JSX.Element;
17
-
18
16
  interface DocstraPageProps {
19
17
  children: React.ReactNode;
20
18
  toc?: boolean;
@@ -27,10 +25,6 @@ interface Props {
27
25
  }
28
26
  declare function DocstraBody({ children }: Props): react_jsx_runtime.JSX.Element;
29
27
 
30
- declare function DocstraTOC(): react_jsx_runtime.JSX.Element;
31
-
32
28
  declare function DocstraCodeBlock(props: any): react_jsx_runtime.JSX.Element;
33
29
 
34
- declare function DocstraSearchBox(): react_jsx_runtime.JSX.Element;
35
-
36
- export { DocstraBody, DocstraCodeBlock, DocstraHeader, DocstraPage, DocstraProvider, DocstraSearchBox, DocstraSidebar, DocstraTOC, useDocstra };
30
+ export { DocstraBody, DocstraCodeBlock, DocstraHeader, DocstraPage, DocstraProvider, useDocstra };
@@ -36,9 +36,6 @@ __export(client_exports, {
36
36
  DocstraHeader: () => DocstraHeader,
37
37
  DocstraPage: () => DocstraPage,
38
38
  DocstraProvider: () => DocstraProvider,
39
- DocstraSearchBox: () => DocstraSearchBox,
40
- DocstraSidebar: () => DocstraSidebar,
41
- DocstraTOC: () => DocstraTOC,
42
39
  useDocstra: () => useDocstra
43
40
  });
44
41
  module.exports = __toCommonJS(client_exports);
@@ -238,6 +235,7 @@ var import_link2 = __toESM(require("next/link"));
238
235
  var import_jsx_runtime3 = require("react/jsx-runtime");
239
236
  function DocstraHeader() {
240
237
  const { openSidebar, setOpenSidebar, docstraConfig } = useDocstra();
238
+ const githubRepo = "https://github.com/" + docstraConfig?.editOnGithub?.owner + "/" + docstraConfig?.editOnGithub?.repo;
241
239
  (0, import_react3.useEffect)(() => {
242
240
  if (openSidebar) {
243
241
  document.body.classList.add("max-md:overflow-hidden");
@@ -255,8 +253,8 @@ function DocstraHeader() {
255
253
  }
256
254
  ) }),
257
255
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hidden divide-x divide-gray-200 md:flex items-center", children: [
258
- docstraConfig.navbar?.links?.map((link) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: link.href, className: "px-6 hover:text-gray-500", children: link.name }, link.name)),
259
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: docstraConfig?.githubRepo || "https://github.com/sudhucodes/docstra", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "size-6 mx-6", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3" }) }) })
256
+ docstraConfig.navbar?.links?.map((link) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: link.href, className: "px-6 hover:text-gray-600", children: link.name }, link.name)),
257
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: githubRepo || "https://github.com/sudhucodes/docstra", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "size-6 mx-6", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3" }) }) })
260
258
  ] }),
261
259
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
262
260
  "button",
@@ -366,7 +364,8 @@ function DocstraTOC() {
366
364
  const lastScrollY = (0, import_react4.useRef)(0);
367
365
  const observerRef = (0, import_react4.useRef)(null);
368
366
  const pathname = (0, import_navigation3.usePathname)();
369
- const githubLink = docstraConfig?.editOnGithub ? `${docstraConfig.editOnGithub.owner}/${docstraConfig.editOnGithub.repo}/edit/main/${mdxFilePath}` : "";
367
+ const baseUrlOfGithub = "https://github.com/" + docstraConfig?.editOnGithub?.owner + "/" + docstraConfig?.editOnGithub?.repo;
368
+ const githubLink = `${baseUrlOfGithub}/edit/main/${docstraConfig?.editOnGithub?.path}/${mdxFilePath}`;
370
369
  (0, import_react4.useEffect)(() => {
371
370
  const onScroll = () => {
372
371
  const currentY = window.scrollY;
@@ -757,7 +756,7 @@ function DocstraPagination() {
757
756
  const currentIndex = flatLinks.findIndex((item) => item.href === pathname);
758
757
  const prev = currentIndex > 0 ? flatLinks[currentIndex - 1] : null;
759
758
  const next = currentIndex < flatLinks.length - 1 ? flatLinks[currentIndex + 1] : null;
760
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col md:flex-row gap-2 justify-between py-10 mt-10", children: [
759
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col lg:flex-row gap-2 justify-between py-10 mt-10", children: [
761
760
  prev ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
762
761
  import_link5.default,
763
762
  {
@@ -803,43 +802,29 @@ function DocstraBody({ children }) {
803
802
  }
804
803
 
805
804
  // src/client/components/code-block.tsx
806
- var import_react7 = require("react");
807
- var import_prism_react_renderer = require("prism-react-renderer");
808
805
  var import_lucide_react10 = require("lucide-react");
809
- var import_react_toast_msg2 = require("react-toast-msg");
806
+ var import_react7 = require("react");
810
807
  var import_jsx_runtime15 = require("react/jsx-runtime");
811
808
  function DocstraCodeBlock(props) {
812
- const { title, children } = props;
813
- const childProps = children?.props || {};
814
- const className = childProps.className || "";
815
- const matches = className.match(/language-(?<lang>.*)/);
816
- const language = props.language || matches && matches.groups && matches.groups.lang || "text";
817
- const code = typeof children === "string" ? children.trim() : children?.props?.children?.toString()?.trim() || "";
818
- const [copied, setCopied] = (0, import_react7.useState)(false);
809
+ const { filename, children, className, rawText } = props;
810
+ const isInline = !className?.includes("language-");
811
+ if (isInline) {
812
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { className: "px-1 py-0.5 rounded border border-gray-200 text-gray-800 text-sm", children: typeof children === "string" ? children : children.props.children });
813
+ }
814
+ const [isCopied, setIsCopied] = (0, import_react7.useState)(false);
815
+ const match = className.match(/language-([\w-]+)/);
816
+ const language = match?.[1];
819
817
  const handleCopy = () => {
820
- navigator.clipboard.writeText(code);
821
- import_react_toast_msg2.toast.success("Copied to clipboard!");
822
- setCopied(true);
818
+ navigator.clipboard.writeText(rawText);
819
+ setIsCopied(true);
820
+ setTimeout(() => setIsCopied(false), 2e3);
823
821
  };
824
- (0, import_react7.useEffect)(() => {
825
- if (copied) {
826
- const timeout = setTimeout(() => setCopied(false), 2e3);
827
- return () => clearTimeout(timeout);
828
- }
829
- }, [copied]);
830
822
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "max-w-2xl overflow-hidden rounded-lg text-sm text-gray-800 border border-gray-200/80 mt-4", children: [
831
823
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center bg-gray-50 justify-between border-b border-gray-200/80", children: [
832
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs text-gray-400 p-4", children: title || language }),
833
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
834
- "button",
835
- {
836
- onClick: handleCopy,
837
- className: "rounded cursor-pointer aspect-square p-2 m-2 text-xs hover:bg-gray-200 transition",
838
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react10.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react10.CopyIcon, { className: "size-4" })
839
- }
840
- )
824
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs text-gray-400 p-4", children: filename || language }),
825
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: handleCopy, className: "rounded cursor-pointer aspect-square p-2 m-2 text-xs hover:bg-gray-200 transition", children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react10.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react10.CopyIcon, { className: "size-4" }) })
841
826
  ] }),
842
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_prism_react_renderer.Highlight, { code, language, theme: import_prism_react_renderer.themes.nightOwlLight, children: ({ style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("pre", { className: "p-4 font-mono whitespace-pre scrollbar-x overflow-x-auto", style, children: tokens.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ...getLineProps({ line }), children: line.map((token, key) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { ...getTokenProps({ token }) }, key)) }, i)) }) })
827
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("pre", { className: "p-4 font-mono whitespace-pre scrollbar-x overflow-x-auto", children })
843
828
  ] });
844
829
  }
845
830
  // Annotate the CommonJS export names for ESM import in node:
@@ -849,9 +834,6 @@ function DocstraCodeBlock(props) {
849
834
  DocstraHeader,
850
835
  DocstraPage,
851
836
  DocstraProvider,
852
- DocstraSearchBox,
853
- DocstraSidebar,
854
- DocstraTOC,
855
837
  useDocstra
856
838
  });
857
839
  //# sourceMappingURL=index.js.map