@dominikcz/greg 0.9.27
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 +397 -0
- package/bin/greg.js +241 -0
- package/bin/init.js +351 -0
- package/bin/templates/docs/getting-started.md +47 -0
- package/bin/templates/docs/index.md +11 -0
- package/bin/templates/greg.config.js +39 -0
- package/bin/templates/greg.config.ts +38 -0
- package/bin/templates/index.html +16 -0
- package/bin/templates/src/App.svelte +5 -0
- package/bin/templates/src/app.css +20 -0
- package/bin/templates/src/main.js +9 -0
- package/bin/templates/svelte.config.js +1 -0
- package/bin/templates/tsconfig.json +21 -0
- package/bin/templates/vite.config.js +23 -0
- package/docs/__partials/markdown/examples/basic.md +4 -0
- package/docs/__partials/markdown/examples/diff.md +10 -0
- package/docs/__partials/markdown/examples/focus.md +5 -0
- package/docs/__partials/markdown/examples/language-title.md +3 -0
- package/docs/__partials/markdown/examples/line-highlighting.md +5 -0
- package/docs/__partials/markdown/examples/line-numbers.md +5 -0
- package/docs/__partials/note.md +4 -0
- package/docs/guide/__shared-warning.md +4 -0
- package/docs/guide/asset-handling.md +88 -0
- package/docs/guide/deploying.md +162 -0
- package/docs/guide/getting-started.md +334 -0
- package/docs/guide/index.md +23 -0
- package/docs/guide/localization.md +290 -0
- package/docs/guide/markdown/code.md +95 -0
- package/docs/guide/markdown/components-and-mermaid.md +43 -0
- package/docs/guide/markdown/containers.md +110 -0
- package/docs/guide/markdown/header-anchors.md +34 -0
- package/docs/guide/markdown/includes.md +84 -0
- package/docs/guide/markdown/index.md +20 -0
- package/docs/guide/markdown/inline-attributes.md +21 -0
- package/docs/guide/markdown/links-and-toc.md +64 -0
- package/docs/guide/markdown/math.md +54 -0
- package/docs/guide/markdown/syntax-highlighting.md +75 -0
- package/docs/guide/routing.md +150 -0
- package/docs/guide/using-svelte.md +88 -0
- package/docs/guide/versioning.md +281 -0
- package/docs/incompatibilities.md +48 -0
- package/docs/index.md +43 -0
- package/docs/reference/badge.md +100 -0
- package/docs/reference/carbon-ads.md +46 -0
- package/docs/reference/code-group.md +126 -0
- package/docs/reference/home-page.md +232 -0
- package/docs/reference/index.md +18 -0
- package/docs/reference/markdowndocs.md +275 -0
- package/docs/reference/outline.md +79 -0
- package/docs/reference/search.md +263 -0
- package/docs/reference/steps.md +200 -0
- package/docs/reference/team-page.md +189 -0
- package/docs/reference/theme.md +150 -0
- package/fakeDocsGenerator/generate_docs.js +310 -0
- package/package.json +92 -0
- package/scripts/build-versions.js +609 -0
- package/scripts/generate-static.js +79 -0
- package/scripts/render-markdown.js +420 -0
- package/src/lib/MarkdownDocs/AiChat.svelte +936 -0
- package/src/lib/MarkdownDocs/BackToTop.svelte +68 -0
- package/src/lib/MarkdownDocs/Breadcrumb.svelte +68 -0
- package/src/lib/MarkdownDocs/DocsNavigation.svelte +149 -0
- package/src/lib/MarkdownDocs/DocsSiteHeader.svelte +758 -0
- package/src/lib/MarkdownDocs/DocsVersionSwitcher.svelte +103 -0
- package/src/lib/MarkdownDocs/MarkdownDocs.svelte +2115 -0
- package/src/lib/MarkdownDocs/MarkdownRenderer.svelte +487 -0
- package/src/lib/MarkdownDocs/Outline.svelte +238 -0
- package/src/lib/MarkdownDocs/PrevNext.svelte +115 -0
- package/src/lib/MarkdownDocs/SearchModal.svelte +1241 -0
- package/src/lib/MarkdownDocs/TreeView.svelte +32 -0
- package/src/lib/MarkdownDocs/TreeViewItem.svelte +219 -0
- package/src/lib/MarkdownDocs/VersionOutdatedNotice.svelte +72 -0
- package/src/lib/MarkdownDocs/__tests__/codeDirectives.test.js +54 -0
- package/src/lib/MarkdownDocs/__tests__/common.test.js +41 -0
- package/src/lib/MarkdownDocs/__tests__/docsExamplesLint.test.js +77 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/__partial-basic.md +3 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/snippet.js +9 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/includes/part.md +11 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/includes/wrapper.md +5 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.js +8 -0
- package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.md +5 -0
- package/src/lib/MarkdownDocs/__tests__/helpers.js +67 -0
- package/src/lib/MarkdownDocs/__tests__/localeUtils.test.js +204 -0
- package/src/lib/MarkdownDocs/__tests__/markdown.test.js +704 -0
- package/src/lib/MarkdownDocs/__tests__/markdownRendererRuntime.test.js +65 -0
- package/src/lib/MarkdownDocs/__tests__/searchIndexBuilder.test.js +117 -0
- package/src/lib/MarkdownDocs/__tests__/sqliteStore.test.js +202 -0
- package/src/lib/MarkdownDocs/__tests__/useRouter.test.js +16 -0
- package/src/lib/MarkdownDocs/ai/adapters/customAdapter.js +14 -0
- package/src/lib/MarkdownDocs/ai/adapters/customAdapter.ts +43 -0
- package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.js +81 -0
- package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.ts +116 -0
- package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.js +92 -0
- package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.ts +137 -0
- package/src/lib/MarkdownDocs/ai/aiProvider.ts +31 -0
- package/src/lib/MarkdownDocs/ai/characters.js +52 -0
- package/src/lib/MarkdownDocs/ai/characters.ts +69 -0
- package/src/lib/MarkdownDocs/ai/chunkStore.ts +25 -0
- package/src/lib/MarkdownDocs/ai/chunker.js +85 -0
- package/src/lib/MarkdownDocs/ai/chunker.ts +135 -0
- package/src/lib/MarkdownDocs/ai/docLinker.js +26 -0
- package/src/lib/MarkdownDocs/ai/docLinker.ts +36 -0
- package/src/lib/MarkdownDocs/ai/promptBuilder.js +33 -0
- package/src/lib/MarkdownDocs/ai/promptBuilder.ts +53 -0
- package/src/lib/MarkdownDocs/ai/ragPipeline.js +54 -0
- package/src/lib/MarkdownDocs/ai/ragPipeline.ts +106 -0
- package/src/lib/MarkdownDocs/ai/stores/memoryStore.js +88 -0
- package/src/lib/MarkdownDocs/ai/stores/memoryStore.ts +112 -0
- package/src/lib/MarkdownDocs/ai/stores/sqliteStore.ts +372 -0
- package/src/lib/MarkdownDocs/ai/types.ts +71 -0
- package/src/lib/MarkdownDocs/aiServer.js +288 -0
- package/src/lib/MarkdownDocs/codeDirectives.js +191 -0
- package/src/lib/MarkdownDocs/codeFenceInfo.js +45 -0
- package/src/lib/MarkdownDocs/codeGroup.ts +46 -0
- package/src/lib/MarkdownDocs/common.ts +47 -0
- package/src/lib/MarkdownDocs/docsUtils.js +281 -0
- package/src/lib/MarkdownDocs/index.plugins.js +22 -0
- package/src/lib/MarkdownDocs/layouts/LayoutDoc.svelte +8 -0
- package/src/lib/MarkdownDocs/layouts/LayoutHome.svelte +58 -0
- package/src/lib/MarkdownDocs/layouts/LayoutPage.svelte +9 -0
- package/src/lib/MarkdownDocs/loadGregConfig.js +82 -0
- package/src/lib/MarkdownDocs/localeUtils.ts +682 -0
- package/src/lib/MarkdownDocs/markdownRendererRuntime.ts +314 -0
- package/src/lib/MarkdownDocs/mermaidThemes.js +319 -0
- package/src/lib/MarkdownDocs/navigationUtils.js +22 -0
- package/src/lib/MarkdownDocs/rehypeCodeGroup.js +326 -0
- package/src/lib/MarkdownDocs/rehypeCodeTitle.js +96 -0
- package/src/lib/MarkdownDocs/rehypeToc.js +170 -0
- package/src/lib/MarkdownDocs/remarkCodeMeta.js +22 -0
- package/src/lib/MarkdownDocs/remarkContainers.js +329 -0
- package/src/lib/MarkdownDocs/remarkCustomAnchors.js +42 -0
- package/src/lib/MarkdownDocs/remarkEscapeSvelte.js +33 -0
- package/src/lib/MarkdownDocs/remarkGlobalComponents.js +65 -0
- package/src/lib/MarkdownDocs/remarkImports.js +461 -0
- package/src/lib/MarkdownDocs/remarkImportsBrowser.js +349 -0
- package/src/lib/MarkdownDocs/remarkInlineAttrs.js +95 -0
- package/src/lib/MarkdownDocs/remarkMathToHtml.js +138 -0
- package/src/lib/MarkdownDocs/searchIndexBuilder.js +497 -0
- package/src/lib/MarkdownDocs/searchServer.js +263 -0
- package/src/lib/MarkdownDocs/treeViewTypes.ts +11 -0
- package/src/lib/MarkdownDocs/useRouter.svelte.ts +114 -0
- package/src/lib/MarkdownDocs/useSplitter.svelte.ts +33 -0
- package/src/lib/MarkdownDocs/versioningDefaults.js +20 -0
- package/src/lib/MarkdownDocs/vitePluginAiServer.js +204 -0
- package/src/lib/MarkdownDocs/vitePluginCopyDocs.js +153 -0
- package/src/lib/MarkdownDocs/vitePluginFrontmatter.js +109 -0
- package/src/lib/MarkdownDocs/vitePluginGregConfig.js +108 -0
- package/src/lib/MarkdownDocs/vitePluginSearchIndex.js +57 -0
- package/src/lib/MarkdownDocs/vitePluginSearchServer.js +190 -0
- package/src/lib/components/Badge.svelte +59 -0
- package/src/lib/components/Button.svelte +138 -0
- package/src/lib/components/CarbonAds.svelte +99 -0
- package/src/lib/components/CodeGroup.svelte +102 -0
- package/src/lib/components/Feature.svelte +209 -0
- package/src/lib/components/Features.svelte +123 -0
- package/src/lib/components/Hero.svelte +399 -0
- package/src/lib/components/Image.svelte +128 -0
- package/src/lib/components/Link.svelte +105 -0
- package/src/lib/components/SocialLink.svelte +84 -0
- package/src/lib/components/SocialLinks.svelte +33 -0
- package/src/lib/components/Steps.svelte +143 -0
- package/src/lib/components/TeamMember.svelte +273 -0
- package/src/lib/components/TeamMembers.svelte +81 -0
- package/src/lib/components/TeamPage.svelte +65 -0
- package/src/lib/components/TeamPageSection.svelte +108 -0
- package/src/lib/components/TeamPageTitle.svelte +89 -0
- package/src/lib/components/index.js +24 -0
- package/src/lib/portal/context.js +12 -0
- package/src/lib/portal/index.js +3 -0
- package/src/lib/portal/portal.svelte +14 -0
- package/src/lib/portal/slot.svelte +8 -0
- package/src/lib/scss/__code.scss +128 -0
- package/src/lib/scss/__containers.scss +99 -0
- package/src/lib/scss/__markdown.scss +447 -0
- package/src/lib/scss/__scrollbar.scss +60 -0
- package/src/lib/scss/__steps.scss +100 -0
- package/src/lib/scss/__theme.scss +238 -0
- package/src/lib/scss/__toc.scss +55 -0
- package/src/lib/scss/__utilities.scss +7 -0
- package/src/lib/scss/greg.scss +9 -0
- package/src/lib/spinner/spinner.svelte +42 -0
- package/svelte.config.js +146 -0
- package/types/index.d.ts +456 -0
package/README.md
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# Greg
|
|
2
|
+
|
|
3
|
+
Svelte 5 + Vite-powered documentation engine. Write Markdown, get a beautiful documentation site — hot-reloaded in milliseconds.
|
|
4
|
+
|
|
5
|
+
Inspired by [VitePress](https://vitepress.dev){target="_blank"}, built on Svelte 5.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npx @dominikcz/greg init
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For unattended/default setup (no prompts):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npx @dominikcz/greg init --defaults
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The interactive wizard will ask for docs path, site title, TypeScript preference, and the type of initial documentation (empty, sample, or generated fake docs). It can also install all required dependencies for you.
|
|
20
|
+
|
|
21
|
+
At the end you only need:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm run dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
In this repository, prefer `npm run ...` scripts for development.
|
|
28
|
+
In consumer projects using Greg, use `greg ...` (typically via npm scripts) or `npx greg ...`.
|
|
29
|
+
|
|
30
|
+
## Manual installation
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install --save-dev @dominikcz/greg @sveltejs/vite-plugin-svelte svelte vite
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If your `package.json` does not already define module type, set:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"type": "module"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**`vite.config.js`**
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import { defineConfig } from 'vite'
|
|
48
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
|
49
|
+
import {
|
|
50
|
+
vitePluginGregConfig,
|
|
51
|
+
vitePluginSearchIndex,
|
|
52
|
+
vitePluginSearchServer,
|
|
53
|
+
vitePluginFrontmatter,
|
|
54
|
+
vitePluginCopyDocs,
|
|
55
|
+
} from '@dominikcz/greg/plugins'
|
|
56
|
+
|
|
57
|
+
export default defineConfig({
|
|
58
|
+
plugins: [
|
|
59
|
+
svelte(),
|
|
60
|
+
vitePluginGregConfig(),
|
|
61
|
+
vitePluginSearchIndex({ docsDir: 'docs', srcDir: '/' }),
|
|
62
|
+
vitePluginSearchServer({ docsDir: 'docs', srcDir: '/' }),
|
|
63
|
+
vitePluginFrontmatter({ docsDir: 'docs', srcDir: '/' }),
|
|
64
|
+
vitePluginCopyDocs({ docsDir: 'docs', srcDir: '/' }),
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**`svelte.config.js`** (must be `.js` — not `.ts`)
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
export { default } from '@dominikcz/greg/svelte.config'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**`greg.config.js`** (or `.ts`)
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
/** @type {import('@dominikcz/greg').GregConfig} */
|
|
79
|
+
export default {
|
|
80
|
+
srcDir: 'docs',
|
|
81
|
+
docsBase: '',
|
|
82
|
+
mainTitle: 'My Docs',
|
|
83
|
+
sidebar: [
|
|
84
|
+
{ text: 'Guide', auto: '/guide' },
|
|
85
|
+
{ text: 'GitHub', link: 'https://github.com/dominikcz/greg' }, // default: _self
|
|
86
|
+
{ text: 'GitHub (new tab)', link: 'https://github.com/dominikcz/greg', target: '_blank' },
|
|
87
|
+
],
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**`src/App.svelte`**
|
|
92
|
+
|
|
93
|
+
```svelte
|
|
94
|
+
<script>
|
|
95
|
+
import MarkdownDocs from '@dominikcz/greg'
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<MarkdownDocs />
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Localization (VitePress-compatible)
|
|
102
|
+
|
|
103
|
+
Greg supports VitePress-style `locales` in `greg.config.js`.
|
|
104
|
+
|
|
105
|
+
- Locale keys use paths like `'/'`, `'/pl/'`, `'/de/'`
|
|
106
|
+
- They are resolved under `docsBase` (URL prefix)
|
|
107
|
+
- Supported per locale: `lang`, `title`, `label`
|
|
108
|
+
- Supported per locale `themeConfig` keys:
|
|
109
|
+
`nav`, `sidebar`, `outline`, `lastUpdatedText`, `langMenuLabel`,
|
|
110
|
+
`sidebarMenuLabel`, `skipToContentLabel`, `returnToTopLabel`,
|
|
111
|
+
`darkModeSwitchLabel`, `lightModeSwitchTitle`, `darkModeSwitchTitle`,
|
|
112
|
+
`docFooter`, `siteTitle`, `logo`, `socialLinks`, `editLink`, `footer`, `aside`, `lastUpdated`
|
|
113
|
+
- Header automatically shows a language switcher when at least two locales are configured
|
|
114
|
+
- `i18nRouting: true` (default) keeps the same relative page when possible
|
|
115
|
+
- `i18nRouting: false` switches directly to locale root
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
/** @type {import('@dominikcz/greg').GregConfig} */
|
|
119
|
+
export default {
|
|
120
|
+
srcDir: 'docs',
|
|
121
|
+
docsBase: '',
|
|
122
|
+
i18nRouting: true,
|
|
123
|
+
locales: {
|
|
124
|
+
'/': {
|
|
125
|
+
lang: 'en-US',
|
|
126
|
+
title: 'My Docs',
|
|
127
|
+
themeConfig: {
|
|
128
|
+
nav: [
|
|
129
|
+
{ text: 'Guide', link: '/guide' },
|
|
130
|
+
{ text: 'Reference', link: '/reference' },
|
|
131
|
+
],
|
|
132
|
+
sidebar: [
|
|
133
|
+
{ text: 'Guide', auto: '/guide' },
|
|
134
|
+
{ text: 'Reference', auto: '/reference' },
|
|
135
|
+
],
|
|
136
|
+
outline: [2, 3],
|
|
137
|
+
lastUpdatedText: 'Last updated:',
|
|
138
|
+
langMenuLabel: 'Change language',
|
|
139
|
+
sidebarMenuLabel: 'Menu',
|
|
140
|
+
skipToContentLabel: 'Skip to content',
|
|
141
|
+
returnToTopLabel: 'Return to top',
|
|
142
|
+
darkModeSwitchLabel: 'Appearance',
|
|
143
|
+
lightModeSwitchTitle: 'Switch to light theme',
|
|
144
|
+
darkModeSwitchTitle: 'Switch to dark theme',
|
|
145
|
+
docFooter: { prev: 'Previous', next: 'Next' },
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
'/pl/': {
|
|
149
|
+
lang: 'pl-PL',
|
|
150
|
+
label: 'Polski',
|
|
151
|
+
title: 'Moje Dokumenty',
|
|
152
|
+
themeConfig: {
|
|
153
|
+
nav: [
|
|
154
|
+
{ text: 'Przewodnik', link: '/pl/guide' },
|
|
155
|
+
{ text: 'Referencja', link: '/pl/reference' },
|
|
156
|
+
],
|
|
157
|
+
sidebar: [
|
|
158
|
+
{ text: 'Przewodnik', auto: '/pl/guide' },
|
|
159
|
+
{ text: 'Referencja', auto: '/pl/reference' },
|
|
160
|
+
],
|
|
161
|
+
outline: { level: [2, 3], label: 'Na tej stronie' },
|
|
162
|
+
lastUpdatedText: 'Zaktualizowano:',
|
|
163
|
+
langMenuLabel: 'Zmien jezyk',
|
|
164
|
+
sidebarMenuLabel: 'Menu',
|
|
165
|
+
skipToContentLabel: 'Przejdz do tresci',
|
|
166
|
+
returnToTopLabel: 'Wroc na gore',
|
|
167
|
+
darkModeSwitchLabel: 'Wyglad',
|
|
168
|
+
lightModeSwitchTitle: 'Przelacz na jasny motyw',
|
|
169
|
+
darkModeSwitchTitle: 'Przelacz na ciemny motyw',
|
|
170
|
+
docFooter: { prev: 'Poprzednia', next: 'Nastepna' },
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## CLI
|
|
178
|
+
|
|
179
|
+
For development in this repository, use `npm run ...` scripts (they call the local CLI entrypoint).
|
|
180
|
+
When Greg is installed in a project, the `greg` command is still available via npm scripts and `npx greg ...`.
|
|
181
|
+
|
|
182
|
+
| Command | Description |
|
|
183
|
+
| --------------------- | ------------------------------------- |
|
|
184
|
+
| `greg init` | Interactive project scaffolding |
|
|
185
|
+
| `greg dev` | Start Vite dev server |
|
|
186
|
+
| `greg build` | Production build (auto versioning) |
|
|
187
|
+
| `greg build:static` | Production build + static export |
|
|
188
|
+
| `greg build:markdown` | Export resolved markdown |
|
|
189
|
+
| `greg preview` | Preview production build |
|
|
190
|
+
| `greg search-server` | Standalone search API server |
|
|
191
|
+
|
|
192
|
+
## Multi-version Docs
|
|
193
|
+
|
|
194
|
+
Greg supports two source strategies configured under `greg.config.* > versioning`:
|
|
195
|
+
|
|
196
|
+
- `branches` (default): reads docs from configured git branches/refs and caches snapshots/builds per commit SHA
|
|
197
|
+
- `folders`: reads docs directly from version folders in the working tree
|
|
198
|
+
|
|
199
|
+
### Rules
|
|
200
|
+
|
|
201
|
+
1. Put all versioning config in `greg.config.js` (or `greg.config.ts`) under `versioning`.
|
|
202
|
+
2. Choose one strategy in `versioning.strategy`.
|
|
203
|
+
3. Map each built version id to its source:
|
|
204
|
+
- branch mode: `versioning.branches[]` with `version` + `branch`
|
|
205
|
+
- folder mode: `versioning.folders[]` with `version` + `dir`
|
|
206
|
+
4. Set `versioning.default` and optional `versioning.aliases` for selector behavior.
|
|
207
|
+
|
|
208
|
+
### Branch Mode Guide
|
|
209
|
+
|
|
210
|
+
Use this when each docs version should come from a Git branch/ref.
|
|
211
|
+
|
|
212
|
+
What to configure:
|
|
213
|
+
|
|
214
|
+
1. `versioning.strategy = 'branches'`
|
|
215
|
+
2. `versioning.branches[]` entries with `version`, `branch`, optional `docsDir`, `title`
|
|
216
|
+
3. `versioning.default` and optional `versioning.aliases`
|
|
217
|
+
|
|
218
|
+
Example `versioning` value:
|
|
219
|
+
|
|
220
|
+
```js [greg.config.js]
|
|
221
|
+
export default {
|
|
222
|
+
versioning: {
|
|
223
|
+
strategy: 'branches',
|
|
224
|
+
default: 'latest',
|
|
225
|
+
aliases: {
|
|
226
|
+
latest: '2.1',
|
|
227
|
+
stable: '2.0'
|
|
228
|
+
},
|
|
229
|
+
branches: [
|
|
230
|
+
{ version: '2.1', branch: 'main', title: '2.1' },
|
|
231
|
+
{ version: '2.0', branch: 'release/2.0', title: '2.0' }
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Folder Mode Guide
|
|
238
|
+
|
|
239
|
+
Use this when each docs version should come from a directory in the working tree.
|
|
240
|
+
|
|
241
|
+
What to configure:
|
|
242
|
+
|
|
243
|
+
1. `versioning.strategy = 'folders'`
|
|
244
|
+
2. `versioning.folders[]` entries with `version`, `dir`, optional `srcDir`, `title`
|
|
245
|
+
3. `versioning.default` and optional `versioning.aliases`
|
|
246
|
+
|
|
247
|
+
Example `versioning` value:
|
|
248
|
+
|
|
249
|
+
```js [greg.config.js]
|
|
250
|
+
export default {
|
|
251
|
+
versioning: {
|
|
252
|
+
strategy: 'folders',
|
|
253
|
+
default: 'latest',
|
|
254
|
+
aliases: {
|
|
255
|
+
latest: '2.1',
|
|
256
|
+
stable: '2.0'
|
|
257
|
+
},
|
|
258
|
+
folders: [
|
|
259
|
+
{ version: '2.1', dir: './docs', title: '2.1' },
|
|
260
|
+
{ version: '2.0', dir: './versions/2.0/docs', title: '2.0' }
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Commands
|
|
267
|
+
|
|
268
|
+
After configuration is in place, run:
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
greg build
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Output is generated to `<outDir>/__versions/<version>` (default `dist/__versions/<version>`) and a manifest is written to `<outDir>/__versions/versions.json`.
|
|
275
|
+
After that, Greg syncs the default version to `dist/` so the root output is directly hostable.
|
|
276
|
+
|
|
277
|
+
Defaults are VitePress-compatible:
|
|
278
|
+
|
|
279
|
+
- `outDir` comes from top-level `greg.config.* > outDir` (default `dist`)
|
|
280
|
+
- manifest path prefix is based on top-level `greg.config.* > base` (default `/`)
|
|
281
|
+
|
|
282
|
+
Optional UI labels/messages can be configured under `versioning.ui`:
|
|
283
|
+
|
|
284
|
+
```js [greg.config.js]
|
|
285
|
+
export default {
|
|
286
|
+
versioning: {
|
|
287
|
+
ui: {
|
|
288
|
+
versionMenuLabel: 'Version',
|
|
289
|
+
manifestUnavailableText: 'Version selector unavailable',
|
|
290
|
+
showManifestUnavailableStatus: false,
|
|
291
|
+
outdatedVersionMessage: 'You are viewing an older version ({current}). Recommended: {default}.',
|
|
292
|
+
outdatedVersionActionLabel: 'Go to latest'
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
To override those labels per locale, use `versioning.locales`:
|
|
299
|
+
|
|
300
|
+
```js [greg.config.js]
|
|
301
|
+
export default {
|
|
302
|
+
versioning: {
|
|
303
|
+
locales: {
|
|
304
|
+
'/': {
|
|
305
|
+
ui: {
|
|
306
|
+
versionMenuLabel: 'Version'
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
'/pl/': {
|
|
310
|
+
ui: {
|
|
311
|
+
versionMenuLabel: 'Wersja'
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Resolution order for versioning UI text is:
|
|
320
|
+
|
|
321
|
+
1. `versioning.locales[active-locale].ui`
|
|
322
|
+
2. `versioning.ui`
|
|
323
|
+
3. built-in default text
|
|
324
|
+
|
|
325
|
+
If `versions.json` cannot be loaded, Greg now shows a subtle fallback text in the header instead of the selector.
|
|
326
|
+
|
|
327
|
+
Example manifest:
|
|
328
|
+
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"default": "latest",
|
|
332
|
+
"versions": [
|
|
333
|
+
{ "version": "2.1", "title": "2.1", "path": "/__versions/2.1/" },
|
|
334
|
+
{ "version": "2.0", "title": "2.0", "path": "/__versions/2.0/" }
|
|
335
|
+
],
|
|
336
|
+
"aliases": {
|
|
337
|
+
"latest": "2.1",
|
|
338
|
+
"stable": "2.0"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Resolved Markdown Export
|
|
344
|
+
|
|
345
|
+
Generate a fully expanded markdown snapshot (all `<!--@include: ...-->` and `<<< ...` resolved)
|
|
346
|
+
for AI knowledge-base ingestion or server-side indexing pipelines.
|
|
347
|
+
|
|
348
|
+
```sh
|
|
349
|
+
greg build:markdown
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Output is written to `dist/resolved-markdown` and mirrors the `docs/` structure.
|
|
353
|
+
|
|
354
|
+
## TypeScript
|
|
355
|
+
|
|
356
|
+
Greg ships types at `@dominikcz/greg`. `greg.config.ts` is supported — it is transpiled via esbuild at build time.
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
import type { GregConfig } from '@dominikcz/greg'
|
|
360
|
+
|
|
361
|
+
export default {
|
|
362
|
+
srcDir: 'docs',
|
|
363
|
+
docsBase: '',
|
|
364
|
+
mainTitle: 'My Docs',
|
|
365
|
+
} satisfies GregConfig
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
`srcDir` can also be an array when your docs are split across multiple folders:
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
import type { GregConfig } from '@dominikcz/greg'
|
|
372
|
+
|
|
373
|
+
export default {
|
|
374
|
+
srcDir: ['docs', 'api-docs', 'handbook'],
|
|
375
|
+
docsBase: '',
|
|
376
|
+
} satisfies GregConfig
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
When multiple folders contain the same relative path (for example `guide/index.md`),
|
|
380
|
+
the later entry in the `srcDir` array overrides the earlier one.
|
|
381
|
+
|
|
382
|
+
> **Note:** `svelte.config` must remain a `.js` file — `@sveltejs/vite-plugin-svelte` loads it directly via Node ESM without a TypeScript transform.
|
|
383
|
+
|
|
384
|
+
## Links
|
|
385
|
+
|
|
386
|
+
- [Documentation](https://github.com/dominikcz/greg)
|
|
387
|
+
- [GitHub](https://github.com/dominikcz/greg)
|
|
388
|
+
- [npm](https://www.npmjs.com/package/@dominikcz/greg)
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## TODO
|
|
393
|
+
|
|
394
|
+
- [ ] AI search integration
|
|
395
|
+
- [ ] edit mode
|
|
396
|
+
- [ ] comments
|
|
397
|
+
- [ ] code cleanup
|
package/bin/greg.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* greg CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* greg init Initialise a new documentation project
|
|
7
|
+
* greg dev Start the Vite development server
|
|
8
|
+
* greg build Build for production (auto-detects versioning config)
|
|
9
|
+
* greg build:static Build for production and generate static route files
|
|
10
|
+
* greg build:markdown Export resolved markdown files
|
|
11
|
+
* greg preview Preview the production build
|
|
12
|
+
* greg search-server Start the standalone search server (production)
|
|
13
|
+
* greg --version Print the Greg version
|
|
14
|
+
* greg --help Show this help message
|
|
15
|
+
*/
|
|
16
|
+
import { spawnSync, fork } from 'node:child_process';
|
|
17
|
+
import { createRequire } from 'node:module';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { resolve, dirname } from 'node:path';
|
|
20
|
+
import { DEFAULT_OUTPUT_BASE_DIR } from '../src/lib/MarkdownDocs/versioningDefaults.js';
|
|
21
|
+
import { loadGregConfig } from '../src/lib/MarkdownDocs/loadGregConfig.js';
|
|
22
|
+
|
|
23
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
const pkg = require('../package.json');
|
|
26
|
+
const USE_COLOR = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
27
|
+
|
|
28
|
+
const [, , command, ...args] = process.argv;
|
|
29
|
+
|
|
30
|
+
function color(text, code) {
|
|
31
|
+
return USE_COLOR ? `\x1b[${code}m${text}\x1b[0m` : text;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function infoTag() {
|
|
35
|
+
return color('[greg]', '1;36');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function warnTag() {
|
|
39
|
+
return color('[greg:warn]', '1;33');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function errorTag() {
|
|
43
|
+
return color('[greg:error]', '1;31');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function help() {
|
|
47
|
+
console.log(`
|
|
48
|
+
greg v${pkg.version}
|
|
49
|
+
|
|
50
|
+
Usage: greg <command> [options]
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
init Initialise a new documentation project (interactive)
|
|
54
|
+
dev Start the Vite development server
|
|
55
|
+
build Build for production (auto-detects versioning config)
|
|
56
|
+
build:static Build and generate static route files
|
|
57
|
+
build:markdown Export resolved markdown files to dist/resolved-markdown
|
|
58
|
+
preview Preview the production build
|
|
59
|
+
search-server Start the standalone search API server (production)
|
|
60
|
+
Options: --index <path> --port <number> --host <addr>
|
|
61
|
+
--url <path> (endpoint path, default /api/search)
|
|
62
|
+
--cors-origin <value> (default *)
|
|
63
|
+
--cors-methods <value> (default "GET, OPTIONS")
|
|
64
|
+
--cors-headers <value> (default "Content-Type")
|
|
65
|
+
--cors-max-age <value> (default 86400)
|
|
66
|
+
ai-server Start the standalone AI/RAG API server (production)
|
|
67
|
+
Options: --index <path> (default dist/search-index.json)
|
|
68
|
+
--port <number> (default 3200)
|
|
69
|
+
--host <addr> (default localhost)
|
|
70
|
+
--url <path> (endpoint path, default /api/ai)
|
|
71
|
+
--provider <name> (ollama|openai, default ollama)
|
|
72
|
+
--model <name> (LLM model override)
|
|
73
|
+
--ollama-url <url>(default http://localhost:11434)
|
|
74
|
+
--cors-origin / --cors-methods / --cors-headers / --cors-max-age
|
|
75
|
+
|
|
76
|
+
Options:
|
|
77
|
+
--version Show version number
|
|
78
|
+
--help Show this help message
|
|
79
|
+
--single With 'build': force a single vite build
|
|
80
|
+
--clean-versions With 'build' + versioning: remove versioned output before build
|
|
81
|
+
--rebuild-all With 'build' + versioning: rebuild all versions and skip build cache
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function run(cmd, extraArgs = [], options = {}) {
|
|
86
|
+
const { exit = true } = options;
|
|
87
|
+
const result = spawnSync(cmd, extraArgs, {
|
|
88
|
+
stdio: 'inherit',
|
|
89
|
+
shell: true,
|
|
90
|
+
// Ensure the local node_modules/.bin is on the PATH so that
|
|
91
|
+
// the project-local vite binary is preferred.
|
|
92
|
+
env: {
|
|
93
|
+
...process.env,
|
|
94
|
+
PATH: resolve(__dirname, '../node_modules/.bin') +
|
|
95
|
+
(process.platform === 'win32' ? ';' : ':') +
|
|
96
|
+
(process.env.PATH ?? ''),
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
const status = result.status ?? 0;
|
|
100
|
+
if (exit) process.exit(status);
|
|
101
|
+
return status;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function runNodeScript(scriptPath, extraArgs = [], options = {}) {
|
|
105
|
+
const { exit = true } = options;
|
|
106
|
+
const result = spawnSync(process.execPath, [scriptPath, ...extraArgs], {
|
|
107
|
+
stdio: 'inherit',
|
|
108
|
+
env: {
|
|
109
|
+
...process.env,
|
|
110
|
+
PATH: resolve(__dirname, '../node_modules/.bin') +
|
|
111
|
+
(process.platform === 'win32' ? ';' : ':') +
|
|
112
|
+
(process.env.PATH ?? ''),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const status = result.status ?? 0;
|
|
116
|
+
if (exit) process.exit(status);
|
|
117
|
+
return status;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function printElapsedSeconds(startMs) {
|
|
121
|
+
const elapsed = ((Date.now() - startMs) / 1000).toFixed(1);
|
|
122
|
+
console.log(`\n${infoTag()} ${color(`Done in ${elapsed}s`, '32')}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function hasVersioningBuildConfig() {
|
|
126
|
+
try {
|
|
127
|
+
const config = await loadGregConfig();
|
|
128
|
+
const versioning = config?.versioning;
|
|
129
|
+
if (!versioning || typeof versioning !== 'object' || Array.isArray(versioning)) return false;
|
|
130
|
+
|
|
131
|
+
const hasBranches = Array.isArray(versioning.branches) && versioning.branches.length > 0;
|
|
132
|
+
const hasFolders = Array.isArray(versioning.folders) && versioning.folders.length > 0;
|
|
133
|
+
const hasFoldersDir = typeof versioning.foldersDir === 'string' && versioning.foldersDir.trim().length > 0;
|
|
134
|
+
return hasBranches || hasFolders || hasFoldersDir;
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.warn(`${warnTag()} Could not read greg.config.* (${error?.message || error}). Falling back to single build.`);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function resolveSiteOutDir(config) {
|
|
142
|
+
return String(config?.outDir || DEFAULT_OUTPUT_BASE_DIR).trim() || DEFAULT_OUTPUT_BASE_DIR;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function resolveDocsSourceDir(config) {
|
|
146
|
+
return String(config?.srcDir || 'docs').trim() || 'docs';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function resolveDocsBase(config) {
|
|
150
|
+
const docsBaseValue = Object.prototype.hasOwnProperty.call(config || {}, 'docsBase')
|
|
151
|
+
? config.docsBase
|
|
152
|
+
: '';
|
|
153
|
+
const cleaned = String(docsBaseValue ?? '').trim().replace(/^\/+|\/+$/g, '');
|
|
154
|
+
return '/' + cleaned;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
switch (command) {
|
|
158
|
+
case 'init': {
|
|
159
|
+
const initScript = resolve(__dirname, 'init.js');
|
|
160
|
+
const child = fork(initScript, args, { stdio: 'inherit' });
|
|
161
|
+
child.on('exit', code => process.exit(code ?? 0));
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case 'dev':
|
|
165
|
+
run('vite', args);
|
|
166
|
+
break;
|
|
167
|
+
case 'build': {
|
|
168
|
+
const startedAt = Date.now();
|
|
169
|
+
const forceSingle = args.includes('--single');
|
|
170
|
+
const passthroughArgs = args.filter((a) => a !== '--single');
|
|
171
|
+
const shouldBuildVersions = !forceSingle && await hasVersioningBuildConfig();
|
|
172
|
+
|
|
173
|
+
if (shouldBuildVersions) {
|
|
174
|
+
console.log(`${infoTag()} ${color('versioning config detected. Running multi-version build.', '36')}`);
|
|
175
|
+
const versionsScript = resolve(__dirname, '../scripts/build-versions.js');
|
|
176
|
+
const status = runNodeScript(versionsScript, passthroughArgs, { exit: false });
|
|
177
|
+
printElapsedSeconds(startedAt);
|
|
178
|
+
process.exit(status);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const status = run('vite build', passthroughArgs, { exit: false });
|
|
182
|
+
printElapsedSeconds(startedAt);
|
|
183
|
+
process.exit(status);
|
|
184
|
+
}
|
|
185
|
+
case 'build:static': {
|
|
186
|
+
const startedAt = Date.now();
|
|
187
|
+
const config = await loadGregConfig();
|
|
188
|
+
const distDir = resolveSiteOutDir(config);
|
|
189
|
+
const docsDir = resolveDocsSourceDir(config);
|
|
190
|
+
const srcDir = resolveDocsBase(config);
|
|
191
|
+
const buildStatus = run('vite build', args, { exit: false });
|
|
192
|
+
if (buildStatus !== 0) {
|
|
193
|
+
printElapsedSeconds(startedAt);
|
|
194
|
+
process.exit(buildStatus);
|
|
195
|
+
}
|
|
196
|
+
const staticScript = resolve(__dirname, '../scripts/generate-static.js');
|
|
197
|
+
const status = runNodeScript(
|
|
198
|
+
staticScript,
|
|
199
|
+
['--docsDir', docsDir, '--srcDir', srcDir, '--distDir', distDir],
|
|
200
|
+
{ exit: false },
|
|
201
|
+
);
|
|
202
|
+
printElapsedSeconds(startedAt);
|
|
203
|
+
process.exit(status);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case 'build:markdown': {
|
|
207
|
+
const markdownScript = resolve(__dirname, '../scripts/render-markdown.js');
|
|
208
|
+
runNodeScript(markdownScript, args);
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case 'preview':
|
|
212
|
+
run('vite preview', args);
|
|
213
|
+
break;
|
|
214
|
+
case 'search-server': {
|
|
215
|
+
// Run the standalone search server directly in this process
|
|
216
|
+
// (no shell needed - it is a Node.js script in the package).
|
|
217
|
+
const serverScript = resolve(__dirname, '../src/lib/MarkdownDocs/searchServer.js');
|
|
218
|
+
const child = fork(serverScript, args, { stdio: 'inherit' });
|
|
219
|
+
child.on('exit', code => process.exit(code ?? 0));
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
case 'ai-server': {
|
|
223
|
+
const aiServerScript = resolve(__dirname, '../src/lib/MarkdownDocs/aiServer.js');
|
|
224
|
+
const child = fork(aiServerScript, args, { stdio: 'inherit' });
|
|
225
|
+
child.on('exit', code => process.exit(code ?? 0));
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
case '--version':
|
|
229
|
+
case '-v':
|
|
230
|
+
console.log(pkg.version);
|
|
231
|
+
break;
|
|
232
|
+
case '--help':
|
|
233
|
+
case '-h':
|
|
234
|
+
case undefined:
|
|
235
|
+
help();
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
console.error(`${errorTag()} Unknown command: ${command}\n`);
|
|
239
|
+
help();
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|