sourcey 3.4.11 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +13 -12
  2. package/dist/cli.js +46 -4
  3. package/dist/components/changelog/ChangelogPage.d.ts +5 -0
  4. package/dist/components/changelog/ChangelogPage.d.ts.map +1 -0
  5. package/dist/components/changelog/ChangelogPage.js +8 -0
  6. package/dist/components/changelog/EntryList.d.ts +5 -0
  7. package/dist/components/changelog/EntryList.d.ts.map +1 -0
  8. package/dist/components/changelog/EntryList.js +6 -0
  9. package/dist/components/changelog/TypeBadge.d.ts +6 -0
  10. package/dist/components/changelog/TypeBadge.d.ts.map +1 -0
  11. package/dist/components/changelog/TypeBadge.js +14 -0
  12. package/dist/components/changelog/VersionCard.d.ts +6 -0
  13. package/dist/components/changelog/VersionCard.d.ts.map +1 -0
  14. package/dist/components/changelog/VersionCard.js +25 -0
  15. package/dist/components/layout/Head.d.ts.map +1 -1
  16. package/dist/components/layout/Head.js +15 -3
  17. package/dist/components/layout/Page.d.ts.map +1 -1
  18. package/dist/components/layout/Page.js +12 -6
  19. package/dist/components/openapi/Introduction.d.ts.map +1 -1
  20. package/dist/components/openapi/Introduction.js +1 -1
  21. package/dist/components/openapi/MediaTypeDetails.d.ts +11 -0
  22. package/dist/components/openapi/MediaTypeDetails.d.ts.map +1 -0
  23. package/dist/components/openapi/MediaTypeDetails.js +54 -0
  24. package/dist/components/openapi/Parameters.d.ts.map +1 -1
  25. package/dist/components/openapi/Parameters.js +6 -1
  26. package/dist/components/openapi/RequestBody.d.ts.map +1 -1
  27. package/dist/components/openapi/RequestBody.js +5 -1
  28. package/dist/components/openapi/Responses.d.ts.map +1 -1
  29. package/dist/components/openapi/Responses.js +1 -1
  30. package/dist/components/openapi/Security.d.ts.map +1 -1
  31. package/dist/components/openapi/Security.js +3 -2
  32. package/dist/components/openapi/Tags.d.ts.map +1 -1
  33. package/dist/components/openapi/Tags.js +8 -1
  34. package/dist/config.d.ts +50 -1
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +50 -4
  37. package/dist/core/changelog-normalizer.d.ts +8 -0
  38. package/dist/core/changelog-normalizer.d.ts.map +1 -0
  39. package/dist/core/changelog-normalizer.js +531 -0
  40. package/dist/core/doxygen-loader.d.ts.map +1 -1
  41. package/dist/core/doxygen-loader.js +2 -0
  42. package/dist/core/loader.js +2 -0
  43. package/dist/core/markdown-loader.d.ts +21 -0
  44. package/dist/core/markdown-loader.d.ts.map +1 -1
  45. package/dist/core/markdown-loader.js +43 -25
  46. package/dist/core/mcp-normalizer.d.ts.map +1 -1
  47. package/dist/core/navigation.d.ts +2 -2
  48. package/dist/core/navigation.d.ts.map +1 -1
  49. package/dist/core/navigation.js +5 -1
  50. package/dist/core/normalizer.d.ts.map +1 -1
  51. package/dist/core/normalizer.js +102 -4
  52. package/dist/core/parser.d.ts +2 -2
  53. package/dist/core/parser.d.ts.map +1 -1
  54. package/dist/core/parser.js +23 -16
  55. package/dist/core/search-indexer.d.ts +3 -2
  56. package/dist/core/search-indexer.d.ts.map +1 -1
  57. package/dist/core/search-indexer.js +50 -17
  58. package/dist/core/tag-utils.d.ts +5 -0
  59. package/dist/core/tag-utils.d.ts.map +1 -0
  60. package/dist/core/tag-utils.js +22 -0
  61. package/dist/core/types.d.ts +82 -4
  62. package/dist/core/types.d.ts.map +1 -1
  63. package/dist/core/types.js +1 -1
  64. package/dist/dev-server.d.ts +2 -0
  65. package/dist/dev-server.d.ts.map +1 -1
  66. package/dist/dev-server.js +81 -210
  67. package/dist/index.d.ts +6 -10
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +115 -247
  70. package/dist/init.d.ts.map +1 -1
  71. package/dist/init.js +7 -3
  72. package/dist/og/fonts/Inter-Bold.ttf +0 -0
  73. package/dist/og/fonts/Inter-Regular.ttf +0 -0
  74. package/dist/og/generate-og-image.d.ts +10 -0
  75. package/dist/og/generate-og-image.d.ts.map +1 -0
  76. package/dist/og/generate-og-image.js +198 -0
  77. package/dist/renderer/changelog-feed.d.ts +18 -0
  78. package/dist/renderer/changelog-feed.d.ts.map +1 -0
  79. package/dist/renderer/changelog-feed.js +91 -0
  80. package/dist/renderer/context.d.ts +27 -7
  81. package/dist/renderer/context.d.ts.map +1 -1
  82. package/dist/renderer/html-builder.d.ts +10 -1
  83. package/dist/renderer/html-builder.d.ts.map +1 -1
  84. package/dist/renderer/html-builder.js +58 -5
  85. package/dist/renderer/llms.d.ts.map +1 -1
  86. package/dist/renderer/llms.js +133 -24
  87. package/dist/site-assembly.d.ts +25 -0
  88. package/dist/site-assembly.d.ts.map +1 -0
  89. package/dist/site-assembly.js +467 -0
  90. package/dist/site-url.d.ts +12 -0
  91. package/dist/site-url.d.ts.map +1 -0
  92. package/dist/site-url.js +67 -0
  93. package/dist/themes/default/sourcey.css +236 -0
  94. package/dist/utils/code-samples.d.ts.map +1 -1
  95. package/dist/utils/code-samples.js +53 -12
  96. package/dist/utils/markdown.d.ts +6 -0
  97. package/dist/utils/markdown.d.ts.map +1 -1
  98. package/dist/utils/markdown.js +11 -2
  99. package/dist/vite-plugin.d.ts +2 -0
  100. package/dist/vite-plugin.d.ts.map +1 -1
  101. package/dist/vite-plugin.js +6 -2
  102. package/package.json +6 -3
package/README.md CHANGED
@@ -18,18 +18,19 @@ npx sourcey init
18
18
 
19
19
  ## Features
