create-specra 0.1.6 → 0.2.0

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 (144) hide show
  1. package/LICENSE.MD +16 -4
  2. package/README.md +53 -17
  3. package/dist/chunk-3DKWECRK.js +45 -0
  4. package/dist/chunk-3DKWECRK.js.map +1 -0
  5. package/dist/chunk-MA7QG54W.js +74 -0
  6. package/dist/chunk-MA7QG54W.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +33 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/deploy-SCEMUQNS.js +141 -0
  11. package/dist/deploy-SCEMUQNS.js.map +1 -0
  12. package/dist/index.js +11 -11
  13. package/dist/index.js.map +1 -1
  14. package/dist/login-NKDRQXRE.js +71 -0
  15. package/dist/login-NKDRQXRE.js.map +1 -0
  16. package/dist/logout-H543QEKU.js +20 -0
  17. package/dist/logout-H543QEKU.js.map +1 -0
  18. package/dist/logs-YDAUCMAV.js +71 -0
  19. package/dist/logs-YDAUCMAV.js.map +1 -0
  20. package/dist/projects-3TAY7EDJ.js +42 -0
  21. package/dist/projects-3TAY7EDJ.js.map +1 -0
  22. package/package.json +7 -3
  23. package/templates/book-docs/docs/v1.0.0/concepts.mdx +89 -0
  24. package/templates/book-docs/docs/v1.0.0/content/_category_.json +7 -0
  25. package/templates/book-docs/docs/v1.0.0/content/formatting.mdx +128 -0
  26. package/templates/book-docs/docs/v1.0.0/content/reusable-content.mdx +116 -0
  27. package/templates/book-docs/docs/v1.0.0/content/structure.mdx +92 -0
  28. package/templates/book-docs/docs/v1.0.0/customization/_category_.json +7 -0
  29. package/templates/book-docs/docs/v1.0.0/customization/branding.mdx +115 -0
  30. package/templates/book-docs/docs/v1.0.0/customization/themes.mdx +81 -0
  31. package/templates/book-docs/docs/v1.0.0/introduction.mdx +38 -0
  32. package/templates/book-docs/docs/v1.0.0/quickstart.mdx +112 -0
  33. package/templates/book-docs/docs/v2.0.0/concepts.mdx +89 -0
  34. package/templates/book-docs/docs/v2.0.0/content/_category_.json +7 -0
  35. package/templates/book-docs/docs/v2.0.0/content/formatting.mdx +128 -0
  36. package/templates/book-docs/docs/v2.0.0/content/reusable-content.mdx +116 -0
  37. package/templates/book-docs/docs/v2.0.0/content/structure.mdx +92 -0
  38. package/templates/book-docs/docs/v2.0.0/customization/_category_.json +7 -0
  39. package/templates/book-docs/docs/v2.0.0/customization/branding.mdx +115 -0
  40. package/templates/book-docs/docs/v2.0.0/customization/themes.mdx +81 -0
  41. package/templates/book-docs/docs/v2.0.0/introduction.mdx +39 -0
  42. package/templates/book-docs/docs/v2.0.0/quickstart.mdx +112 -0
  43. package/templates/book-docs/gitignore +7 -0
  44. package/templates/book-docs/package.json +28 -0
  45. package/templates/book-docs/postcss.config.mjs +8 -0
  46. package/templates/book-docs/public/api-specs/openapi-example.json +259 -0
  47. package/templates/book-docs/public/api-specs/postman-example.json +205 -0
  48. package/templates/book-docs/public/api-specs/test-api.json +256 -0
  49. package/templates/book-docs/public/api-specs/users-api.json +264 -0
  50. package/templates/book-docs/specra.config.json +77 -0
  51. package/templates/book-docs/src/app.css +2 -0
  52. package/templates/book-docs/src/app.html +12 -0
  53. package/templates/book-docs/src/routes/+layout.server.ts +11 -0
  54. package/templates/book-docs/src/routes/+layout.svelte +21 -0
  55. package/templates/book-docs/src/routes/+page.server.ts +9 -0
  56. package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
  57. package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
  58. package/templates/book-docs/svelte.config.js +8 -0
  59. package/templates/book-docs/tsconfig.json +12 -0
  60. package/templates/book-docs/vite.config.ts +6 -0
  61. package/templates/jbrains-docs/docs/v1.0.0/advanced/_category_.json +8 -0
  62. package/templates/jbrains-docs/docs/v1.0.0/advanced/async.mdx +95 -0
  63. package/templates/jbrains-docs/docs/v1.0.0/advanced/generics.mdx +126 -0
  64. package/templates/jbrains-docs/docs/v1.0.0/basics/_category_.json +8 -0
  65. package/templates/jbrains-docs/docs/v1.0.0/basics/control-flow.mdx +106 -0
  66. package/templates/jbrains-docs/docs/v1.0.0/basics/syntax.mdx +129 -0
  67. package/templates/jbrains-docs/docs/v1.0.0/basics/types.mdx +135 -0
  68. package/templates/jbrains-docs/docs/v1.0.0/getting-started.mdx +111 -0
  69. package/templates/jbrains-docs/docs/v1.0.0/home.mdx +37 -0
  70. package/templates/jbrains-docs/docs/v1.0.0/tools/_category_.json +8 -0
  71. package/templates/jbrains-docs/docs/v1.0.0/tools/build-tools.mdx +165 -0
  72. package/templates/jbrains-docs/docs/v1.0.0/tools/testing.mdx +112 -0
  73. package/templates/jbrains-docs/docs/v2.0.0/advanced/_category_.json +8 -0
  74. package/templates/jbrains-docs/docs/v2.0.0/advanced/async.mdx +95 -0
  75. package/templates/jbrains-docs/docs/v2.0.0/advanced/generics.mdx +126 -0
  76. package/templates/jbrains-docs/docs/v2.0.0/basics/_category_.json +8 -0
  77. package/templates/jbrains-docs/docs/v2.0.0/basics/control-flow.mdx +106 -0
  78. package/templates/jbrains-docs/docs/v2.0.0/basics/syntax.mdx +129 -0
  79. package/templates/jbrains-docs/docs/v2.0.0/basics/types.mdx +135 -0
  80. package/templates/jbrains-docs/docs/v2.0.0/getting-started.mdx +111 -0
  81. package/templates/jbrains-docs/docs/v2.0.0/home.mdx +37 -0
  82. package/templates/jbrains-docs/docs/v2.0.0/tools/_category_.json +8 -0
  83. package/templates/jbrains-docs/docs/v2.0.0/tools/build-tools.mdx +165 -0
  84. package/templates/jbrains-docs/docs/v2.0.0/tools/testing.mdx +112 -0
  85. package/templates/jbrains-docs/gitignore +7 -0
  86. package/templates/jbrains-docs/package.json +28 -0
  87. package/templates/jbrains-docs/postcss.config.mjs +8 -0
  88. package/templates/jbrains-docs/public/api-specs/openapi-example.json +259 -0
  89. package/templates/jbrains-docs/public/api-specs/postman-example.json +205 -0
  90. package/templates/jbrains-docs/public/api-specs/test-api.json +256 -0
  91. package/templates/jbrains-docs/public/api-specs/users-api.json +264 -0
  92. package/templates/jbrains-docs/specra.config.json +80 -0
  93. package/templates/jbrains-docs/src/app.css +2 -0
  94. package/templates/jbrains-docs/src/app.html +12 -0
  95. package/templates/jbrains-docs/src/routes/+layout.server.ts +11 -0
  96. package/templates/jbrains-docs/src/routes/+layout.svelte +21 -0
  97. package/templates/jbrains-docs/src/routes/+page.server.ts +9 -0
  98. package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
  99. package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
  100. package/templates/jbrains-docs/svelte.config.js +8 -0
  101. package/templates/jbrains-docs/tsconfig.json +12 -0
  102. package/templates/jbrains-docs/vite.config.ts +6 -0
  103. package/templates/minimal/docs/v1.0.0/about.mdx +3 -3
  104. package/templates/minimal/docs/v2.0.0/about.mdx +57 -0
  105. package/templates/minimal/docs/v2.0.0/components/_category_.json +8 -0
  106. package/templates/minimal/docs/v2.0.0/components/callout.mdx +83 -0
  107. package/templates/minimal/docs/v2.0.0/components/code-block.mdx +103 -0
  108. package/templates/minimal/docs/v2.0.0/components/index.mdx +8 -0
  109. package/templates/minimal/docs/v2.0.0/components/tabs.mdx +92 -0
  110. package/templates/minimal/docs/v2.0.0/configuration.mdx +322 -0
  111. package/templates/minimal/docs/v2.0.0/features.mdx +197 -0
  112. package/templates/minimal/docs/v2.0.0/getting-started.mdx +183 -0
  113. package/templates/minimal/gitignore +7 -0
  114. package/templates/minimal/package.json +14 -19
  115. package/templates/minimal/specra.config.json +13 -64
  116. package/templates/minimal/src/app.css +2 -0
  117. package/templates/minimal/src/app.html +12 -0
  118. package/templates/minimal/src/routes/+layout.server.ts +11 -0
  119. package/templates/minimal/src/routes/+layout.svelte +21 -0
  120. package/templates/minimal/src/routes/+page.server.ts +9 -0
  121. package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
  122. package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
  123. package/templates/minimal/svelte.config.js +8 -0
  124. package/templates/minimal/tsconfig.json +6 -35
  125. package/templates/minimal/vite.config.ts +6 -0
  126. package/templates/minimal/README.md +0 -132
  127. package/templates/minimal/app/api/mdx-watch/route.ts +0 -6
  128. package/templates/minimal/app/docs/[version]/[...slug]/loading.tsx +0 -7
  129. package/templates/minimal/app/docs/[version]/[...slug]/page.tsx +0 -192
  130. package/templates/minimal/app/docs/[version]/not-found.tsx +0 -10
  131. package/templates/minimal/app/docs/[version]/page.tsx +0 -27
  132. package/templates/minimal/app/globals.css +0 -1
  133. package/templates/minimal/app/layout.tsx +0 -58
  134. package/templates/minimal/app/not-found.tsx +0 -10
  135. package/templates/minimal/app/page.tsx +0 -179
  136. package/templates/minimal/docs/v1.0.0/index.mdx +0 -29
  137. package/templates/minimal/next.config.mjs +0 -1
  138. package/templates/minimal/package-lock.json +0 -6503
  139. package/templates/minimal/proxy_.ts +0 -22
  140. package/templates/minimal/scripts/generate-redirects.mjs +0 -128
  141. package/templates/minimal/scripts/generate-static-redirects.mjs +0 -115
  142. package/templates/minimal/scripts/index-search.ts +0 -159
  143. package/templates/minimal/scripts/test-search.ts +0 -83
  144. package/templates/minimal/yarn.lock +0 -3940
