sourcey 3.5.9 → 3.5.10
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
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Sourcey
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Docs straight from the source.
|
|
4
4
|
|
|
5
|
-
Sourcey
|
|
5
|
+
Sourcey tells the whole product story. It turns specs, code, rich guides, changelog, roadmap pages, examples, and portable context files from your project into static HTML you can deploy anywhere.
|
|
6
|
+
|
|
7
|
+
No dashboard. No runtime. No API calls to render your own documentation.
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/sourcey)
|
|
8
10
|
[](https://github.com/sourcey/sourcey/actions)
|
|
@@ -17,17 +19,18 @@ npx sourcey init
|
|
|
17
19
|
|
|
18
20
|

|
|
19
21
|
|
|
20
|
-
**[Live demo](https://
|
|
22
|
+
**[Live demo](https://sourcey.com/cheesestore)** · [Documentation](https://sourcey.com/docs) · [GitHub](https://github.com/sourcey/sourcey)
|
|
21
23
|
|
|
22
24
|
## Features
|
|
23
25
|
|
|
24
26
|
- **OpenAPI 2.0, 3.0, 3.1, and 3.2**: full spec coverage including `QUERY` operations, response summaries, hierarchical tags, `deviceAuthorization` OAuth, `querystring` parameters, and `$self`-aware refs for multi-document APIs
|
|
25
27
|
- **API reference from OpenAPI**: endpoints, parameters, request/response schemas, auto-generated code samples in 10 languages (cURL, JavaScript, TypeScript, Python, Go, Ruby, Java, PHP, Rust, C#)
|
|
26
28
|
- **MCP server documentation**: tools, resources, prompts rendered as browsable reference with JSON-RPC, TypeScript, and Python code samples. Color-coded method types, annotation badges, connection config cards
|
|
27
|
-
- **
|
|
29
|
+
- **Rich guides**: markdown pages with steps, cards, accordions, syntax-highlighted code blocks, and prose alongside your API reference
|
|
30
|
+
- **Product story pages**: changelog, roadmap pages, examples, reference material, search, and portable context exports in one source-owned site
|
|
28
31
|
- **C++ and Doxygen**: feed Doxygen XML output, get modern searchable API docs. No new parser, no four-tool Breathe/Exhale/Sphinx pipeline
|
|
29
32
|
- **Go and godoc**: native package documentation extracted from Go source via the toolchain. Render Go modules as Sourcey tabs, generate standalone static Go docs sites, or commit `godoc.json` snapshots for JS-only docs hosts. No Doxygen detour
|
|
30
|
-
- **
|
|
33
|
+
- **Context exports**: auto-generate llms.txt and llms-full.txt alongside your HTML as alternate views of the same documentation graph
|
|
31
34
|
- **TypeScript config**: `sourcey.config.ts` with `defineConfig()` autocomplete; theme, navbar, CTA buttons, footer
|
|
32
35
|
- **Theme presets**: default (sidebar + TOC), minimal (single column), api-first (Stripe-style three column); colors, fonts, layout dimensions, and custom CSS on top
|
|
33
36
|
- **Vite dev server**: SSR hot reload on every component and CSS change; spec and markdown changes trigger instant refresh
|
|
@@ -36,22 +39,6 @@ npx sourcey init
|
|
|
36
39
|
- **Static HTML output**: no framework runtime, no vendor lock-in. Deploy to GitHub Pages, Vercel, Netlify, S3, anywhere
|
|
37
40
|
- **Open source**: AGPL-3.0. Self-host, fork, extend. Your docs, your infrastructure
|
|
38
41
|
|
|
39
|
-
### Sourcey vs alternatives
|
|
40
|
-
|
|
41
|
-
| | Sourcey | Redocly | GitBook | Mintlify | Fern | ReadMe |
|
|
42
|
-
|---|---|---|---|---|---|---|
|
|
43
|
-
| Open source | Yes | Partial | No | No | No | No |
|
|
44
|
-
| Static output | Yes | Yes | No | No | No | No |
|
|
45
|
-
| Zero JS shipped | Yes | No | No | No | No | No |
|
|
46
|
-
| MCP server docs | Native | No | No | No | No | No |
|
|
47
|
-
| Doxygen / C++ docs | Native | No | No | No | No | No |
|
|
48
|
-
| godoc / Go docs | Native | No | No | No | No | No |
|
|
49
|
-
| Config format | TypeScript | YAML | GUI | JSON | YAML | GUI |
|
|
50
|
-
| Local preview | Vite SSR | Local | Hosted | Local | Local | Hosted |
|
|
51
|
-
| No account required | Yes | Partial | No | No | No | No |
|
|
52
|
-
| Self-hosted | Yes | Yes | No | No | Yes | No |
|
|
53
|
-
| Pricing | Free | $10–$24 | $65–$249 | $250+ | $150+ | $79–$3,000+ |
|
|
54
|
-
|
|
55
42
|
## Install
|
|
56
43
|
|
|
57
44
|
### Sourcey CLI
|
package/dist/client/sidebar.js
CHANGED
|
@@ -4,7 +4,176 @@
|
|
|
4
4
|
// backdrop click, nav link click, Escape (native dialog behavior).
|
|
5
5
|
// Dropdown toggles list visibility for tab selection.
|
|
6
6
|
(function () {
|
|
7
|
+
function storageGet(key) {
|
|
8
|
+
try {
|
|
9
|
+
return window.sessionStorage.getItem(key);
|
|
10
|
+
} catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function storageSet(key, value) {
|
|
16
|
+
try {
|
|
17
|
+
window.sessionStorage.setItem(key, value);
|
|
18
|
+
} catch {
|
|
19
|
+
// Ignore blocked storage. Sidebar navigation still works normally.
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function storageRemove(key) {
|
|
24
|
+
try {
|
|
25
|
+
window.sessionStorage.removeItem(key);
|
|
26
|
+
} catch {
|
|
27
|
+
// Ignore blocked storage. Sidebar navigation still works normally.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function normalizePath(pathname) {
|
|
32
|
+
var clean = (pathname || '/').replace(/\/+$/, '') || '/';
|
|
33
|
+
clean = clean.replace(/\/index(?:\.html)?$/, '') || '/';
|
|
34
|
+
clean = clean.replace(/\.html$/, '');
|
|
35
|
+
return clean || '/';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function commonPath(paths) {
|
|
39
|
+
if (!paths.length) return null;
|
|
40
|
+
var parts = paths.map(function (path) {
|
|
41
|
+
return normalizePath(path).split('/').filter(Boolean);
|
|
42
|
+
});
|
|
43
|
+
var common = [];
|
|
44
|
+
|
|
45
|
+
for (var i = 0; i < parts[0].length; i++) {
|
|
46
|
+
var part = parts[0][i];
|
|
47
|
+
var allMatch = parts.every(function (segments) {
|
|
48
|
+
return segments[i] === part;
|
|
49
|
+
});
|
|
50
|
+
if (!allMatch) break;
|
|
51
|
+
common.push(part);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return '/' + common.join('/');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function navScope(nav) {
|
|
58
|
+
var paths = [];
|
|
59
|
+
nav.querySelectorAll('a.nav-link[href]').forEach(function (link) {
|
|
60
|
+
var href = link.getAttribute('href');
|
|
61
|
+
if (!href || href.startsWith('#')) return;
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
var url = new URL(href, window.location.href);
|
|
65
|
+
if (url.origin === window.location.origin) {
|
|
66
|
+
paths.push(url.pathname);
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
// Ignore malformed hrefs.
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return commonPath(paths);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function searchIndexScope() {
|
|
77
|
+
var meta = document.querySelector('meta[name="sourcey-search"]');
|
|
78
|
+
var content = meta && meta.getAttribute('content');
|
|
79
|
+
if (!content) return null;
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
var url = new URL(content, window.location.href);
|
|
83
|
+
if (url.origin === window.location.origin) {
|
|
84
|
+
return normalizePath(url.pathname.replace(/\/search-index\.json$/, ''));
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// Ignore malformed metadata.
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function sidebarStorageKey(scroller, nav) {
|
|
94
|
+
var tab = scroller.getAttribute('data-sourcey-sidebar-tab') || 'default';
|
|
95
|
+
var scope = navScope(nav) || searchIndexScope() || normalizePath(window.location.pathname);
|
|
96
|
+
return 'sourcey:sidebar-scroll:v1:' + window.location.origin + scope + ':' + tab;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function clampSidebarScroll(scroller, top) {
|
|
100
|
+
var max = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
|
|
101
|
+
return Math.max(0, Math.min(top, max));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function saveSidebarScroll(scroller, key) {
|
|
105
|
+
storageSet(key, String(Math.round(scroller.scrollTop || 0)));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function restoreSidebarScroll(scroller, key) {
|
|
109
|
+
var raw = storageGet(key);
|
|
110
|
+
if (raw === null) return false;
|
|
111
|
+
storageRemove(key);
|
|
112
|
+
|
|
113
|
+
var top = Number(raw);
|
|
114
|
+
if (!Number.isFinite(top) || top <= 0) return false;
|
|
115
|
+
|
|
116
|
+
function apply() {
|
|
117
|
+
scroller.scrollTop = clampSidebarScroll(scroller, top);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
apply();
|
|
121
|
+
requestAnimationFrame(apply);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function revealActiveSidebarLink(nav) {
|
|
126
|
+
var active = nav.querySelector('.nav-link.active');
|
|
127
|
+
if (!active) return;
|
|
128
|
+
requestAnimationFrame(function () {
|
|
129
|
+
active.scrollIntoView({ block: 'nearest', behavior: 'auto' });
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function shouldSaveForNavigation(e, link) {
|
|
134
|
+
if (!link || e.defaultPrevented) return false;
|
|
135
|
+
if (e.button !== undefined && e.button !== 0) return false;
|
|
136
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return false;
|
|
137
|
+
if (link.hasAttribute('download')) return false;
|
|
138
|
+
|
|
139
|
+
var target = link.getAttribute('target');
|
|
140
|
+
if (target && target.toLowerCase() !== '_self') return false;
|
|
141
|
+
|
|
142
|
+
var href = link.getAttribute('href');
|
|
143
|
+
if (!href || href.startsWith('#')) return false;
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
var url = new URL(href, window.location.href);
|
|
147
|
+
if (url.origin !== window.location.origin) return false;
|
|
148
|
+
if (url.pathname === window.location.pathname && url.search === window.location.search && url.hash) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function initDesktopSidebarScroll() {
|
|
158
|
+
var scroller = document.querySelector('[data-sourcey-sidebar-scroll]');
|
|
159
|
+
var nav = document.getElementById('nav');
|
|
160
|
+
if (!scroller || !nav) return;
|
|
161
|
+
|
|
162
|
+
var key = sidebarStorageKey(scroller, nav);
|
|
163
|
+
var restored = restoreSidebarScroll(scroller, key);
|
|
164
|
+
if (!restored) revealActiveSidebarLink(nav);
|
|
165
|
+
|
|
166
|
+
nav.addEventListener('click', function (e) {
|
|
167
|
+
var link = e.target.closest('a[href]');
|
|
168
|
+
if (shouldSaveForNavigation(e, link)) {
|
|
169
|
+
saveSidebarScroll(scroller, key);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
7
174
|
function init() {
|
|
175
|
+
initDesktopSidebarScroll();
|
|
176
|
+
|
|
8
177
|
var dialog = document.getElementById('mobile-nav');
|
|
9
178
|
var openBtns = document.querySelectorAll('[data-drawer-slide]');
|
|
10
179
|
if (!dialog) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Sidebar.tsx"],"names":[],"mappings":"AA+FA;;GAEG;AACH,wBAAgB,OAAO,
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Sidebar.tsx"],"names":[],"mappings":"AA+FA;;GAEG;AACH,wBAAgB,OAAO,wCA2GtB"}
|
|
@@ -58,7 +58,7 @@ export function Sidebar() {
|
|
|
58
58
|
const primaryAction = site.navbar.primary;
|
|
59
59
|
const groups = activeTab.groups;
|
|
60
60
|
const logoHref = site.logo?.href ?? `${base}${nav.tabs[0]?.href ?? ""}`;
|
|
61
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { id: "sidebar", class: "z-20 hidden lg:block fixed bottom-0 right-auto w-[18rem]", style: "top: var(--header-height)", children: _jsx("div", { class: "absolute inset-0 z-10 overflow-auto pr-8 pb-10", children: _jsxs("div", { class: "relative text-sm leading-6", children: [_jsx("div", { class: "sticky top-0 h-8 z-10 bg-gradient-to-b from-[rgb(var(--color-background-light))] dark:from-[rgb(var(--color-background-dark))]" }), _jsx("nav", { id: "nav", role: "navigation", children: _jsx(NavGroups, { groups: groups, activePageSlug: nav.activePageSlug, base: base }) })] }) }) }), _jsxs("dialog", { id: "mobile-nav", class: "mobile-nav-dialog", children: [site.logo?.light && (_jsx("div", { class: "px-4 py-4 border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-gray-800)/0.5)] shrink-0", children: _jsx(Logo, { href: logoHref, logo: site.logo, height: "h-6" }) })), nav.tabs.length > 1 && (_jsx("div", { class: "pt-5 px-4 shrink-0", children: _jsxs("div", { class: "drawer-dropdown", children: [_jsxs("button", { id: "drawer-group-toggle", type: "button", class: "drawer-dropdown-trigger", "aria-expanded": "false", children: [_jsx("span", { class: "drawer-dropdown-label", children: activeTab.label }), _jsx(DropdownChevron, {})] }), _jsx("ul", { id: "drawer-group-list", class: "drawer-dropdown-list", style: "display:none", children: nav.tabs.map((tab) => (_jsx("li", { children: _jsx("a", { href: `${base}${tab.href}`, class: `drawer-dropdown-item${tab.slug === nav.activeTabSlug ? " active" : ""}`, children: tab.label }) }, tab.slug))) })] }) })), _jsx("nav", { class: "pt-5 pb-3 px-4 flex-1 overflow-y-auto", children: _jsx(NavGroups, { groups: groups, activePageSlug: nav.activePageSlug, base: base }) }), (links.length > 0 || primaryAction) && (_jsx("div", { class: "px-4 py-3 border-t border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-gray-800)/0.5)] shrink-0", children: _jsxs("ul", { class: "space-y-3", children: [links.map((link) => {
|
|
61
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { id: "sidebar", class: "z-20 hidden lg:block fixed bottom-0 right-auto w-[18rem]", style: "top: var(--header-height)", children: _jsx("div", { class: "absolute inset-0 z-10 overflow-auto pr-8 pb-10", "data-sourcey-sidebar-scroll": true, "data-sourcey-sidebar-tab": nav.activeTabSlug || "default", children: _jsxs("div", { class: "relative text-sm leading-6", children: [_jsx("div", { class: "sticky top-0 h-8 z-10 bg-gradient-to-b from-[rgb(var(--color-background-light))] dark:from-[rgb(var(--color-background-dark))]" }), _jsx("nav", { id: "nav", role: "navigation", children: _jsx(NavGroups, { groups: groups, activePageSlug: nav.activePageSlug, base: base }) })] }) }) }), _jsxs("dialog", { id: "mobile-nav", class: "mobile-nav-dialog", children: [site.logo?.light && (_jsx("div", { class: "px-4 py-4 border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-gray-800)/0.5)] shrink-0", children: _jsx(Logo, { href: logoHref, logo: site.logo, height: "h-6" }) })), nav.tabs.length > 1 && (_jsx("div", { class: "pt-5 px-4 shrink-0", children: _jsxs("div", { class: "drawer-dropdown", children: [_jsxs("button", { id: "drawer-group-toggle", type: "button", class: "drawer-dropdown-trigger", "aria-expanded": "false", children: [_jsx("span", { class: "drawer-dropdown-label", children: activeTab.label }), _jsx(DropdownChevron, {})] }), _jsx("ul", { id: "drawer-group-list", class: "drawer-dropdown-list", style: "display:none", children: nav.tabs.map((tab) => (_jsx("li", { children: _jsx("a", { href: `${base}${tab.href}`, class: `drawer-dropdown-item${tab.slug === nav.activeTabSlug ? " active" : ""}`, children: tab.label }) }, tab.slug))) })] }) })), _jsx("nav", { class: "pt-5 pb-3 px-4 flex-1 overflow-y-auto", children: _jsx(NavGroups, { groups: groups, activePageSlug: nav.activePageSlug, base: base }) }), (links.length > 0 || primaryAction) && (_jsx("div", { class: "px-4 py-3 border-t border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-gray-800)/0.5)] shrink-0", children: _jsxs("ul", { class: "space-y-3", children: [links.map((link) => {
|
|
62
62
|
const label = link.label ?? socialLabels[link.type] ?? link.href;
|
|
63
63
|
return (_jsx("li", { children: _jsxs("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", class: "flex items-center gap-2.5 text-[rgb(var(--color-gray-600))] hover:text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-400))] dark:hover:text-[rgb(var(--color-gray-200))]", children: [link.type !== "link" && _jsx(SocialIcon, { type: link.type }), _jsx("span", { children: label })] }) }, link.href));
|
|
64
64
|
}), primaryAction && (_jsx("li", { children: _jsxs("a", { href: primaryAction.href, target: "_blank", class: "group relative flex items-center justify-center px-4 py-2 text-sm font-medium", children: [_jsx("span", { class: "absolute inset-0 bg-[rgb(var(--color-primary-dark))] rounded-lg group-hover:opacity-90" }), _jsx("span", { class: "z-10 text-white", children: primaryAction.label })] }) }))] }) }))] })] }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sourcey",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.10",
|
|
4
4
|
"description": "Precision documentation from OpenAPI, MCP, Doxygen, godoc, and Markdown. Static HTML you own.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"jiti": "^2.6.1",
|
|
46
46
|
"js-yaml": "^4.1.0",
|
|
47
47
|
"marked": "^15.0.0",
|
|
48
|
-
"mcp-parser": "^0.
|
|
48
|
+
"mcp-parser": "^0.4.0",
|
|
49
49
|
"moxygen": "^2.1.1",
|
|
50
50
|
"preact": "^10.28.4",
|
|
51
51
|
"preact-render-to-string": "^6.6.6",
|