20
20
 
21
- - **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#)
22
- - **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
23
- - **Markdown guides with rich components** — steps, cards, accordions, syntax-highlighted code blocks; prose docs alongside your API reference
24
- - **C++ and Doxygen** — feed Doxygen XML output, get modern searchable API docs. No new parser, no four-tool Breathe/Exhale/Sphinx pipeline
25
- - **llms.txt generation** — auto-generate llms.txt and llms-full.txt alongside your HTML. Docs serve developers and AI agents from one build
26
- - **TypeScript config** — `sourcey.config.ts` with `defineConfig()` autocomplete; theme, navbar, CTA buttons, footer
27
- - **Theme presets** — default (sidebar + TOC), minimal (single column), api-first (Stripe-style three column); colors, fonts, layout dimensions, and custom CSS on top
28
- - **Vite dev server** — SSR hot reload on every component and CSS change; spec and markdown changes trigger instant refresh
29
- - **Dark mode** — semantic design tokens, light/dark logo variants, localStorage persistence
30
- - **Client-side search** — instant fuzzy search across all pages and API operations; Cmd+K
31
- - **Static HTML output** — no framework runtime, no vendor lock-in. Deploy to GitHub Pages, Vercel, Netlify, S3, anywhere
32
- - **Open source** — AGPL-3.0. Self-host, fork, extend. Your docs, your infrastructure
21
+ - **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
22
+ - **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#)
23
+ - **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
24
+ - **Markdown guides with rich components**: steps, cards, accordions, syntax-highlighted code blocks; prose docs alongside your API reference
25
+ - **C++ and Doxygen**: feed Doxygen XML output, get modern searchable API docs. No new parser, no four-tool Breathe/Exhale/Sphinx pipeline
26
+ - **llms.txt generation**: auto-generate llms.txt and llms-full.txt alongside your HTML. Docs serve developers and AI agents from one build
27
+ - **TypeScript config**: `sourcey.config.ts` with `defineConfig()` autocomplete; theme, navbar, CTA buttons, footer
28
+ - **Theme presets**: default (sidebar + TOC), minimal (single column), api-first (Stripe-style three column); colors, fonts, layout dimensions, and custom CSS on top
29
+ - **Vite dev server**: SSR hot reload on every component and CSS change; spec and markdown changes trigger instant refresh
30
+ - **Dark mode**: semantic design tokens, light/dark logo variants, localStorage persistence
31
+ - **Client-side search**: instant fuzzy search across all pages and API operations; Cmd+K
32
+ - **Static HTML output**: no framework runtime, no vendor lock-in. Deploy to GitHub Pages, Vercel, Netlify, S3, anywhere
33
+ - **Open source**: AGPL-3.0. Self-host, fork, extend. Your docs, your infrastructure
33
34
 
34
35
  ### Sourcey vs alternatives
35
36
 
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@ import { defineCommand, runMain } from "citty";
3
3
  import { buildDocs, buildSiteDocs } from "./index.js";
4
4
  import { loadConfig } from "./config.js";
5
5
  import { init } from "./init.js";
6
+ import { formatChangelogDiagnostic } from "./site-assembly.js";
6
7
  import pkg from "../package.json" with { type: "json" };