@@ -0,0 +1,119 @@
1
+ import {
2
+ extractTableOfContents,
3
+ getAdjacentDocs,
4
+ isCategoryPage,
5
+ getCachedVersions,
6
+ getCachedAllDocs,
7
+ getCachedDocBySlug,
8
+ getI18nConfig,
9
+ getConfig,
10
+ } from 'specra';
11
+ import type { PageServerLoad } from './$types';
12
+
13
+ export const load: PageServerLoad = async ({ params }) => {
14
+ const { version, slug: slugArray } = params;
15
+ const slug = slugArray;
16
+
17
+ const i18nConfig = getI18nConfig();
18
+ const slugParts = slug.split('/');
19
+ let locale: string | undefined;
20
+ if (i18nConfig && i18nConfig.locales.includes(slugParts[0])) {
21
+ locale = slugParts[0];
22
+ }
23
+
24
+ const allDocs = await getCachedAllDocs(version, locale);
25
+ const versions = getCachedVersions();
26
+ const config = getConfig();
27
+ const isCategory = isCategoryPage(slug, allDocs);
28
+ const doc = await getCachedDocBySlug(slug, version);
29
+
30
+ let title = 'Page Not Found';
31
+ let description = 'The requested documentation page could not be found.';
32
+ let ogUrl = `/docs/${version}/${slug}`;
33
+
34
+ if (doc) {
35
+ title = doc.meta.title || doc.title;
36
+ description = doc.meta.description || `Documentation for ${title}`;
37
+ }
38
+
39
+ // Category page without doc content
40
+ if (!doc && isCategory) {
41
+ const categoryDoc = allDocs.find((d) => d.slug.startsWith(slug + '/'));
42
+ const categoryTabGroup = categoryDoc?.meta?.tab_group || categoryDoc?.categoryTabGroup;
43
+ const categoryTitle = slug
44
+ .split('/')
45
+ .pop()
46
+ ?.replace(/-/g, ' ')
47
+ .replace(/\b\w/g, (l) => l.toUpperCase()) || 'Category';
48
+
49
+ return {
50
+ version,
51
+ slug,
52
+ allDocs,
53
+ versions,
54
+ config,
55
+ isCategory: true,
56
+ isNotFound: false,
57
+ doc: null,
58
+ categoryTitle,
59
+ categoryDescription: 'Browse the documentation in this section.',
60
+ categoryTabGroup,
61
+ toc: [],
62
+ previous: null,
63
+ next: null,
64
+ title,
65
+ description,
66
+ ogUrl,
67
+ };
68
+ }
69
+
70
+ // Not found
71
+ if (!doc) {
72
+ return {
73
+ version,
74
+ slug,
75
+ allDocs,
76
+ versions,
77
+ config,
78
+ isCategory: false,
79
+ isNotFound: true,
80
+ doc: null,
81
+ categoryTitle: null,
82
+ categoryDescription: null,
83
+ categoryTabGroup: undefined,
84
+ toc: [],
85
+ previous: null,
86
+ next: null,
87
+ title,
88
+ description,
89
+ ogUrl,
90
+ };
91
+ }
92
+
93
+ // Normal doc page
94
+ const toc = extractTableOfContents(doc.meta.content || doc.content);
95
+ const { previous, next } = getAdjacentDocs(slug, allDocs);
96
+ const showCategoryIndex = isCategory && !!doc;
97
+ const matchingDoc = allDocs.find((d) => d.slug === slug);
98
+ const currentPageTabGroup = doc.meta?.tab_group || matchingDoc?.categoryTabGroup;
99
+
100
+ return {
101
+ version,
102
+ slug,
103
+ allDocs,
104
+ versions,
105
+ config,
106
+ isCategory: showCategoryIndex,
107
+ isNotFound: false,
108
+ doc,
109
+ categoryTitle: null,
110
+ categoryDescription: null,
111
+ categoryTabGroup: currentPageTabGroup,
112
+ toc,
113
+ previous: previous ? { title: previous.meta.title, slug: previous.slug } : null,
114
+ next: next ? { title: next.meta.title, slug: next.slug } : null,
115
+ title,
116
+ description,
117
+ ogUrl,
118
+ };
119
+ };
@@ -0,0 +1,129 @@
1
+ <script lang="ts">
2
+ import {
3
+ TableOfContents,
4
+ Header,
5
+ DocLayout,
6
+ CategoryIndex,
7
+ HotReloadIndicator,
8
+ DevModeBadge,
9
+ MdxHotReload,
10
+ MdxContent,
11
+ NotFoundContent,
12
+ SearchHighlight,
13
+ MobileDocLayout,
14
+ mdxComponents,
15
+ } from 'specra/components';
16
+ import type { PageData } from './$types';
17
+
18
+ let { data }: { data: PageData } = $props();
19
+
20
+ let allDocsCompat: any[] = $derived(data.allDocs);
21
+ let previousDoc = $derived(data.previous ?? undefined);
22
+ let nextDoc = $derived(data.next ?? undefined);
23
+ let categoryTitle = $derived(data.categoryTitle ?? undefined);
24
+ let categoryDescription = $derived(data.categoryDescription ?? undefined);
25
+ </script>
26
+
27
+ <svelte:head>
28
+ <title>{data.title}</title>
29
+ <meta name="description" content={data.description} />
30
+ <meta property="og:title" content={data.title} />
31
+ <meta property="og:description" content={data.description} />
32
+ <meta property="og:url" content={data.ogUrl} />
33
+ <meta property="og:type" content="article" />
34
+ <meta name="twitter:card" content="summary_large_image" />
35
+ <meta name="twitter:title" content={data.title} />
36
+ <meta name="twitter:description" content={data.description} />
37
+ </svelte:head>
38
+
39
+ {#if !data.doc && data.isCategory}
40
+ <MobileDocLayout
41
+ docs={allDocsCompat}
42
+ version={data.version}
43
+ config={data.config}
44
+ activeTabGroup={data.categoryTabGroup}
45
+ >
46
+ {#snippet header()}
47
+ <Header currentVersion={data.version} versions={data.versions} config={data.config} />
48
+ {/snippet}
49
+ <CategoryIndex
50
+ categoryPath={data.slug}
51
+ version={data.version}
52
+ allDocs={allDocsCompat}
53
+ title={categoryTitle}
54
+ description={categoryDescription}
55
+ config={data.config}
56
+ />
57
+ </MobileDocLayout>
58
+ <MdxHotReload />
59
+ <HotReloadIndicator />
60
+ <DevModeBadge />
61
+ {:else if data.isNotFound}
62
+ <MobileDocLayout
63
+ docs={allDocsCompat}
64
+ version={data.version}
65
+ config={data.config}
66
+ >
67
+ {#snippet header()}
68
+ <Header currentVersion={data.version} versions={data.versions} config={data.config} />
69
+ {/snippet}
70
+ <NotFoundContent version={data.version} />
71
+ </MobileDocLayout>
72
+ <MdxHotReload />
73
+ <HotReloadIndicator />
74
+ <DevModeBadge />
75
+ {:else if data.doc}
76
+ <MobileDocLayout
77
+ docs={allDocsCompat}
78
+ version={data.version}
79
+ config={data.config}
80
+ activeTabGroup={data.categoryTabGroup}
81
+ >
82
+ {#snippet header()}
83
+ <Header currentVersion={data.version} versions={data.versions} config={data.config} />
84
+ {/snippet}
85
+ {#snippet toc()}
86
+ {#if !data.isCategory}
87
+ <TableOfContents items={data.toc} config={data.config} />
88
+ {/if}
89
+ {/snippet}
90
+
91
+ {#if data.isCategory}
92
+ {#snippet categoryContent()}
93
+ {#if data.doc?.contentNodes}
94
+ <MdxContent nodes={data.doc.contentNodes} components={mdxComponents} />
95
+ {:else if data.doc?.content}
96
+ {@html data.doc.content}
97
+ {/if}
98
+ {/snippet}
99
+ <CategoryIndex
100
+ categoryPath={data.slug}
101
+ version={data.version}
102
+ allDocs={allDocsCompat}
103
+ title={data.doc.meta.title}
104
+ description={data.doc.meta.description}
105
+ content={categoryContent}
106
+ config={data.config}
107
+ />
108
+ {:else}
109
+ <SearchHighlight />
110
+ <DocLayout
111
+ meta={data.doc.meta}
112
+ previousDoc={previousDoc}
113
+ nextDoc={nextDoc}
114
+ version={data.version}
115
+ slug={data.slug}
116
+ config={data.config}
117
+ >
118
+ {#if data.doc.contentNodes}
119
+ <MdxContent nodes={data.doc.contentNodes} components={mdxComponents} />
120
+ {:else}
121
+ {@html data.doc.content}
122
+ {/if}
123
+ </DocLayout>
124
+ {/if}
125
+ </MobileDocLayout>
126
+ <MdxHotReload />
127
+ <HotReloadIndicator />
128
+ <DevModeBadge />
129
+ {/if}
@@ -0,0 +1,8 @@
1
+ import { specraConfig } from 'specra/svelte-config';
2
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3
+
4
+ const config = specraConfig({
5
+ vitePreprocess: { vitePreprocess }
6
+ });
7
+
8
+ export default config;
@@ -1,41 +1,12 @@
1
1
  {
2
+ "extends": "./.svelte-kit/tsconfig.json",
2
3
  "compilerOptions": {
3
- "lib": [
4
- "dom",
5
- "dom.iterable",
6
- "esnext"
7
- ],
8
4
  "allowJs": true,
9
- "target": "ES6",
10
- "skipLibCheck": true,
11
- "strict": true,
12
- "noEmit": true,
5
+ "checkJs": true,
13
6
  "esModuleInterop": true,
14
- "module": "esnext",
15
- "moduleResolution": "bundler",
7
+ "forceConsistentCasingInFileNames": true,
16
8
  "resolveJsonModule": true,
17
- "isolatedModules": true,
18
- "jsx": "react-jsx",
19
- "incremental": true,
20
- "plugins": [
21
- {
22
- "name": "next"
23
- }
24
- ],
25
- "paths": {
26
- "@/*": [
27
- "./*"
28
- ]
29
- }
30
- },
31
- "include": [
32
- "next-env.d.ts",
33
- "**/*.ts",
34
- "**/*.tsx",
35
- ".next/types/**/*.ts",
36
- ".next/dev/types/**/*.ts"
37
- ],
38
- "exclude": [
39
- "node_modules"
40
- ]
9
+ "skipLibCheck": true,
10
+ "strict": true
11
+ }
41
12
  }
@@ -0,0 +1,6 @@
1
+ import { sveltekit } from '@sveltejs/kit/vite';
2
+ import { defineConfig } from 'vite';
3
+
4
+ export default defineConfig({
5
+ plugins: [sveltekit()]
6
+ });
@@ -1,132 +0,0 @@
1
- # Specra Documentation Site
2
-
3
- Welcome to your new Specra documentation site! This project was created with `create-specra`.
4
-
5
- ## Getting Started
6
-
7
- First, install dependencies and run the development server:
8
-
9
- ```bash
10
- npm install
11
- npm run dev
12
- # or
13
- yarn install
14
- yarn dev
15
- # or
16
- pnpm install
17
- pnpm dev
18
- ```
19
-
20
- Open [http://localhost:3000](http://localhost:3000) with your browser to see your documentation site.
21
-
22
- ## Project Structure
23
-
24
- ```
25
- ├── app/ # Next.js app directory
26
- │ ├── layout.tsx # Root layout
27
- │ ├── page.tsx # Home page
28
- │ └── docs/ # Documentation pages
29
- ├── components/ # Reusable components
30
- │ ├── docs/ # Documentation-specific components
31
- │ └── ui/ # UI components
32
- ├── docs/ # Your MDX documentation files
33
- │ └── v1.0.0/ # Version 1.0.0 docs
34
- ├── lib/ # Utility functions
35
- │ ├── mdx.ts # MDX processing
36
- │ ├── config.ts # Configuration
37
- │ └── parsers/ # API parsers
38
- ├── public/ # Static assets
39
- └── specra.config.json # Specra configuration
40
- ```
41
-
42
- ## Writing Documentation
43
-
44
- Add your MDX files in the `docs/v1.0.0/` directory:
45
-
46
- ```mdx
47
- ---
48
- title: My Page
49
- description: This is my documentation page
50
- ---
51
-
52
- # My Page
53
-
54
- Your content here...
55
- ```
56
-
57
- ### Using Components
58
-
59
- Import and use components in your MDX:
60
-
61
- ```mdx
62
- import { Callout } from '@/components/docs/callout'
63
- import { CodeBlock } from '@/components/docs/code-block'
64
- import { Tabs, Tab } from '@/components/docs/tabs'
65
-
66
- <Callout type="info">
67
- This is an info callout!
68
- </Callout>
69
-
70
- <Tabs>
71
- <Tab title="JavaScript">
72
- ```js
73
- console.log('Hello World')
74
- ```
75
- </Tab>
76
- <Tab title="TypeScript">
77
- ```ts
78
- console.log('Hello World')
79
- ```
80
- </Tab>
81
- </Tabs>
82
- ```
83
-
84
- ## Configuration
85
-
86
- Edit `specra.config.json` to customize your site:
87
-
88
- ```json
89
- {
90
- "site": {
91
- "title": "Your Docs",
92
- "description": "Your documentation site",
93
- "url": "https://yourdocs.com"
94
- },
95
- "navigation": {
96
- "links": [
97
- { "title": "Home", "href": "/" },
98
- { "title": "Docs", "href": "/docs" }
99
- ]
100
- }
101
- }
102
- ```
103
-
104
- ## Building for Production
105
-
106
- ```bash
107
- npm run build
108
- npm run start
109
- ```
110
-
111
- ## Learn More
112
-
113
- - [Specra Documentation](https://specra.dev/docs)
114
- - [Next.js Documentation](https://nextjs.org/docs)
115
- - [MDX Documentation](https://mdxjs.com)
116
-
117
- ## Deployment
118
-
119
- Deploy your Specra documentation site to Vercel, Netlify, or any hosting platform that supports Next.js.
120
-
121
- ### Vercel
122
-
123
- [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new)
124
-
125
- ### Netlify
126
-
127
- [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start)
128
-
129
- ## Need Help?
130
-
131
- - Check the [documentation](https://specra.dev/docs)
132
- - Report issues on [GitHub](https://github.com/yourusername/specra/issues)
@@ -1,6 +0,0 @@
1
- // Next.js requires dynamic to be statically analyzable, so we can't re-export it
2
- export const dynamic = 'error'
3
- export const runtime = 'nodejs'
4
-
5
- // Re-export the GET handler from SDK
6
- export { GET } from "specra/app/api/mdx-watch"
@@ -1,7 +0,0 @@
1
- export default function Loading() {
2
- return (
3
- <div className="flex items-center justify-center min-h-screen">
4
- <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-gray-900" />
5
- </div>
6
- )
7
- }
@@ -1,192 +0,0 @@
1
- import type { Metadata } from "next"
2
- import { Suspense } from "react"
3
- import {
4
- extractTableOfContents,
5
- getAdjacentDocs,
6
- isCategoryPage,
7
- getCachedVersions,
8
- getCachedAllDocs,
9
- getCachedDocBySlug,
10
- getConfig,
11
- } from "specra/lib"
12
- import {
13
- DocLayout,
14
- TableOfContents,
15
- Header,
16
- DocLayoutWrapper,
17
- HotReloadIndicator,
18
- DevModeBadge,
19
- MdxHotReload,
20
- CategoryIndex,
21
- NotFoundContent,
22
- DocLoading,
23
- } from "specra/components"
24
-
25
- interface PageProps {
26
- params: Promise<{
27
- version: string
28
- slug: string[]
29
- }>
30
- }
31
-
32
- export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
33
- const { version, slug: slugArray } = await params
34
- const slug = slugArray.join("/")
35
- const doc = await getCachedDocBySlug(slug, version)
36
-
37
- if (!doc) {
38
- return {
39
- title: "Page Not Found",
40
- description: "The requested documentation page could not be found.",
41
- }
42
- }
43
-
44
- const title = doc.meta.title || doc.title
45
- const description = doc.meta.description || `Documentation for ${title}`
46
- const url = `/docs/${version}/${slug}`
47
-
48
- return {
49
- title: `${title}`,
50
- description,
51
- openGraph: {
52
- title,
53
- description,
54
- url,
55
- siteName: "Documentation Platform",
56
- type: "article",
57
- locale: "en_US",
58
- },
59
- twitter: {
60
- card: "summary_large_image",
61
- title,
62
- description,
63
- },
64
- alternates: {
65
- canonical: url,
66
- },
67
- }
68
- }
69
-
70
- export async function generateStaticParams() {
71
- const versions = getCachedVersions()
72
- const params = []
73
-
74
- for (const version of versions) {
75
- const docs = await getCachedAllDocs(version)
76
- for (const doc of docs) {
77
- params.push({
78
- version,
79
- slug: doc.slug.split("/").filter(Boolean),
80
- })
81
- }
82
- }
83
-
84
- return params
85
- }
86
-
87
- export default async function DocPage({ params }: PageProps) {
88
- const { version, slug: slugArray } = await params
89
- const slug = slugArray.join("/")
90
-
91
- const allDocs = await getCachedAllDocs(version)
92
- const versions = getCachedVersions()
93
- const config = getConfig()
94
- const isCategory = isCategoryPage(slug, allDocs)
95
- const doc = await getCachedDocBySlug(slug, version)
96
-
97
- if (!doc && isCategory) {
98
- const categoryDoc = allDocs.find((d) => d.slug.startsWith(slug + "/"))
99
- const categoryTabGroup = categoryDoc?.meta?.tab_group || categoryDoc?.categoryTabGroup
100
-
101
- return (
102
- <>
103
- <DocLayoutWrapper
104
- header={<Header currentVersion={version} versions={versions} config={config} />}
105
- docs={allDocs}
106
- version={version}
107
- children={
108
- <CategoryIndex
109
- categoryPath={slug}
110
- version={version}
111
- allDocs={allDocs}
112
- title={slug.split("/").pop()?.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()) || "Category"}
113
- description="Browse the documentation in this section."
114
- config={config}
115
- />
116
- }
117
- toc={<div />}
118
- config={config}
119
- currentPageTabGroup={categoryTabGroup}
120
- />
121
- <MdxHotReload />
122
- <HotReloadIndicator />
123
- <DevModeBadge />
124
- </>
125
- )
126
- }
127
-
128
- if (!doc) {
129
- return (
130
- <>
131
- <Suspense fallback={<DocLoading />}>
132
- <DocLayoutWrapper
133
- header={<Header currentVersion={version} versions={versions} config={config} />}
134
- docs={allDocs}
135
- version={version}
136
- children={<NotFoundContent version={version} />}
137
- toc={<div />}
138
- config={config}
139
- currentPageTabGroup={undefined}
140
- />
141
- <MdxHotReload />
142
- <HotReloadIndicator />
143
- <DevModeBadge />
144
- </Suspense>
145
- </>
146
- )
147
- }
148
-
149
- const toc = extractTableOfContents(doc.content)
150
- const { previous, next } = getAdjacentDocs(slug, allDocs)
151
- const showCategoryIndex = isCategory && doc
152
- const currentPageTabGroup = doc.meta?.tab_group || doc.categoryTabGroup
153
-
154
- return (
155
- <>
156
- <Suspense fallback={<DocLoading />}>
157
- <DocLayoutWrapper
158
- header={<Header currentVersion={version} versions={versions} config={config} />}
159
- docs={allDocs}
160
- version={version}
161
- toc={showCategoryIndex ? <div /> : <TableOfContents items={toc} config={config} />}
162
- config={config}
163
- currentPageTabGroup={currentPageTabGroup}
164
- >
165
- {showCategoryIndex ? (
166
- <CategoryIndex
167
- categoryPath={slug}
168
- version={version}
169
- allDocs={allDocs}
170
- title={doc.meta.title}
171
- description={doc.meta.description}
172
- content={doc.content}
173
- config={config}
174
- />
175
- ) : (
176
- <DocLayout
177
- meta={doc.meta}
178
- content={doc.content}
179
- previousDoc={previous ? { title: previous.meta.title, slug: previous.slug } : undefined}
180
- nextDoc={next ? { title: next.meta.title, slug: next.slug } : undefined}
181
- version={version}
182
- slug={slug}
183
- config={config}
184
- />
185
- )}
186
- </DocLayoutWrapper>
187
- <MdxHotReload />
188
- <HotReloadIndicator />
189
- </Suspense>
190
- </>
191
- )
192
- }
@@ -1,10 +0,0 @@
1
-
2
- import { VersionNotFound } from "specra/components"
3
-
4
- export default function NotFound() {
5
- return (
6
- <>
7
- <VersionNotFound />
8
- </>
9
- )
10
- }
@@ -1,27 +0,0 @@
1
- import { redirect } from "next/navigation"
2
- import { getCachedVersions, getCachedAllDocs } from "specra/lib"
3
-
4
- interface PageProps {
5
- params: Promise<{
6
- version: string
7
- }>
8
- }
9
-
10
- export async function generateStaticParams() {
11
- const versions = getCachedVersions()
12
- return versions.map((version) => ({
13
- version,
14
- }))
15
- }
16
-
17
- export default async function VersionIndexPage({ params }: PageProps) {
18
- const { version } = await params
19
- const docs = await getCachedAllDocs(version)
20
-
21
- if (docs.length === 0) {
22
- redirect("/docs/v1.0.0")
23
- }
24
-
25
- // Redirect to first doc
26
- redirect(`/docs/${version}/${docs[0].slug}`)
27
- }
@@ -1 +0,0 @@
1
- @import "specra/styles";