sourcey 3.4.4 → 3.4.7

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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { SitePage } from "./renderer/html-builder.js";
1
2
  import type { NormalizedSpec } from "./core/types.js";
2
3
  import type { ResolvedConfig } from "./config.js";
3
4
  export interface BuildOptions {
@@ -30,6 +31,14 @@ export interface SiteBuildResult {
30
31
  _specs?: Map<string, NormalizedSpec>;
31
32
  }
32
33
  export declare function buildSiteDocs(options?: SiteBuildOptions): Promise<SiteBuildResult>;
34
+ /**
35
+ * Rewrite internal links in markdown page HTML to correct relative .html paths.
36
+ *
37
+ * Authors write links like [Page](/slug) or [Page](/tab/slug). This pass
38
+ * rewrites matching href values so they resolve on static file servers
39
+ * that don't support extensionless URLs.
40
+ */
41
+ export declare function resolveInternalLinks(pages: SitePage[], config: ResolvedConfig): void;
33
42
  export { defineConfig } from "./config.js";
34
43
  export type { NormalizedSpec, NormalizedOperation, NormalizedTag, NormalizedSchema, NormalizedParameter, NormalizedRequestBody, NormalizedResponse, } from "./core/types.js";
35
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,aAAa,CAAC;AAe/D,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAY3E;AAMD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACtC;AAED,wBAAsB,aAAa,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoH5F;AAgKD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,aAAa,CAAC;AAe/D,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAY3E;AAMD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACtC;AAED,wBAAsB,aAAa,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoH5F;AA6ED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAmGpF;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -204,7 +204,7 @@ async function resolveAssetUrl(pathOrUrl) {
204
204
  * rewrites matching href values so they resolve on static file servers
205
205
  * that don't support extensionless URLs.
206
206
  */
207
- function resolveInternalLinks(pages, config) {
207
+ export function resolveInternalLinks(pages, config) {
208
208
  // Build a map from every plausible clean path to the output path.
209
209
  // e.g. "components" -> "components.html", "config/ref-theme-tokens" -> "config/ref-theme-tokens.html"
210
210
  const pathMap = new Map();
@@ -212,6 +212,13 @@ function resolveInternalLinks(pages, config) {
212
212
  const out = page.outputPath; // e.g. "components.html" or "config/ref-theme-tokens.html"
213
213
  const clean = out.replace(/\.html$/, ""); // "components" or "config/ref-theme-tokens"
214
214
  pathMap.set(clean, out);
215
+ if (page.currentPage.kind === "markdown" && page.currentPage.markdown?.sourcePath) {
216
+ const sourceClean = page.currentPage.markdown.sourcePath
217
+ .replace(/\\/g, "/")
218
+ .replace(/^\/+/, "")
219
+ .replace(/\.(md|mdx)$/, "");
220
+ pathMap.set(sourceClean, out);
221
+ }
215
222
  }
216
223
  // Repo source link base: e.g. "https://github.com/user/repo/tree/main"
217
224
  const repoBase = config.repo?.replace(/\/$/, "");
@@ -234,22 +241,37 @@ function resolveInternalLinks(pages, config) {
234
241
  // Split off hash fragment
235
242
  const [path, hash] = href.split("#", 2);
236
243
  const hashSuffix = hash ? `#${hash}` : "";
237
- // Normalize: strip leading slash, trailing slash, and .md extension
238
- const clean = path.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\.md$/, "");
244
+ // Normalize: strip leading slash, trailing slash, and markdown extension
245
+ const sourcePath = path.replace(/\\/g, "/");
246
+ const clean = sourcePath.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\.(md|mdx)$/, "");
239
247
  // Skip if already has .html extension
240
248
  if (clean.endsWith(".html"))
241
249
  return _match;
242
- // Look up in path map — try the full clean path first, then
250
+ const candidates = new Set();
251
+ // Relative markdown links should resolve against the current page's
252
+ // source path, not just the built output path.
253
+ if (!sourcePath.startsWith("/") && md.sourcePath) {
254
+ const sourceDir = posix.dirname(md.sourcePath.replace(/\\/g, "/"));
255
+ candidates.add(posix.normalize(posix.join(sourceDir, clean)));
256
+ }
257
+ candidates.add(clean);
258
+ // Look up in path map — try the resolved path first, then
243
259
  // progressively strip leading segments to handle deployment prefixes
244
- // (e.g. "/docs/components" → "docs/components" → "components")
260
+ // (e.g. "docs/components" → "components").
245
261
  let target;
246
- let candidate = clean;
247
- while (!target && candidate) {
248
- target = pathMap.get(candidate);
249
- const slash = candidate.indexOf("/");
250
- if (slash === -1)
262
+ for (const initialCandidate of candidates) {
263
+ let candidate = initialCandidate;
264
+ while (!target && candidate && candidate !== ".") {
265
+ target = pathMap.get(candidate);
266
+ if (target)
267
+ break;
268
+ const slash = candidate.indexOf("/");
269
+ if (slash === -1)
270
+ break;
271
+ candidate = candidate.substring(slash + 1);
272
+ }
273
+ if (target)
251
274
  break;
252
- candidate = candidate.substring(slash + 1);
253
275
  }
254
276
  if (target) {
255
277
  // Build relative path from this page to the target
@@ -1 +1 @@
1
- {"version":3,"file":"html-builder.d.ts","sourceRoot":"","sources":["../../src/renderer/html-builder.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAiB,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0B5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F,OAAO,CAAC,WAAW,CAAC,CAsDtB"}
1
+ {"version":3,"file":"html-builder.d.ts","sourceRoot":"","sources":["../../src/renderer/html-builder.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAiB,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0B5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F,OAAO,CAAC,WAAW,CAAC,CAuDtB"}
@@ -1,4 +1,4 @@
1
- import { mkdir, writeFile, readFile, access } from "node:fs/promises";
1
+ import { mkdir, writeFile, readFile, access, rm } from "node:fs/promises";
2
2
  import { resolve, dirname } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { build as viteBuild } from "vite";
@@ -35,6 +35,7 @@ async function resolveAssetPaths() {
35
35
  */
36
36
  export async function buildSite(pages, navigation, outputDir, site, options) {
37
37
  const resolvedDir = resolve(outputDir);
38
+ await rm(resolvedDir, { recursive: true, force: true });
38
39
  await mkdir(resolvedDir, { recursive: true });
39
40
  for (const page of pages) {
40
41
  const pageDir = dirname(resolve(resolvedDir, page.outputPath));
@@ -71,6 +71,6 @@
71
71
  --method-prompt: #2563eb;
72
72
 
73
73
  /* Typography */
74
- --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
74
+ --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
75
75
  --font-mono: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, 'Liberation Mono', Menlo, monospace;
76
76
  }
@@ -134,6 +134,18 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
134
134
  display: block;
135
135
  }
136
136
 
137
+ /* ── Inline Code (not-prose containers lose Tailwind prose styling) ── */
138
+
139
+ #sourcey .not-prose :not(pre) > code {
140
+ font-size: 0.875em;
141
+ font-weight: 600;
142
+ color: var(--tw-prose-code);
143
+ }
144
+ #sourcey .not-prose :not(pre) > code::before,
145
+ #sourcey .not-prose :not(pre) > code::after {
146
+ content: "`";
147
+ }
148
+
137
149
  /* ── Prose Code Block (fenced code in markdown pages) ─────────────── */
138
150
 
139
151
  #sourcey .prose-code-block {
@@ -206,8 +218,8 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
206
218
  /* ── Nav Links ────────────────────────────────────────────────────── */
207
219
 
208
220
  #sourcey .nav-group-label {
209
- padding: 0.25rem 0.75rem 0.25rem 1rem;
210
- margin-bottom: 0.25rem;
221
+ padding: 0 0.75rem 0.25rem 1rem;
222
+ margin-bottom: 0.625rem;
211
223
  font-size: inherit;
212
224
  font-weight: 600;
213
225
  color: rgb(var(--color-gray-900));
@@ -232,13 +244,13 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
232
244
  #sourcey .nav-link {
233
245
  display: flex;
234
246
  align-items: flex-start;
235
- padding: 0.25rem 0.75rem 0.25rem 1rem;
247
+ padding: 0.375rem 0.75rem 0.375rem 1rem;
236
248
  gap: 0.75rem;
237
249
  cursor: pointer;
238
250
  text-align: left;
239
251
  overflow-wrap: break-word;
240
252
  hyphens: auto;
241
- border-radius: 0.375rem;
253
+ border-radius: 0.75rem;
242
254
  width: 100%;
243
255
  color: rgb(var(--color-gray-700));
244
256
  transition: color 0.15s, background-color 0.15s;
@@ -257,7 +269,7 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
257
269
  #sourcey .nav-link.active {
258
270
  color: rgb(var(--color-primary-ink));
259
271
  background: rgb(var(--color-primary) / 0.08);
260
- font-weight: 500;
272
+ text-shadow: -0.2px 0 0 currentColor, 0.2px 0 0 currentColor;
261
273
  }
262
274
  .dark #sourcey .nav-link.active {
263
275
  color: rgb(var(--color-primary-light));
@@ -273,6 +285,7 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
273
285
  }
274
286
  #sourcey #toc ul ul .toc-item {
275
287
  margin-left: 0.75rem;
288
+ border-left: none;
276
289
  }
277
290
  .dark #sourcey #toc .toc-item {
278
291
  border-left-color: rgb(var(--color-gray-700));
@@ -280,6 +293,7 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
280
293
  #sourcey #toc .toc-item.active {
281
294
  color: rgb(var(--color-primary-ink));
282
295
  border-left-color: rgb(var(--color-primary-ink));
296
+ font-weight: 500;
283
297
  }
284
298
  .dark #sourcey #toc .toc-item.active {
285
299
  color: rgb(var(--color-primary-light));
@@ -2,8 +2,8 @@
2
2
  * Heroicons (outline, 24x24) — MIT License
3
3
  * https://heroicons.com
4
4
  *
5
- * Inline SVG map for card icons and other markdown components.
6
- * Each value is the inner path content (no wrapping <svg>).
5
+ * Loads ALL 324 outline icons from the heroicons package at build time.
6
+ * Icon names use kebab-case (e.g. "arrow-right", "academic-cap").
7
7
  * Render with: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">${path}</svg>`
8
8
  */
9
9
  /**
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiCH;;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"}
@@ -2,50 +2,32 @@
2
2
  * Heroicons (outline, 24x24) — MIT License
3
3
  * https://heroicons.com
4
4
  *
5
- * Inline SVG map for card icons and other markdown components.
6
- * Each value is the inner path content (no wrapping <svg>).
5
+ * Loads ALL 324 outline icons from the heroicons package at build time.
6
+ * Icon names use kebab-case (e.g. "arrow-right", "academic-cap").
7
7
  * Render with: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">${path}</svg>`
8
8
  */
9
- const icons = {
10
- // Search / discovery
11
- search: '<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>',
12
- // Commerce
13
- cart: '<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"/>',
14
- // People / users
15
- users: '<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/>',
16
- // Notifications
17
- bell: '<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0"/>',
18
- // Code / terminal
19
- code: '<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5"/>',
20
- terminal: '<path stroke-linecap="round" stroke-linejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z"/>',
21
- // Documents / books
22
- book: '<path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25"/>',
23
- document: '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/>',
24
- // Security
25
- key: '<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"/>',
26
- shield: '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z"/>',
27
- lock: '<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"/>',
28
- // Connectivity
29
- plug: '<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"/>',
30
- globe: '<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418"/>',
31
- // Data
32
- database: '<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125"/>',
33
- // Communication
34
- envelope: '<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75"/>',
35
- // Navigation / flow
36
- arrow: '<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/>',
37
- bolt: '<path stroke-linecap="round" stroke-linejoin="round" d="m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z"/>',
38
- // Settings / config
39
- cog: '<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>',
40
- // Misc
41
- star: '<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>',
42
- rocket: '<path stroke-linecap="round" stroke-linejoin="round" d="M15.59 14.37a48.414 48.414 0 0 1-6.01-1.7c-.837-.25-1.538-.707-2.088-1.257m8.098 2.957a48.108 48.108 0 0 0 3.478-.852c.227-.07.457-.14.689-.213a1.5 1.5 0 0 0 .955-1.04l.44-2.201a1.5 1.5 0 0 0-.725-1.594l-1.898-1.1a1.5 1.5 0 0 0-1.501 0l-1.898 1.1a1.5 1.5 0 0 0-.725 1.594l.44 2.2c.065.324-.057.662-.283.906M15.59 14.37l-3.79 3.79a1.5 1.5 0 0 1-2.122 0l-.379-.379M15.59 14.37l3.79-3.79a1.5 1.5 0 0 0 0-2.122l-.379-.379m-7.422 6.29-2.29 2.29M9.5 11.413l-2.29-2.29M6.912 15.4l-1.342 1.342a1.5 1.5 0 0 0 0 2.121l.707.707a1.5 1.5 0 0 0 2.121 0l1.342-1.342"/>',
43
- cube: '<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9"/>',
44
- heart: '<path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"/>',
45
- check: '<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>',
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
- 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
- };
9
+ import { readdirSync, readFileSync } from "fs";
10
+ import { join, basename } from "path";
11
+ import { createRequire } from "module";
12
+ const require = createRequire(import.meta.url);
13
+ const outlineDir = join(require.resolve("heroicons/package.json"), "..", "24", "outline");
14
+ /**
15
+ * Extract inner SVG content (everything between the opening <svg> and closing </svg> tags).
16
+ */
17
+ function extractInnerSvg(svgContent) {
18
+ return svgContent
19
+ .replace(/<svg[^>]*>/, "")
20
+ .replace(/<\/svg>\s*$/, "")
21
+ .trim();
22
+ }
23
+ const icons = {};
24
+ for (const file of readdirSync(outlineDir)) {
25
+ if (!file.endsWith(".svg"))
26
+ continue;
27
+ const name = basename(file, ".svg");
28
+ const raw = readFileSync(join(outlineDir, file), "utf-8");
29
+ icons[name] = extractInnerSvg(raw);
30
+ }
49
31
  /**
50
32
  * Return raw inner SVG content for a named icon, or undefined.
51
33
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sourcey",
3
- "version": "3.4.4",
4
- "description": "Open source documentation platform. API references, guides, static output.",
3
+ "version": "3.4.7",
4
+ "description": "Precision documentation from OpenAPI, MCP, Doxygen, and Markdown. Static HTML you own.",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=20"
@@ -36,6 +36,7 @@
36
36
  "@tailwindcss/typography": "^0.5.19",
37
37
  "@tailwindcss/vite": "^4.2.2",
38
38
  "citty": "^0.1.6",
39
+ "heroicons": "^2.2.0",
39
40
  "jiti": "^2.6.1",
40
41
  "js-yaml": "^4.1.0",
41
42
  "marked": "^15.0.0",