7
8
  const build = defineCommand({
8
9
  meta: {
@@ -27,25 +28,38 @@ const build = defineCommand({
27
28
  description: "Embeddable output (no html/body wrapper)",
28
29
  default: false,
29
30
  },
31
+ config: {
32
+ type: "string",
33
+ alias: ["c"],
34
+ description: "Path to sourcey.config.ts (file or directory containing it)",
35
+ required: false,
36
+ },
30
37
  quiet: {
31
38
  type: "boolean",
32
39
  alias: ["q"],
33
40
  description: "Suppress output",
34
41
  default: false,
35
42
  },
43
+ strictChangelog: {
44
+ type: "boolean",
45
+ description: "Treat changelog warnings as build errors",
46
+ default: false,
47
+ },
36
48
  },
37
49
  async run({ args }) {
38
50
  const startTime = Date.now();
39
51
  try {
40
52
  if (args.spec) {
41
53
  if (!args.quiet)
42
- console.log(`\nSourcey — generating docs from ${args.spec}\n`);
54
+ console.log(`\nSourcey: generating docs from ${args.spec}\n`);
43
55
  const result = await buildDocs({
44
56
  specSource: args.spec,
45
57
  outputDir: args.output,
46
58
  embeddable: args.embed,
59
+ strictChangelog: args.strictChangelog,
47
60
  });
48
61
  if (!args.quiet) {
62
+ logChangelogDiagnostics(result.changelogDiagnostics);
49
63
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
50
64
  console.log(` Spec: ${result.spec.info.title} v${result.spec.info.version}`);
51
65
  console.log(` Operations: ${result.spec.operations.length}`);
@@ -54,15 +68,17 @@ const build = defineCommand({
54
68
  }
55
69
  }
56
70
  else {
57
- const config = await loadConfig();
71
+ const config = await loadConfig(args.config);
58
72
  if (!args.quiet)
59
- console.log(`\nSourcey — building documentation site\n`);
73
+ console.log(`\nSourcey: building documentation site\n`);
60
74
  const result = await buildSiteDocs({
61
75
  config,
62
76
  outputDir: args.output,
63
77
  embeddable: args.embed,
78
+ strictChangelog: args.strictChangelog,
64
79
  });
65
80
  if (!args.quiet) {
81
+ logChangelogDiagnostics(result.changelogDiagnostics);
66
82
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
67
83
  console.log(` Pages: ${result.pageCount}`);
68
84
  console.log(` Output: ${result.outputDir}`);
@@ -89,11 +105,24 @@ const dev = defineCommand({
89
105
  description: "Port to listen on",
90
106
  default: "4400",
91
107
  },
108
+ config: {
109
+ type: "string",
110
+ alias: ["c"],
111
+ description: "Path to sourcey.config.ts (file or directory containing it)",
112
+ required: false,
113
+ },
114
+ strictChangelog: {
115
+ type: "boolean",
116
+ description: "Treat changelog warnings as dev errors",
117
+ default: false,
118
+ },
92
119
  },
93
120
  async run({ args }) {
94
121
  const { startDevServer } = await import("./dev-server.js");
95
122
  await startDevServer({
96
123
  port: parseInt(args.port, 10),
124
+ config: args.config,
125
+ strictChangelog: args.strictChangelog,
97
126
  });
98
127
  },
99
128
  });
@@ -150,11 +179,24 @@ const main = defineCommand({
150
179
  return;
151
180
  if (args.spec) {
152
181
  await build.run({
153
- args: { _: [], spec: args.spec, output: "dist", embed: false, quiet: false },
182
+ args: {
183
+ _: [],
184
+ spec: args.spec,
185
+ output: "dist",
186
+ embed: false,
187
+ config: undefined,
188
+ quiet: false,
189
+ strictChangelog: false,
190
+ },
154
191
  rawArgs: [],
155
192
  cmd: build,
156
193
  });
157
194
  }
158
195
  },
159
196
  });
197
+ function logChangelogDiagnostics(diagnostics) {
198
+ for (const diagnostic of diagnostics) {
199
+ console.log(` ${formatChangelogDiagnostic(diagnostic)}`);
200
+ }
201
+ }
160
202
  runMain(main);
@@ -0,0 +1,5 @@
1
+ import type { ChangelogPage as ChangelogPageData } from "../../core/markdown-loader.js";
2
+ export declare function ChangelogPage({ page }: {
3
+ page: ChangelogPageData;
4
+ }): import("preact").JSX.Element;
5
+ //# sourceMappingURL=ChangelogPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangelogPage.d.ts","sourceRoot":"","sources":["../../../src/components/changelog/ChangelogPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGxF,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,gCAyBlE"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { VersionCard } from "./VersionCard.js";
3
+ export function ChangelogPage({ page }) {
4
+ const versions = page.permalinkVersionId
5
+ ? page.changelog.versions.filter((version) => version.id === page.permalinkVersionId)
6
+ : page.changelog.versions;
7
+ return (_jsxs("div", { class: "sourcey-changelog-page", children: [_jsxs("header", { class: "sourcey-changelog-header", children: [_jsx("div", { class: "mt-0.5 space-y-2.5", children: _jsx("h1", { class: "text-2xl sm:text-3xl text-[rgb(var(--color-gray-900))] tracking-tight dark:text-[rgb(var(--color-gray-200))] font-bold", style: "overflow-wrap: anywhere", children: page.title }) }), page.description && (_jsx("p", { class: "sourcey-changelog-description", children: page.description }))] }), _jsx("div", { class: "sourcey-changelog-list", children: versions.map((version) => (_jsx(VersionCard, { version: version }, version.id))) })] }));
8
+ }
@@ -0,0 +1,5 @@
1
+ import type { NormalizedChangelogEntry } from "../../core/types.js";
2
+ export declare function EntryList({ entries }: {
3
+ entries: NormalizedChangelogEntry[];
4
+ }): import("preact").JSX.Element | null;
5
+ //# sourceMappingURL=EntryList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntryList.d.ts","sourceRoot":"","sources":["../../../src/components/changelog/EntryList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,wBAAwB,EAAE,CAAA;CAAE,uCAU7E"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ export function EntryList({ entries }) {
3
+ if (!entries.length)
4
+ return null;
5
+ return (_jsx("ul", { class: "sourcey-changelog-entry-list", children: entries.map((entry, index) => (_jsx("li", { dangerouslySetInnerHTML: { __html: entry.html } }, `${entry.text}-${index}`))) }));
6
+ }
@@ -0,0 +1,6 @@
1
+ import type { ChangelogChangeType } from "../../core/types.js";
2
+ export declare function TypeBadge({ type, label, }: {
3
+ type: ChangelogChangeType;
4
+ label: string;
5
+ }): import("preact").JSX.Element;
6
+ //# sourceMappingURL=TypeBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeBadge.d.ts","sourceRoot":"","sources":["../../../src/components/changelog/TypeBadge.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAY/D,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,GACN,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf,gCAEA"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import { Badge } from "../ui/Badge.js";
3
+ const BADGE_CLASS = {
4
+ added: "sourcey-changelog-badge sourcey-changelog-badge-added",
5
+ changed: "sourcey-changelog-badge sourcey-changelog-badge-changed",
6
+ fixed: "sourcey-changelog-badge sourcey-changelog-badge-fixed",
7
+ removed: "sourcey-changelog-badge sourcey-changelog-badge-removed",
8
+ deprecated: "sourcey-changelog-badge sourcey-changelog-badge-deprecated",
9
+ security: "sourcey-changelog-badge sourcey-changelog-badge-security",
10
+ other: "sourcey-changelog-badge sourcey-changelog-badge-other",
11
+ };
12
+ export function TypeBadge({ type, label, }) {
13
+ return _jsx(Badge, { class: BADGE_CLASS[type], children: label });
14
+ }
@@ -0,0 +1,6 @@
1
+ import type { NormalizedChangelogVersion } from "../../core/types.js";
2
+ export declare function VersionCard({ version, permalinkHref, }: {
3
+ version: NormalizedChangelogVersion;
4
+ permalinkHref?: string;
5
+ }): import("preact").JSX.Element;
6
+ //# sourceMappingURL=VersionCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionCard.d.ts","sourceRoot":"","sources":["../../../src/components/changelog/VersionCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAoBtE,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,aAAa,GACd,EAAE;IACD,OAAO,EAAE,0BAA0B,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,gCAuCA"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { Markdown } from "../ui/Markdown.js";
3
+ import { EntryList } from "./EntryList.js";
4
+ import { TypeBadge } from "./TypeBadge.js";
5
+ function formatDate(date) {
6
+ if (!date)
7
+ return null;
8
+ try {
9
+ return new Intl.DateTimeFormat("en", {
10
+ year: "numeric",
11
+ month: "long",
12
+ day: "numeric",
13
+ timeZone: "UTC",
14
+ }).format(new Date(`${date}T00:00:00Z`));
15
+ }
16
+ catch {
17
+ return date;
18
+ }
19
+ }
20
+ export function VersionCard({ version, permalinkHref, }) {
21
+ const href = permalinkHref ?? `#${version.id}`;
22
+ const label = version.version ?? "Unreleased";
23
+ const formattedDate = formatDate(version.date);
24
+ return (_jsxs("article", { id: version.id, class: `sourcey-changelog-version${version.version ? "" : " sourcey-changelog-version-unreleased"}`, children: [_jsxs("header", { class: "sourcey-changelog-version-header", children: [_jsxs("div", { class: "sourcey-changelog-version-heading", children: [_jsx("a", { href: href, class: "sourcey-changelog-version-link", children: label }), version.yanked && _jsx("span", { class: "sourcey-changelog-pill sourcey-changelog-pill-yanked", children: "YANKED" }), version.prerelease && _jsx("span", { class: "sourcey-changelog-pill sourcey-changelog-pill-pre", children: "pre" })] }), _jsxs("div", { class: "sourcey-changelog-version-meta", children: [formattedDate && _jsx("time", { dateTime: version.date ?? undefined, children: formattedDate }), version.compareUrl && (_jsx("a", { href: version.compareUrl, target: "_blank", rel: "noopener noreferrer", class: "sourcey-changelog-compare-link", children: "Compare" }))] })] }), version.summary && _jsx(Markdown, { content: version.summary, class: "sourcey-changelog-summary" }), _jsx("div", { class: "sourcey-changelog-sections", children: version.sections.map((section) => (_jsxs("section", { class: "sourcey-changelog-section", children: [_jsx("div", { class: "sourcey-changelog-section-header", children: _jsx(TypeBadge, { type: section.type, label: section.label }) }), _jsx(EntryList, { entries: section.entries })] }, `${version.id}-${section.label}`))) })] }));
25
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Head.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Head.tsx"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,iCAwEnB"}
1
+ {"version":3,"file":"Head.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Head.tsx"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,iCA8FnB"}
@@ -8,13 +8,25 @@ export function Head() {
8
8
  const spec = useContext(SpecContext);
9
9
  const options = useContext(OptionsContext);
10
10
  const page = useContext(PageContext);
11
+ const changelogVersion = page.kind === "changelog" && page.changelog.permalinkVersionId
12
+ ? page.changelog.changelog.versions.find((version) => version.id === page.changelog.permalinkVersionId)
13
+ : undefined;
11
14
  const siteName = site.name || spec.info.title || "";
12
15
  const pageTitle = page.kind === "markdown"
13
16
  ? (siteName ? `${page.markdown.title} — ${siteName}` : page.markdown.title)
14
- : `${siteName} — API Reference`;
17
+ : page.kind === "changelog"
18
+ ? (() => {
19
+ const baseTitle = changelogVersion
20
+ ? `${changelogVersion.version ?? "Unreleased"} — ${page.changelog.title}`
21
+ : page.changelog.title;
22
+ return siteName ? `${baseTitle} — ${siteName}` : baseTitle;
23
+ })()
24
+ : `${siteName} — API Reference`;
15
25
  const pageDescription = page.kind === "markdown"
16
26
  ? page.markdown.description || pageTitle
17
- : spec.info.description ?? `${siteName} API Documentation`;
27
+ : page.kind === "changelog"
28
+ ? changelogVersion?.summary || page.changelog.description || pageTitle
29
+ : spec.info.summary ?? spec.info.description ?? `${siteName} API Documentation`;
18
30
  const nav = useContext(NavigationContext);
19
31
  const { colors, fonts, layout } = site.theme;
20
32
  // Desktop: h-16 row + h-12 tabs (when multi-tab) = 7rem, or h-16 alone = 4rem.
@@ -44,5 +56,5 @@ export function Head() {
44
56
  body { margin: 0; background: rgb(var(--color-background-light)); }
45
57
  .dark body { background: rgb(var(--color-background-dark)); }
46
58
  `;
47
- return (_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: pageTitle }), _jsx("meta", { name: "description", content: pageDescription }), _jsx("meta", { name: "generator", content: `Sourcey ${pkg.version}` }), _jsx("meta", { property: "og:title", content: pageTitle }), _jsx("meta", { property: "og:description", content: pageDescription }), _jsx("meta", { property: "og:type", content: "website" }), siteName && _jsx("meta", { property: "og:site_name", content: siteName }), _jsx("meta", { name: "twitter:card", content: "summary" }), _jsx("meta", { name: "twitter:title", content: pageTitle }), _jsx("meta", { name: "twitter:description", content: pageDescription }), _jsx("meta", { name: "sourcey-search", content: `${options.assetBase}search-index.json` }), _jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "anonymous" }), _jsx("link", { rel: "stylesheet", href: `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fonts.googleFont)}:wght@100..900&display=swap` }), _jsx("style", { dangerouslySetInnerHTML: { __html: themeCSS } }), showLangIconCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: langIconCSS() } }), site.customCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: site.customCSS } }), _jsx("script", { dangerouslySetInnerHTML: { __html: `(function(){var t=localStorage.getItem('sourcey-theme');if(t==='dark')document.documentElement.classList.add('dark')})()` } }), _jsx("link", { rel: "stylesheet", href: `${options.assetBase}sourcey.css` }), site.favicon && _jsx("link", { rel: "icon", href: site.favicon })] }));
59
+ return (_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: pageTitle }), _jsx("meta", { name: "description", content: pageDescription }), _jsx("meta", { name: "generator", content: `Sourcey ${pkg.version}` }), options.pageUrl && _jsx("link", { rel: "canonical", href: options.pageUrl }), _jsx("meta", { property: "og:title", content: pageTitle }), _jsx("meta", { property: "og:description", content: pageDescription }), _jsx("meta", { property: "og:type", content: "website" }), siteName && _jsx("meta", { property: "og:site_name", content: siteName }), options.pageUrl && _jsx("meta", { property: "og:url", content: options.pageUrl }), options.ogImageUrl && _jsx("meta", { property: "og:image", content: options.ogImageUrl }), options.ogImageUrl && _jsx("meta", { property: "og:image:width", content: "1200" }), options.ogImageUrl && _jsx("meta", { property: "og:image:height", content: "630" }), options.ogImageUrl && _jsx("meta", { property: "og:image:type", content: "image/png" }), _jsx("meta", { name: "twitter:card", content: options.ogImageUrl ? "summary_large_image" : "summary" }), _jsx("meta", { name: "twitter:title", content: pageTitle }), _jsx("meta", { name: "twitter:description", content: pageDescription }), options.ogImageUrl && _jsx("meta", { name: "twitter:image", content: options.ogImageUrl }), _jsx("meta", { name: "sourcey-search", content: `${options.assetBase}search-index.json` }), options.alternateLinks?.map((link) => (_jsx("link", { rel: "alternate", type: link.type, href: link.href, title: link.title }, `${link.type}-${link.href}`))), _jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "anonymous" }), _jsx("link", { rel: "stylesheet", href: `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fonts.googleFont)}:wght@100..900&display=swap` }), _jsx("style", { dangerouslySetInnerHTML: { __html: themeCSS } }), showLangIconCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: langIconCSS() } }), site.customCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: site.customCSS } }), _jsx("script", { dangerouslySetInnerHTML: { __html: `(function(){var t=localStorage.getItem('sourcey-theme');if(t==='dark')document.documentElement.classList.add('dark')})()` } }), _jsx("link", { rel: "stylesheet", href: `${options.assetBase}sourcey.css` }), site.favicon && _jsx("link", { rel: "icon", href: site.favicon })] }));
48
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Page.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Page.tsx"],"names":[],"mappings":"AAsPA,wBAAgB,IAAI,iCAqCnB"}
1
+ {"version":3,"file":"Page.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Page.tsx"],"names":[],"mappings":"AAoRA,wBAAgB,IAAI,iCAqCnB"}
@@ -11,6 +11,7 @@ import { Tags } from "../openapi/Tags.js";
11
11
  import { Definition } from "../openapi/Definition.js";
12
12
  import { SocialIcon, socialLabels } from "../ui/SocialIcon.js";
13
13
  import { McpConnection } from "../mcp/McpConnection.js";
14
+ import { ChangelogPage } from "../changelog/ChangelogPage.js";
14
15
  /**
15
16
  * Markdown page content with prose typography.
16
17
  */
@@ -22,13 +23,16 @@ function MarkdownPageContent({ page, className = "" }) {
22
23
  const eyebrow = activeGroup?.label;
23
24
  return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsxs("header", { class: "relative leading-none", children: [_jsxs("div", { class: "mt-0.5 space-y-2.5", children: [eyebrow && (_jsx("div", { class: "h-5 text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))] text-sm font-semibold", children: eyebrow })), _jsx("div", { class: "flex flex-col sm:flex-row items-start sm:items-center relative gap-2 min-w-0", children: _jsx("h1", { class: "text-2xl sm:text-3xl text-[rgb(var(--color-gray-900))] tracking-tight dark:text-[rgb(var(--color-gray-200))] font-bold", style: "overflow-wrap: anywhere", children: page.title }) })] }), page.description && (_jsx("div", { class: "page-description mt-2 text-lg prose prose-gray dark:prose-invert", style: "overflow-wrap: anywhere", children: _jsx(Markdown, { content: page.description, inline: true }) }))] }), _jsx("div", { class: "prose prose-gray dark:prose-invert relative mt-8 mb-14 max-w-none", dangerouslySetInnerHTML: { __html: page.html } }), _jsx(PageNavigation, {}), _jsx(ContentFooter, {})] }));
24
25
  }
26
+ function ChangelogPageContent({ page, className = "" }) {
27
+ return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsx(ChangelogPage, { page: page }), _jsx(PageNavigation, {}), _jsx(ContentFooter, {})] }));
28
+ }
25
29
  /**
26
30
  * OpenAPI spec page content.
27
31
  */
28
32
  function SpecPageContent({ className = "" }) {
29
33
  const spec = useContext(SpecContext);
30
34
  const serverUrl = spec.servers[0]?.url ?? "/";
31
- return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsxs("article", { children: [_jsx("header", { class: "mb-8", children: _jsxs("div", { class: "flex items-baseline gap-3", children: [_jsx("h1", { class: "text-2xl sm:text-3xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight", children: spec.info.title }), _jsxs("span", { class: "text-sm text-[rgb(var(--color-gray-500))] dark:text-[rgb(var(--color-gray-400))]", children: ["v", spec.info.version] })] }) }), _jsx(Introduction, {}), spec.operations[0]?.mcpExtras?.connection && (_jsx(McpConnection, { connection: spec.operations[0].mcpExtras.connection })), _jsx(SecurityDefinitions, {}), _jsx(Tags, { tags: spec.tags, serverUrl: serverUrl }), Object.keys(spec.schemas).length > 0 && (_jsxs("div", { class: "mt-12", children: [_jsx("div", { class: "mb-6", children: _jsx("h1", { class: "text-xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: "Models" }) }), Object.entries(spec.schemas).map(([name, schema]) => (_jsx(Definition, { name: name, schema: schema }, name)))] }))] }), _jsx(ContentFooter, {})] }));
35
+ return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsxs("article", { children: [_jsxs("header", { class: "mb-8", children: [_jsxs("div", { class: "flex items-baseline gap-3", children: [_jsx("h1", { class: "text-2xl sm:text-3xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight", children: spec.info.title }), _jsxs("span", { class: "text-sm text-[rgb(var(--color-gray-500))] dark:text-[rgb(var(--color-gray-400))]", children: ["v", spec.info.version] })] }), spec.info.summary && (_jsx("p", { class: "mt-2 max-w-2xl text-sm text-[rgb(var(--color-gray-600))] dark:text-[rgb(var(--color-gray-400))]", children: spec.info.summary }))] }), _jsx(Introduction, {}), spec.operations[0]?.mcpExtras?.connection && (_jsx(McpConnection, { connection: spec.operations[0].mcpExtras.connection })), _jsx(SecurityDefinitions, {}), _jsx(Tags, { tags: spec.tags, serverUrl: serverUrl }), Object.keys(spec.schemas).length > 0 && (_jsxs("div", { class: "mt-12", children: [_jsx("div", { class: "mb-6", children: _jsx("h1", { class: "text-xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: "Models" }) }), Object.entries(spec.schemas).map(([name, schema]) => (_jsx(Definition, { name: name, schema: schema }, name)))] }))] }), _jsx(ContentFooter, {})] }));
32
36
  }
33
37
  function PageNavigation() {
34
38
  const nav = useContext(NavigationContext);
@@ -58,8 +62,10 @@ function ContentFooter() {
58
62
  // Build "Edit this page" URL when repo + editBranch are configured
59
63
  let editUrl;
60
64
  const editPath = page.kind === "markdown"
61
- ? (page.markdown?.editPath === undefined ? page.markdown?.sourcePath : page.markdown?.editPath)
62
- : undefined;
65
+ ? (page.markdown.editPath === undefined ? page.markdown.sourcePath : page.markdown.editPath)
66
+ : page.kind === "changelog"
67
+ ? (page.changelog.editPath === undefined ? page.changelog.sourcePath : page.changelog.editPath)
68
+ : undefined;
63
69
  if (site.repo && site.editBranch && editPath) {
64
70
  const repoBase = site.repo.replace(/\/$/, "");
65
71
  const basePath = site.editBasePath ? `${site.editBasePath.replace(/^\/|\/$/g, "")}/` : "";
@@ -75,15 +81,15 @@ function ContentFooter() {
75
81
  // ---------------------------------------------------------------------------
76
82
  function DefaultLayout() {
77
83
  const page = useContext(PageContext);
78
- return (_jsxs("div", { class: "max-w-[92rem] mx-auto relative px-4 lg:px-8", children: [_jsx(Sidebar, {}), _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.markdown.headings }), _jsx(MarkdownPageContent, { page: page.markdown, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : (_jsx(SpecPageContent, { className: "lg:pl-[23.7rem] lg:-ml-12" })) })] }));
84
+ return (_jsxs("div", { class: "max-w-[92rem] mx-auto relative px-4 lg:px-8", children: [_jsx(Sidebar, {}), _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.markdown.headings }), _jsx(MarkdownPageContent, { page: page.markdown, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : page.kind === "changelog" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.changelog.headings }), _jsx(ChangelogPageContent, { page: page.changelog, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : (_jsx(SpecPageContent, { className: "lg:pl-[23.7rem] lg:-ml-12" })) })] }));
79
85
  }
80
86
  function MinimalLayout() {
81
87
  const page = useContext(PageContext);
82
- return (_jsx("div", { class: "max-w-3xl mx-auto relative px-4 lg:px-8", children: _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsx(MarkdownPageContent, { page: page.markdown })) : (_jsx(SpecPageContent, {})) }) }));
88
+ return (_jsx("div", { class: "max-w-3xl mx-auto relative px-4 lg:px-8", children: _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsx(MarkdownPageContent, { page: page.markdown })) : page.kind === "changelog" ? (_jsx(ChangelogPageContent, { page: page.changelog })) : (_jsx(SpecPageContent, {})) }) }));
83
89
  }
84
90
  function ApiFirstLayout() {
85
91
  const page = useContext(PageContext);
86
- return (_jsxs("div", { class: "max-w-[92rem] mx-auto relative px-4 lg:px-8", children: [_jsx(Sidebar, {}), _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.markdown.headings }), _jsx(MarkdownPageContent, { page: page.markdown, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : (_jsx(SpecPageContent, { className: "lg:pl-[23.7rem] lg:-ml-12" })) })] }));
92
+ return (_jsxs("div", { class: "max-w-[92rem] mx-auto relative px-4 lg:px-8", children: [_jsx(Sidebar, {}), _jsx("main", { id: "docs", class: "pt-[8.5rem] lg:pt-10", children: page.kind === "markdown" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.markdown.headings }), _jsx(MarkdownPageContent, { page: page.markdown, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : page.kind === "changelog" ? (_jsxs("div", { class: "flex flex-row-reverse gap-12 box-border w-full", children: [_jsx(TableOfContents, { headings: page.changelog.headings }), _jsx(ChangelogPageContent, { page: page.changelog, className: "lg:pl-[23.7rem] lg:-ml-12 xl:w-[calc(100%-28rem)]" })] })) : (_jsx(SpecPageContent, { className: "lg:pl-[23.7rem] lg:-ml-12" })) })] }));
87
93
  }
88
94
  // ---------------------------------------------------------------------------
89
95
  // Page shell
@@ -1 +1 @@
1
- {"version":3,"file":"Introduction.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Introduction.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,YAAY,iCAuC3B"}
1
+ {"version":3,"file":"Introduction.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Introduction.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,YAAY,iCAqC3B"}
@@ -9,5 +9,5 @@ import { Markdown } from "../ui/Markdown.js";
9
9
  export function Introduction() {
10
10
  const spec = useContext(SpecContext);
11
11
  const { info, servers } = spec;
12
- return (_jsxs("div", { id: "introduction", "data-traverse-target": "introduction", class: "mb-8", children: [info.termsOfService && (_jsx("p", { class: "mt-4 text-sm text-[rgb(var(--color-gray-500))]", children: _jsx("a", { href: info.termsOfService, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: "Terms of Service" }) })), info.contact?.email && (_jsxs("p", { class: "mt-2 text-sm text-[rgb(var(--color-gray-500))]", children: ["Contact: ", _jsx("a", { href: `mailto:${info.contact.email}`, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: info.contact.email })] })), servers.length > 0 && (_jsxs("div", { class: "mt-6 rounded-[var(--radius)] border border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)] overflow-x-auto", children: [_jsxs("div", { class: "px-4 py-2.5 text-xs font-semibold text-[rgb(var(--color-gray-600))] dark:text-[rgb(var(--color-gray-300))] border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)]", children: ["Base URL", servers.length > 1 ? "s" : ""] }), servers.map((s, i) => (_jsxs("div", { class: `flex items-baseline gap-3 px-4 py-2 ${i > 0 ? "border-t border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))]" : ""}`, children: [_jsx("code", { class: "font-mono text-sm text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: s.url }), s.description && (_jsx("span", { class: "text-xs text-[rgb(var(--color-gray-500))]", children: s.description }))] }, i)))] })), info.description && (_jsx(Markdown, { content: info.description, class: "max-w-none mt-8" }))] }));
12
+ return (_jsxs("div", { id: "introduction", "data-traverse-target": "introduction", class: "mb-8", children: [info.termsOfService && (_jsx("p", { class: "mt-4 text-sm text-[rgb(var(--color-gray-500))]", children: _jsx("a", { href: info.termsOfService, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: "Terms of Service" }) })), info.contact?.email && (_jsxs("p", { class: "mt-2 text-sm text-[rgb(var(--color-gray-500))]", children: ["Contact: ", _jsx("a", { href: `mailto:${info.contact.email}`, class: "text-[rgb(var(--color-primary-ink))] dark:text-[rgb(var(--color-primary-light))]", children: info.contact.email })] })), servers.length > 0 && (_jsxs("div", { class: "mt-6 rounded-[var(--radius)] border border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)] overflow-x-auto", children: [_jsxs("div", { class: "px-4 py-2.5 text-xs font-semibold text-[rgb(var(--color-gray-600))] dark:text-[rgb(var(--color-gray-300))] border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)]", children: ["Base URL", servers.length > 1 ? "s" : ""] }), servers.map((s, i) => (_jsxs("div", { class: `flex items-baseline gap-3 px-4 py-2 ${i > 0 ? "border-t border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))]" : ""}`, children: [_jsx("code", { class: "font-mono text-sm text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: s.url }), s.description && (_jsx("span", { class: "text-xs text-[rgb(var(--color-gray-500))]", children: s.description }))] }, i)))] })), info.description && _jsx(Markdown, { content: info.description, class: "max-w-none mt-8" })] }));
13
13
  }
@@ -0,0 +1,11 @@
1
+ import type { MediaTypeContent } from "../../core/types.js";
2
+ interface MediaTypeDetailsProps {
3
+ mediaType: string;
4
+ content: MediaTypeContent;
5
+ showLabel?: boolean;
6
+ }
7
+ export declare function MediaTypeDetails({ mediaType, content, showLabel }: MediaTypeDetailsProps): import("preact").JSX.Element | null;
8
+ export declare function firstContentSchema(content?: Record<string, MediaTypeContent>): import("../../core/types.js").NormalizedSchema | undefined;
9
+ export declare function contentMediaTypes(content?: Record<string, MediaTypeContent>): string[];
10
+ export {};
11
+ //# sourceMappingURL=MediaTypeDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaTypeDetails.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/MediaTypeDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,gBAAgB,EAAuB,MAAM,qBAAqB,CAAC;AAIjG,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,SAAS,EAAE,OAAO,EAAE,SAAgB,EAAE,EAAE,qBAAqB,uCAsBhE;AAED,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,8DAI3C;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,EAAE,CAEtF"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { SchemaDatatype } from "../schema/SchemaDatatype.js";
3
+ import { Badge, DeprecatedBadge, RequiredBadge } from "../ui/Badge.js";
4
+ export function MediaTypeDetails({ mediaType, content, showLabel = true }) {
5
+ const hasEncodings = hasEncodingDetails(content);
6
+ if (!showLabel && !hasEncodings)
7
+ return null;
8
+ return (_jsxs("div", { class: showLabel ? "mt-4" : "", children: [showLabel && (_jsxs("div", { class: "mb-3 flex flex-wrap items-center gap-2", children: [_jsx("code", { class: "text-xs font-medium text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: mediaType }), content.schema && (_jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: content.schema }) }))] })), hasEncodings && _jsx(EncodingDetails, { content: content })] }));
9
+ }
10
+ export function firstContentSchema(content) {
11
+ if (!content)
12
+ return undefined;
13
+ return Object.values(content).find((mediaType) => mediaType.schema)?.schema;
14
+ }
15
+ export function contentMediaTypes(content) {
16
+ return content ? Object.keys(content) : [];
17
+ }
18
+ function hasEncodingDetails(content) {
19
+ return Object.keys(content.encoding ?? {}).length > 0
20
+ || (content.prefixEncoding?.length ?? 0) > 0
21
+ || !!content.itemEncoding;
22
+ }
23
+ function EncodingDetails({ content }) {
24
+ const namedEntries = Object.entries(content.encoding ?? {});
25
+ const positionalEntries = [
26
+ ...(content.prefixEncoding ?? []).map((encoding, index) => ({
27
+ name: `[${index}]`,
28
+ encoding,
29
+ })),
30
+ ...(content.itemEncoding ? [{ name: "[n]", encoding: content.itemEncoding }] : []),
31
+ ];
32
+ if (!namedEntries.length && !positionalEntries.length)
33
+ return null;
34
+ return (_jsxs("div", { class: "mt-4", children: [_jsx("div", { class: "text-xs font-semibold uppercase tracking-[0.14em] text-[rgb(var(--color-gray-500))]", children: "Encoding" }), namedEntries.length > 0 && (_jsx(EncodingList, { className: "params-list mt-2", entries: namedEntries.map(([name, encoding]) => ({ name, encoding })) })), positionalEntries.length > 0 && (_jsxs("div", { class: namedEntries.length > 0 ? "mt-4" : "mt-2", children: [_jsx("div", { class: "text-xs font-medium text-[rgb(var(--color-gray-500))]", children: "Ordered Parts" }), _jsx(EncodingList, { className: "params-list mt-2", entries: positionalEntries })] }))] }));
35
+ }
36
+ function EncodingList({ entries, className = "params-list" }) {
37
+ return (_jsx("div", { class: className, children: entries.map((entry) => (_jsx(EncodingItem, { name: entry.name, encoding: entry.encoding }, entry.name))) }));
38
+ }
39
+ function EncodingItem({ name, encoding }) {
40
+ const headerEntries = Object.entries(encoding.headers ?? {});
41
+ const nestedEntries = [
42
+ ...(encoding.prefixEncoding ?? []).map((entry, index) => ({
43
+ name: `[${index}]`,
44
+ encoding: entry,
45
+ })),
46
+ ...(encoding.itemEncoding ? [{ name: "[n]", encoding: encoding.itemEncoding }] : []),
47
+ ];
48
+ return (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: name }), encoding.contentType && (_jsx("span", { class: "param-type", children: _jsx("code", { class: "text-xs font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: encoding.contentType }) })), encoding.style && _jsxs(Badge, { children: ["style ", encoding.style] }), encoding.explode !== undefined && _jsxs(Badge, { children: ["explode ", String(encoding.explode)] }), encoding.allowReserved !== undefined && (_jsxs(Badge, { children: ["allowReserved ", String(encoding.allowReserved)] }))] }), headerEntries.length > 0 && (_jsxs("div", { class: "mt-3", children: [_jsx("div", { class: "text-xs font-medium text-[rgb(var(--color-gray-500))]", children: "Headers" }), _jsx("div", { class: "params-list mt-2", children: headerEntries.map(([headerName, header]) => (_jsx(EncodingHeader, { name: headerName, header: header }, headerName))) })] })), nestedEntries.length > 0 && (_jsxs("div", { class: "mt-3", children: [_jsx("div", { class: "text-xs font-medium text-[rgb(var(--color-gray-500))]", children: "Nested Encoding" }), _jsx(EncodingList, { className: "params-list mt-2", entries: nestedEntries })] }))] }));
49
+ }
50
+ function EncodingHeader({ name, header }) {
51
+ const schema = header.schema ?? firstContentSchema(header.content);
52
+ const mediaTypes = contentMediaTypes(header.content);
53
+ return (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: name }), schema && (_jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: schema }) })), mediaTypes.length > 0 && (_jsx("span", { class: "param-type", children: _jsx("code", { class: "text-xs font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: mediaTypes.join(", ") }) })), header.required && _jsx(RequiredBadge, {}), header.deprecated && _jsx(DeprecatedBadge, {})] }), header.description && (_jsx("div", { class: "param-description", children: header.description }))] }));
54
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Parameters.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Parameters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAK/D,UAAU,eAAe;IACvB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,EAAE,eAAe,uCA2BzD"}
1
+ {"version":3,"file":"Parameters.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Parameters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAM/D,UAAU,eAAe;IACvB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,EAAE,eAAe,uCAgDzD"}
@@ -2,8 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { SchemaDatatype } from "../schema/SchemaDatatype.js";
3
3
  import { RequiredBadge, DeprecatedBadge } from "../ui/Badge.js";
4
4
  import { Markdown } from "../ui/Markdown.js";
5
+ import { MediaTypeDetails, contentMediaTypes, firstContentSchema } from "./MediaTypeDetails.js";
5
6
  export function Parameters({ parameters }) {
6
7
  if (!parameters.length)
7
8
  return null;
8
- return (_jsx("div", { class: "params-list", children: parameters.map((param) => (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: param.name }), param.schema && (_jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: param.schema }) })), param.required && _jsx(RequiredBadge, {}), param.deprecated && _jsx(DeprecatedBadge, {}), _jsx("span", { class: "param-in", children: param.in })] }), param.description && (_jsx("div", { class: "param-description", children: _jsx(Markdown, { content: param.description, class: "prose-sm" }) }))] }, `${param.in}-${param.name}`))) }));
9
+ return (_jsx("div", { class: "params-list", children: parameters.map((param) => {
10
+ const schema = param.schema ?? firstContentSchema(param.content);
11
+ const mediaTypes = contentMediaTypes(param.content);
12
+ return (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: param.name }), schema && (_jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: schema }) })), mediaTypes.length > 0 && (_jsx("span", { class: "param-type", children: _jsx("code", { class: "text-xs font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: mediaTypes.join(", ") }) })), param.required && _jsx(RequiredBadge, {}), param.deprecated && _jsx(DeprecatedBadge, {}), _jsx("span", { class: "param-in", children: param.in })] }), (param.description || mediaTypes.length > 0) && (_jsxs("div", { class: "param-description", children: [param.description && (_jsx(Markdown, { content: param.description, class: "prose-sm" })), param.content && Object.entries(param.content).map(([mediaType, content]) => (_jsx(MediaTypeDetails, { mediaType: mediaType, content: content, showLabel: true }, mediaType)))] }))] }, `${param.in}-${param.name}`));
13
+ }) }));
9
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RequestBody.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/RequestBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAKjE,UAAU,gBAAgB;IACxB,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,gBAAgB,uCAkBrD;AAED,UAAU,uBAAuB;IAC/B,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,uBAAuB,uCAQnE"}
1
+ {"version":3,"file":"RequestBody.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/RequestBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAMjE,UAAU,gBAAgB;IACxB,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,gBAAgB,uCA4BrD;AAED,UAAU,uBAAuB;IAC/B,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,uBAAuB,uCAQnE"}
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { SchemaView } from "../schema/SchemaView.js";
3
3
  import { ExampleView } from "../schema/ExampleView.js";
4
4
  import { Markdown } from "../ui/Markdown.js";
5
+ import { MediaTypeDetails } from "./MediaTypeDetails.js";
5
6
  /**
6
7
  * Request body content (rendered in the main content column).
7
8
  */
@@ -9,7 +10,10 @@ export function RequestBody({ body }) {
9
10
  const mediaTypes = Object.entries(body.content);
10
11
  if (!mediaTypes.length)
11
12
  return null;
12
- return (_jsx("div", { children: mediaTypes.map(([mediaType, content]) => (_jsxs("div", { children: [body.description && (_jsx("div", { class: "mb-4 text-sm text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-400))]", children: _jsx(Markdown, { content: body.description }) })), content.schema && _jsx(SchemaView, { schema: content.schema })] }, mediaType))) }));
13
+ return (_jsxs("div", { children: [body.description && (_jsx("div", { class: "mb-4 text-sm text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-400))]", children: _jsx(Markdown, { content: body.description }) })), mediaTypes.map(([mediaType, content]) => (_jsxs("div", { class: mediaTypes.length > 1 ? "mt-8 first:mt-0" : "", children: [_jsx(MediaTypeDetails, { mediaType: mediaType, content: content, showLabel: mediaTypes.length > 1
14
+ || Object.keys(content.encoding ?? {}).length > 0
15
+ || (content.prefixEncoding?.length ?? 0) > 0
16
+ || !!content.itemEncoding }), content.schema && _jsx(SchemaView, { schema: content.schema })] }, mediaType)))] }));
13
17
  }
14
18
  /**
15
19
  * Request body example (rendered in the sticky code panel).
@@ -1 +1 @@
1
- {"version":3,"file":"Responses.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Responses.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAS9D,UAAU,cAAc;IACtB,SAAS,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAUD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,uCA6B1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,uCAiE9D"}
1
+ {"version":3,"file":"Responses.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Responses.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAS9D,UAAU,cAAc;IACtB,SAAS,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAUD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,uCAoC1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,uCAiE9D"}
@@ -23,7 +23,7 @@ function statusColorClass(code) {
23
23
  export function ResponsesCopy({ responses }) {
24
24
  if (!responses.length)
25
25
  return null;
26
- return (_jsx("div", { class: "params-list", children: responses.map((r) => (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header font-mono text-sm", children: [_jsx("span", { class: `px-1.5 py-0.5 rounded-md text-xs font-bold ${statusColorClass(r.statusCode)}`, children: r.statusCode }), _jsx("span", { class: "font-medium text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: httpStatusText(r.statusCode) }), r.content && (_jsx("span", { class: "param-type", children: renderResponseType(r) }))] }), r.description && (_jsx("div", { class: "param-description", children: _jsx(Markdown, { content: r.description, class: "prose-sm" }) }))] }, r.statusCode))) }));
26
+ return (_jsx("div", { class: "params-list", children: responses.map((r) => (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header font-mono text-sm", children: [_jsx("span", { class: `px-1.5 py-0.5 rounded-md text-xs font-bold ${statusColorClass(r.statusCode)}`, children: r.statusCode }), _jsx("span", { class: "font-medium text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: httpStatusText(r.statusCode) }), r.content && (_jsx("span", { class: "param-type", children: renderResponseType(r) }))] }), (r.summary || r.description) && (_jsxs("div", { class: "param-description", children: [r.summary && (_jsx("p", { class: "text-sm font-medium text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: r.summary })), r.description && (_jsx(Markdown, { content: r.description, class: "prose-sm" }))] }))] }, r.statusCode))) }));
27
27
  }
28
28
  /**
29
29
  * Response examples with status code tabs on the code block card.
@@ -1 +1 @@
1
- {"version":3,"file":"Security.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Security.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,UAAU,aAAa;IACrB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,aAAa,uCA8CvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,wCA+ElC"}
1
+ {"version":3,"file":"Security.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Security.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAK/D,UAAU,aAAa;IACrB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,aAAa,uCA+CvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,wCA8FlC"}