sourcey 3.3.10 → 3.4.1
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 +19 -3
- package/dist/client/scroll-tracker.js +8 -1
- package/dist/client/search.js +26 -7
- package/dist/components/layout/Head.d.ts.map +1 -1
- package/dist/components/layout/Head.js +1 -1
- package/dist/components/layout/Header.d.ts.map +1 -1
- package/dist/components/layout/Header.js +2 -2
- package/dist/components/layout/Page.d.ts.map +1 -1
- package/dist/components/layout/Page.js +6 -5
- package/dist/components/layout/Sidebar.d.ts.map +1 -1
- package/dist/components/layout/Sidebar.js +11 -2
- package/dist/components/layout/TableOfContents.d.ts.map +1 -1
- package/dist/components/layout/TableOfContents.js +3 -2
- package/dist/components/mcp/AnnotationBadges.d.ts +15 -0
- package/dist/components/mcp/AnnotationBadges.d.ts.map +1 -0
- package/dist/components/mcp/AnnotationBadges.js +10 -0
- package/dist/components/mcp/McpConnection.d.ts +10 -0
- package/dist/components/mcp/McpConnection.d.ts.map +1 -0
- package/dist/components/mcp/McpConnection.js +32 -0
- package/dist/components/mcp/McpEndpointBar.d.ts +8 -0
- package/dist/components/mcp/McpEndpointBar.d.ts.map +1 -0
- package/dist/components/mcp/McpEndpointBar.js +16 -0
- package/dist/components/mcp/McpReturns.d.ts +18 -0
- package/dist/components/mcp/McpReturns.d.ts.map +1 -0
- package/dist/components/mcp/McpReturns.js +33 -0
- package/dist/components/openapi/Operation.d.ts.map +1 -1
- package/dist/components/openapi/Operation.js +5 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -3
- package/dist/core/markdown-loader.d.ts.map +1 -1
- package/dist/core/markdown-loader.js +7 -2
- package/dist/core/mcp-normalizer.d.ts +11 -0
- package/dist/core/mcp-normalizer.d.ts.map +1 -0
- package/dist/core/mcp-normalizer.js +382 -0
- package/dist/core/search-indexer.d.ts +3 -1
- package/dist/core/search-indexer.d.ts.map +1 -1
- package/dist/core/search-indexer.js +7 -3
- package/dist/core/types.d.ts +26 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +47 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -10
- package/dist/renderer/html-builder.d.ts +2 -0
- package/dist/renderer/html-builder.d.ts.map +1 -1
- package/dist/renderer/html-builder.js +15 -0
- package/dist/renderer/llms.d.ts +6 -0
- package/dist/renderer/llms.d.ts.map +1 -0
- package/dist/renderer/llms.js +247 -0
- package/dist/themes/default/main.css +3 -0
- package/dist/themes/default/sourcey.css +101 -23
- package/dist/utils/icons.d.ts +4 -0
- package/dist/utils/icons.d.ts.map +1 -1
- package/dist/utils/icons.js +6 -0
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js +97 -1
- package/package.json +6 -2
|
@@ -7,6 +7,38 @@
|
|
|
7
7
|
* utilities in generated HTML.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
/* ── Page Description (display font) ─────────────────────────────── */
|
|
11
|
+
|
|
12
|
+
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap');
|
|
13
|
+
|
|
14
|
+
#sourcey .page-description {
|
|
15
|
+
font-family: 'Playfair Display', Georgia, serif;
|
|
16
|
+
font-size: 1.375rem;
|
|
17
|
+
line-height: 1.4;
|
|
18
|
+
font-style: italic;
|
|
19
|
+
color: rgb(var(--color-gray-600));
|
|
20
|
+
}
|
|
21
|
+
.dark #sourcey .page-description {
|
|
22
|
+
color: rgb(var(--color-gray-400));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* ── Page Top Gradient ────────────────────────────────────────────── */
|
|
26
|
+
|
|
27
|
+
#sourcey #page::before {
|
|
28
|
+
content: "";
|
|
29
|
+
position: fixed;
|
|
30
|
+
top: 0;
|
|
31
|
+
left: 0;
|
|
32
|
+
right: 0;
|
|
33
|
+
height: 400px;
|
|
34
|
+
background: linear-gradient(to bottom, rgb(var(--color-primary) / 0.03), transparent);
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
z-index: -1;
|
|
37
|
+
}
|
|
38
|
+
.dark #sourcey #page::before {
|
|
39
|
+
background: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
10
42
|
/* ── Scroll Offset (clears fixed navbar on anchor clicks) ──────────── */
|
|
11
43
|
|
|
12
44
|
[data-traverse-target],
|
|
@@ -55,6 +87,43 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
55
87
|
-webkit-overflow-scrolling: touch;
|
|
56
88
|
}
|
|
57
89
|
|
|
90
|
+
/* ── Prose Video (::video directive) ──────────────────────────────── */
|
|
91
|
+
|
|
92
|
+
#sourcey .prose-video {
|
|
93
|
+
position: relative;
|
|
94
|
+
width: 100%;
|
|
95
|
+
padding-bottom: 56.25%; /* 16:9 */
|
|
96
|
+
margin: 1.5rem 0;
|
|
97
|
+
border-radius: var(--radius);
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
}
|
|
100
|
+
#sourcey .prose-video iframe,
|
|
101
|
+
#sourcey .prose-video video {
|
|
102
|
+
position: absolute;
|
|
103
|
+
top: 0;
|
|
104
|
+
left: 0;
|
|
105
|
+
width: 100%;
|
|
106
|
+
height: 100%;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* ── Prose Iframe (::iframe directive) ────────────────────────────── */
|
|
110
|
+
|
|
111
|
+
#sourcey .prose-iframe {
|
|
112
|
+
width: 100%;
|
|
113
|
+
margin: 1.5rem 0;
|
|
114
|
+
border-radius: var(--radius);
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
border: 1px solid rgb(var(--color-stone-950) / 0.1);
|
|
117
|
+
}
|
|
118
|
+
.dark #sourcey .prose-iframe {
|
|
119
|
+
border-color: rgb(255 255 255 / 0.1);
|
|
120
|
+
}
|
|
121
|
+
#sourcey .prose-iframe iframe {
|
|
122
|
+
width: 100%;
|
|
123
|
+
height: 100%;
|
|
124
|
+
display: block;
|
|
125
|
+
}
|
|
126
|
+
|
|
58
127
|
/* ── Prose Code Block (fenced code in markdown pages) ─────────────── */
|
|
59
128
|
|
|
60
129
|
#sourcey .prose-code-block {
|
|
@@ -159,39 +228,49 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
159
228
|
text-align: left;
|
|
160
229
|
overflow-wrap: break-word;
|
|
161
230
|
hyphens: auto;
|
|
162
|
-
border-
|
|
231
|
+
border-radius: 0.375rem;
|
|
163
232
|
width: 100%;
|
|
164
233
|
color: rgb(var(--color-gray-700));
|
|
165
|
-
transition: color 0.15s,
|
|
234
|
+
transition: color 0.15s, background-color 0.15s;
|
|
166
235
|
}
|
|
167
236
|
.dark #sourcey .nav-link {
|
|
168
237
|
color: rgb(var(--color-gray-400));
|
|
169
238
|
}
|
|
170
239
|
#sourcey .nav-link:hover {
|
|
171
240
|
color: rgb(var(--color-gray-900));
|
|
172
|
-
|
|
241
|
+
background: rgb(var(--color-gray-100) / 0.6);
|
|
173
242
|
}
|
|
174
243
|
.dark #sourcey .nav-link:hover {
|
|
175
244
|
color: rgb(var(--color-gray-300));
|
|
176
|
-
|
|
245
|
+
background: rgb(var(--color-gray-800) / 0.4);
|
|
177
246
|
}
|
|
178
247
|
#sourcey .nav-link.active {
|
|
179
248
|
color: rgb(var(--color-primary));
|
|
180
|
-
|
|
249
|
+
background: rgb(var(--color-primary) / 0.08);
|
|
181
250
|
font-weight: 500;
|
|
182
251
|
}
|
|
183
252
|
.dark #sourcey .nav-link.active {
|
|
184
253
|
color: rgb(var(--color-primary-light));
|
|
185
|
-
|
|
254
|
+
background: rgb(var(--color-primary-light) / 0.08);
|
|
186
255
|
}
|
|
187
256
|
|
|
188
257
|
/* ── TOC Active State ─────────────────────────────────────────────── */
|
|
189
258
|
|
|
259
|
+
#sourcey #toc .toc-item {
|
|
260
|
+
border-left: 2px solid rgb(var(--color-gray-200));
|
|
261
|
+
padding-left: 0.75rem;
|
|
262
|
+
transition: color 0.15s, border-color 0.15s;
|
|
263
|
+
}
|
|
264
|
+
.dark #sourcey #toc .toc-item {
|
|
265
|
+
border-left-color: rgb(var(--color-gray-700));
|
|
266
|
+
}
|
|
190
267
|
#sourcey #toc .toc-item.active {
|
|
191
268
|
color: rgb(var(--color-primary));
|
|
269
|
+
border-left-color: rgb(var(--color-primary));
|
|
192
270
|
}
|
|
193
271
|
.dark #sourcey #toc .toc-item.active {
|
|
194
272
|
color: rgb(var(--color-primary-light));
|
|
273
|
+
border-left-color: rgb(var(--color-primary-light));
|
|
195
274
|
}
|
|
196
275
|
|
|
197
276
|
/* ── Code Block Panels (language dropdown + response tabs) ─────────── */
|
|
@@ -480,7 +559,7 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
480
559
|
|
|
481
560
|
#sourcey .steps {
|
|
482
561
|
margin-left: 0.875rem;
|
|
483
|
-
margin-top:
|
|
562
|
+
margin-top: 1rem;
|
|
484
563
|
margin-bottom: 1.5rem;
|
|
485
564
|
}
|
|
486
565
|
|
|
@@ -1025,11 +1104,10 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
1025
1104
|
color: rgb(var(--color-primary-light));
|
|
1026
1105
|
}
|
|
1027
1106
|
|
|
1028
|
-
/* Drawer nav items — larger touch targets
|
|
1107
|
+
/* Drawer nav items — larger touch targets */
|
|
1029
1108
|
#sourcey .mobile-nav-dialog .nav-link,
|
|
1030
1109
|
#sourcey .mobile-nav-dialog .nav-link:hover,
|
|
1031
1110
|
#sourcey .mobile-nav-dialog .nav-link.active {
|
|
1032
|
-
border-left: none;
|
|
1033
1111
|
padding-top: 0.5rem;
|
|
1034
1112
|
padding-bottom: 0.5rem;
|
|
1035
1113
|
}
|
|
@@ -1080,30 +1158,25 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
1080
1158
|
position: fixed;
|
|
1081
1159
|
inset: 0;
|
|
1082
1160
|
z-index: 500;
|
|
1083
|
-
background:
|
|
1084
|
-
backdrop-filter: blur(4px);
|
|
1085
|
-
-webkit-backdrop-filter: blur(4px);
|
|
1086
|
-
align-items: flex-start;
|
|
1087
|
-
justify-content: center;
|
|
1088
|
-
padding-top: 15vh;
|
|
1161
|
+
background: transparent;
|
|
1089
1162
|
}
|
|
1090
1163
|
|
|
1091
1164
|
#sourcey #search-dialog.open {
|
|
1092
|
-
display:
|
|
1165
|
+
display: block;
|
|
1093
1166
|
}
|
|
1094
1167
|
|
|
1095
1168
|
#sourcey .search-dialog-inner {
|
|
1096
|
-
|
|
1097
|
-
max-width: 540px;
|
|
1169
|
+
position: absolute;
|
|
1098
1170
|
background: rgb(var(--color-background-light));
|
|
1099
1171
|
border-radius: var(--radius);
|
|
1100
|
-
|
|
1172
|
+
border: 1px solid rgb(var(--color-gray-200) / 0.7);
|
|
1173
|
+
box-shadow: 0 8px 32px rgb(var(--color-overlay) / 0.12);
|
|
1101
1174
|
overflow: hidden;
|
|
1102
|
-
margin: 0 1rem;
|
|
1103
1175
|
}
|
|
1104
1176
|
.dark #sourcey .search-dialog-inner {
|
|
1105
1177
|
background: rgb(var(--color-gray-900));
|
|
1106
|
-
|
|
1178
|
+
border-color: rgb(var(--color-gray-700) / 0.5);
|
|
1179
|
+
box-shadow: 0 8px 32px rgb(var(--color-overlay) / 0.4);
|
|
1107
1180
|
}
|
|
1108
1181
|
|
|
1109
1182
|
#sourcey .search-input-row {
|
|
@@ -1173,7 +1246,8 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
1173
1246
|
gap: 0.25rem;
|
|
1174
1247
|
}
|
|
1175
1248
|
|
|
1176
|
-
#sourcey .search-footer kbd
|
|
1249
|
+
#sourcey .search-footer kbd,
|
|
1250
|
+
#sourcey #search-open kbd {
|
|
1177
1251
|
display: inline-flex;
|
|
1178
1252
|
align-items: center;
|
|
1179
1253
|
justify-content: center;
|
|
@@ -1188,7 +1262,8 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
1188
1262
|
background: rgb(var(--color-gray-50));
|
|
1189
1263
|
color: rgb(var(--color-gray-500));
|
|
1190
1264
|
}
|
|
1191
|
-
.dark #sourcey .search-footer kbd
|
|
1265
|
+
.dark #sourcey .search-footer kbd,
|
|
1266
|
+
.dark #sourcey #search-open kbd {
|
|
1192
1267
|
border-color: rgb(var(--color-gray-700));
|
|
1193
1268
|
background: rgb(var(--color-gray-800));
|
|
1194
1269
|
color: rgb(var(--color-gray-400));
|
|
@@ -1249,6 +1324,9 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
|
|
|
1249
1324
|
#sourcey .search-result-method.method-put { background: var(--method-put); }
|
|
1250
1325
|
#sourcey .search-result-method.method-delete { background: var(--method-delete); }
|
|
1251
1326
|
#sourcey .search-result-method.method-patch { background: var(--method-patch); }
|
|
1327
|
+
#sourcey .search-result-method.method-tool { background: var(--method-tool); }
|
|
1328
|
+
#sourcey .search-result-method.method-resource { background: var(--method-resource); }
|
|
1329
|
+
#sourcey .search-result-method.method-prompt { background: var(--method-prompt); }
|
|
1252
1330
|
|
|
1253
1331
|
#sourcey .search-result-path {
|
|
1254
1332
|
font-family: var(--font-mono);
|
package/dist/utils/icons.d.ts
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
* Each value is the inner path content (no wrapping <svg>).
|
|
7
7
|
* Render with: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">${path}</svg>`
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Return raw inner SVG content for a named icon, or undefined.
|
|
11
|
+
*/
|
|
12
|
+
export declare function iconPath(name: string): string | undefined;
|
|
9
13
|
/**
|
|
10
14
|
* Render a Heroicon as an inline SVG string.
|
|
11
15
|
* Returns empty string if the icon name is not found.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgFH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C"}
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgFH;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C"}
|
package/dist/utils/icons.js
CHANGED
|
@@ -46,6 +46,12 @@ const icons = {
|
|
|
46
46
|
info: '<path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"/>',
|
|
47
47
|
warning: '<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"/>',
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Return raw inner SVG content for a named icon, or undefined.
|
|
51
|
+
*/
|
|
52
|
+
export function iconPath(name) {
|
|
53
|
+
return icons[name];
|
|
54
|
+
}
|
|
49
55
|
/**
|
|
50
56
|
* Render a Heroicon as an inline SVG string.
|
|
51
57
|
* Returns empty string if the icon name is not found.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAgJD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3D"}
|
package/dist/utils/markdown.js
CHANGED
|
@@ -16,8 +16,104 @@ export function renderCodeBlock(text, lang) {
|
|
|
16
16
|
<div class="prose-code-content">${shiki}</div>
|
|
17
17
|
</div>`;
|
|
18
18
|
}
|
|
19
|
+
/* ── Shared directive helpers ─────────────────────────────────────── */
|
|
20
|
+
function parseDirectiveAttrs(raw) {
|
|
21
|
+
const attrs = {};
|
|
22
|
+
for (const [, k, v] of raw.matchAll(/(\w+)="([^"]*)"/g))
|
|
23
|
+
attrs[k] = v;
|
|
24
|
+
return attrs;
|
|
25
|
+
}
|
|
26
|
+
function escAttr(s) {
|
|
27
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
28
|
+
}
|
|
29
|
+
function requireHttps(url) {
|
|
30
|
+
try {
|
|
31
|
+
const u = new URL(url);
|
|
32
|
+
if (u.protocol !== "https:" && u.protocol !== "http:")
|
|
33
|
+
return null;
|
|
34
|
+
return u.href;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function parseVideoUrl(url) {
|
|
41
|
+
// YouTube
|
|
42
|
+
let m = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]+)/);
|
|
43
|
+
if (m)
|
|
44
|
+
return { src: `https://www.youtube-nocookie.com/embed/${m[1]}`, type: "iframe" };
|
|
45
|
+
// Vimeo
|
|
46
|
+
m = url.match(/vimeo\.com\/(\d+)/);
|
|
47
|
+
if (m)
|
|
48
|
+
return { src: `https://player.vimeo.com/video/${m[1]}`, type: "iframe" };
|
|
49
|
+
// Raw video
|
|
50
|
+
const ext = url.split(".").pop()?.toLowerCase();
|
|
51
|
+
const mime = ext === "webm" ? "video/webm" : "video/mp4";
|
|
52
|
+
return { src: url, type: "video", mime };
|
|
53
|
+
}
|
|
54
|
+
const videoExtension = {
|
|
55
|
+
extensions: [
|
|
56
|
+
{
|
|
57
|
+
name: "video",
|
|
58
|
+
level: "block",
|
|
59
|
+
start(src) {
|
|
60
|
+
return src.match(/::video\[/)?.index;
|
|
61
|
+
},
|
|
62
|
+
tokenizer(src) {
|
|
63
|
+
const match = src.match(/^::video\[([^\]]+)\](?:\{([^}]*)\})?/);
|
|
64
|
+
if (!match)
|
|
65
|
+
return undefined;
|
|
66
|
+
const attrs = parseDirectiveAttrs(match[2] ?? "");
|
|
67
|
+
return { type: "video", raw: match[0], url: match[1], title: attrs.title ?? "" };
|
|
68
|
+
},
|
|
69
|
+
renderer(token) {
|
|
70
|
+
const { url, title } = token;
|
|
71
|
+
const parsed = parseVideoUrl(url);
|
|
72
|
+
const safeTitle = escAttr(title);
|
|
73
|
+
if (parsed.type === "iframe") {
|
|
74
|
+
return `<div class="prose-video not-prose">
|
|
75
|
+
<iframe src="${parsed.src}" title="${safeTitle}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen loading="lazy"></iframe>
|
|
76
|
+
</div>\n`;
|
|
77
|
+
}
|
|
78
|
+
return `<div class="prose-video not-prose">
|
|
79
|
+
<video controls preload="metadata" title="${safeTitle}">
|
|
80
|
+
<source src="${parsed.src}" type="${parsed.mime}" />
|
|
81
|
+
</video>
|
|
82
|
+
</div>\n`;
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
const iframeExtension = {
|
|
88
|
+
extensions: [
|
|
89
|
+
{
|
|
90
|
+
name: "iframe",
|
|
91
|
+
level: "block",
|
|
92
|
+
start(src) {
|
|
93
|
+
return src.match(/::iframe\[/)?.index;
|
|
94
|
+
},
|
|
95
|
+
tokenizer(src) {
|
|
96
|
+
const match = src.match(/^::iframe\[([^\]]+)\](?:\{([^}]*)\})?/);
|
|
97
|
+
if (!match)
|
|
98
|
+
return undefined;
|
|
99
|
+
const attrs = parseDirectiveAttrs(match[2] ?? "");
|
|
100
|
+
const height = parseInt(attrs.height ?? "", 10);
|
|
101
|
+
return { type: "iframe", raw: match[0], url: match[1], title: attrs.title ?? "", height: Number.isFinite(height) ? height : 400 };
|
|
102
|
+
},
|
|
103
|
+
renderer(token) {
|
|
104
|
+
const { url, title, height } = token;
|
|
105
|
+
const safeUrl = requireHttps(url);
|
|
106
|
+
if (!safeUrl)
|
|
107
|
+
return `<p>[iframe: invalid URL]</p>\n`;
|
|
108
|
+
return `<div class="prose-iframe not-prose" style="height:${height}px">
|
|
109
|
+
<iframe src="${escAttr(safeUrl)}" title="${escAttr(title)}" frameborder="0" loading="lazy" allowfullscreen></iframe>
|
|
110
|
+
</div>\n`;
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
};
|
|
19
115
|
/** Singleton Marked instance — code blocks get Shiki + prose wrapper, headings get IDs. */
|
|
20
|
-
const marked = new Marked({
|
|
116
|
+
const marked = new Marked(videoExtension, iframeExtension, {
|
|
21
117
|
renderer: {
|
|
22
118
|
code({ text, lang }) {
|
|
23
119
|
return renderCodeBlock(text, lang);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sourcey",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
4
4
|
"description": "Open source documentation platform. API references, guides, static output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsc && cp -r src/themes dist/ && cp src/client/*.js dist/client/",
|
|
24
|
-
"
|
|
24
|
+
"watch": "npm run build && tsc --watch --preserveWatchOutput",
|
|
25
25
|
"test": "vitest run",
|
|
26
26
|
"test:watch": "vitest",
|
|
27
27
|
"lint": "eslint src/ test/",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"jiti": "^2.6.1",
|
|
40
40
|
"js-yaml": "^4.1.0",
|
|
41
41
|
"marked": "^15.0.0",
|
|
42
|
+
"mcp-parser": "^0.2.0",
|
|
42
43
|
"moxygen": "^2.1.1",
|
|
43
44
|
"preact": "^10.28.4",
|
|
44
45
|
"preact-render-to-string": "^6.6.6",
|
|
@@ -69,6 +70,9 @@
|
|
|
69
70
|
"developer-documentation",
|
|
70
71
|
"doxygen"
|
|
71
72
|
],
|
|
73
|
+
"funding": {
|
|
74
|
+
"url": "https://sourcey.com"
|
|
75
|
+
},
|
|
72
76
|
"author": "Kam Low <oss@0state.com> (https://sourcey.com)",
|
|
73
77
|
"license": "AGPL-3.0-only",
|
|
74
78
|
"repository": {
|