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
@@ -867,6 +867,242 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
867
867
  #sourcey .callout-warning .callout-title { color: #f59e0b; }
868
868
  .dark #sourcey .callout-warning .callout-title { color: #fbbf24; }
869
869
 
870
+ /* ── Changelog ───────────────────────────────────────────────────── */
871
+
872
+ #sourcey .sourcey-changelog-page {
873
+ width: 100%;
874
+ }
875
+
876
+ #sourcey .sourcey-changelog-header {
877
+ margin-bottom: 2rem;
878
+ }
879
+
880
+ #sourcey .sourcey-changelog-description {
881
+ margin-top: 0.75rem;
882
+ font-size: 1.05rem;
883
+ line-height: 1.7;
884
+ color: rgb(var(--color-gray-600));
885
+ }
886
+
887
+ .dark #sourcey .sourcey-changelog-description {
888
+ color: rgb(var(--color-gray-400));
889
+ }
890
+
891
+ #sourcey .sourcey-changelog-list {
892
+ display: flex;
893
+ flex-direction: column;
894
+ gap: 1rem;
895
+ }
896
+
897
+ #sourcey .sourcey-changelog-version {
898
+ border: 1px solid rgb(var(--color-gray-200) / 0.8);
899
+ border-radius: 1rem;
900
+ padding: 1.25rem 1.25rem 1rem;
901
+ background: linear-gradient(180deg, rgb(var(--color-gray-50) / 0.75), rgb(255 255 255));
902
+ }
903
+
904
+ .dark #sourcey .sourcey-changelog-version {
905
+ border-color: rgb(var(--color-gray-800) / 0.8);
906
+ background: linear-gradient(180deg, rgb(255 255 255 / 0.03), rgb(255 255 255 / 0.015));
907
+ }
908
+
909
+ #sourcey .sourcey-changelog-version-unreleased {
910
+ border-style: dashed;
911
+ }
912
+
913
+ #sourcey .sourcey-changelog-version-header {
914
+ display: flex;
915
+ align-items: flex-start;
916
+ justify-content: space-between;
917
+ gap: 1rem;
918
+ margin-bottom: 1rem;
919
+ }
920
+
921
+ @media (max-width: 768px) {
922
+ #sourcey .sourcey-changelog-version-header {
923
+ flex-direction: column;
924
+ }
925
+ }
926
+
927
+ #sourcey .sourcey-changelog-version-heading {
928
+ display: flex;
929
+ align-items: center;
930
+ gap: 0.5rem;
931
+ flex-wrap: wrap;
932
+ }
933
+
934
+ #sourcey .sourcey-changelog-version-link {
935
+ font-size: 1.25rem;
936
+ font-weight: 700;
937
+ color: rgb(var(--color-gray-900));
938
+ text-decoration: none;
939
+ }
940
+
941
+ .dark #sourcey .sourcey-changelog-version-link {
942
+ color: rgb(var(--color-gray-200));
943
+ }
944
+
945
+ #sourcey .sourcey-changelog-version-link:hover {
946
+ color: rgb(var(--color-primary-ink));
947
+ }
948
+
949
+ .dark #sourcey .sourcey-changelog-version-link:hover {
950
+ color: rgb(var(--color-primary-light));
951
+ }
952
+
953
+ #sourcey .sourcey-changelog-version-meta {
954
+ display: flex;
955
+ align-items: center;
956
+ gap: 0.75rem;
957
+ font-size: 0.925rem;
958
+ color: rgb(var(--color-gray-500));
959
+ }
960
+
961
+ .dark #sourcey .sourcey-changelog-version-meta {
962
+ color: rgb(var(--color-gray-400));
963
+ }
964
+
965
+ #sourcey .sourcey-changelog-compare-link {
966
+ color: rgb(var(--color-primary-ink));
967
+ text-decoration: none;
968
+ }
969
+
970
+ .dark #sourcey .sourcey-changelog-compare-link {
971
+ color: rgb(var(--color-primary-light));
972
+ }
973
+
974
+ #sourcey .sourcey-changelog-pill {
975
+ display: inline-flex;
976
+ align-items: center;
977
+ border-radius: 999px;
978
+ padding: 0.15rem 0.5rem;
979
+ font-size: 0.72rem;
980
+ font-weight: 700;
981
+ letter-spacing: 0.03em;
982
+ }
983
+
984
+ #sourcey .sourcey-changelog-pill-yanked {
985
+ background: rgb(239 68 68 / 0.12);
986
+ color: rgb(185 28 28);
987
+ }
988
+
989
+ .dark #sourcey .sourcey-changelog-pill-yanked {
990
+ background: rgb(248 113 113 / 0.15);
991
+ color: rgb(252 165 165);
992
+ }
993
+
994
+ #sourcey .sourcey-changelog-pill-pre {
995
+ background: rgb(var(--color-gray-100));
996
+ color: rgb(var(--color-gray-600));
997
+ }
998
+
999
+ .dark #sourcey .sourcey-changelog-pill-pre {
1000
+ background: rgb(255 255 255 / 0.08);
1001
+ color: rgb(var(--color-gray-300));
1002
+ }
1003
+
1004
+ #sourcey .sourcey-changelog-summary {
1005
+ margin-bottom: 1rem;
1006
+ }
1007
+
1008
+ #sourcey .sourcey-changelog-summary p:first-child {
1009
+ margin-top: 0;
1010
+ }
1011
+
1012
+ #sourcey .sourcey-changelog-sections {
1013
+ display: flex;
1014
+ flex-direction: column;
1015
+ gap: 0.875rem;
1016
+ }
1017
+
1018
+ #sourcey .sourcey-changelog-section {
1019
+ display: flex;
1020
+ flex-direction: column;
1021
+ gap: 0.5rem;
1022
+ }
1023
+
1024
+ #sourcey .sourcey-changelog-section-header {
1025
+ display: flex;
1026
+ align-items: center;
1027
+ gap: 0.5rem;
1028
+ }
1029
+
1030
+ #sourcey .sourcey-changelog-entry-list {
1031
+ margin: 0;
1032
+ padding-left: 1.25rem;
1033
+ color: rgb(var(--color-gray-700));
1034
+ }
1035
+
1036
+ .dark #sourcey .sourcey-changelog-entry-list {
1037
+ color: rgb(var(--color-gray-300));
1038
+ }
1039
+
1040
+ #sourcey .sourcey-changelog-entry-list li {
1041
+ margin: 0.35rem 0;
1042
+ }
1043
+
1044
+ #sourcey .sourcey-changelog-entry-list li > p {
1045
+ margin: 0;
1046
+ }
1047
+
1048
+ #sourcey .sourcey-changelog-badge {
1049
+ text-transform: none;
1050
+ }
1051
+
1052
+ #sourcey .sourcey-changelog-badge-added {
1053
+ background: rgb(var(--color-success) / 0.12);
1054
+ color: rgb(21 128 61);
1055
+ }
1056
+
1057
+ .dark #sourcey .sourcey-changelog-badge-added {
1058
+ background: rgb(var(--color-success) / 0.16);
1059
+ color: rgb(134 239 172);
1060
+ }
1061
+
1062
+ #sourcey .sourcey-changelog-badge-changed {
1063
+ background: rgb(var(--color-primary) / 0.12);
1064
+ color: rgb(var(--color-primary-ink));
1065
+ }
1066
+
1067
+ .dark #sourcey .sourcey-changelog-badge-changed {
1068
+ background: rgb(var(--color-primary-light) / 0.12);
1069
+ color: rgb(var(--color-primary-light));
1070
+ }
1071
+
1072
+ #sourcey .sourcey-changelog-badge-fixed {
1073
+ background: rgb(245 158 11 / 0.14);
1074
+ color: rgb(180 83 9);
1075
+ }
1076
+
1077
+ .dark #sourcey .sourcey-changelog-badge-fixed {
1078
+ background: rgb(251 191 36 / 0.16);
1079
+ color: rgb(253 224 71);
1080
+ }
1081
+
1082
+ #sourcey .sourcey-changelog-badge-removed,
1083
+ #sourcey .sourcey-changelog-badge-security {
1084
+ background: rgb(239 68 68 / 0.12);
1085
+ color: rgb(185 28 28);
1086
+ }
1087
+
1088
+ .dark #sourcey .sourcey-changelog-badge-removed,
1089
+ .dark #sourcey .sourcey-changelog-badge-security {
1090
+ background: rgb(248 113 113 / 0.16);
1091
+ color: rgb(252 165 165);
1092
+ }
1093
+
1094
+ #sourcey .sourcey-changelog-badge-deprecated,
1095
+ #sourcey .sourcey-changelog-badge-other {
1096
+ background: rgb(var(--color-gray-100));
1097
+ color: rgb(var(--color-gray-600));
1098
+ }
1099
+
1100
+ .dark #sourcey .sourcey-changelog-badge-deprecated,
1101
+ .dark #sourcey .sourcey-changelog-badge-other {
1102
+ background: rgb(255 255 255 / 0.08);
1103
+ color: rgb(var(--color-gray-300));
1104
+ }
1105
+
870
1106
  /* Tip — green */
871
1107
  #sourcey .callout-tip { border-left-color: #22c55e; }
872
1108
  .dark #sourcey .callout-tip { border-left-color: #4ade80; }
@@ -1 +1 @@
1
- {"version":3,"file":"code-samples.d.ts","sourceRoot":"","sources":["../../src/utils/code-samples.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAuLnD,8CAA8C;AAC9C,eAAO,MAAM,yBAAyB,UAAmC,CAAC;AAM1E;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,mBAAmB,EACvB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAM,EAA8B,GAC1C,UAAU,EAAE,CAmBd"}
1
+ {"version":3,"file":"code-samples.d.ts","sourceRoot":"","sources":["../../src/utils/code-samples.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAuMnD,8CAA8C;AAC9C,eAAO,MAAM,yBAAyB,UAAmC,CAAC;AAM1E;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,mBAAmB,EACvB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAM,EAA8B,GAC1C,UAAU,EAAE,CAmBd"}
@@ -43,7 +43,10 @@ const generators = {
43
43
  else if (contentType) {
44
44
  args.push(`headers={'Content-Type': '${contentType}'}`);
45
45
  }
46
- lines.push(`response = requests.${method.toLowerCase()}(${args.join(", ")})`);
46
+ const request = pythonShortcutMethod(method)
47
+ ? `requests.${method.toLowerCase()}(${args.join(", ")})`
48
+ : `requests.request('${method}', ${args.join(", ")})`;
49
+ lines.push(`response = ${request}`);
47
50
  lines.push(`data = response.json()`);
48
51
  return { lang: "python", label: "Python", source: lines.join("\n") };
49
52
  },
@@ -75,12 +78,20 @@ const generators = {
75
78
  ``,
76
79
  `uri = URI('${url}')`,
77
80
  ];
78
- const methodClass = method === "GET" ? "Get" : method === "POST" ? "Post" : method === "PUT" ? "Put" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Patch" : "Post";
79
- lines.push(`request = Net::HTTP::${methodClass}.new(uri)`);
80
- if (contentType)
81
- lines.push(`request['Content-Type'] = '${contentType}'`);
82
- if (body)
83
- lines.push(`request.body = '${indent(body, 2)}'`);
81
+ const methodClass = rubyShortcutMethod(method);
82
+ if (methodClass) {
83
+ lines.push(`request = Net::HTTP::${methodClass}.new(uri)`);
84
+ if (contentType)
85
+ lines.push(`request['Content-Type'] = '${contentType}'`);
86
+ if (body)
87
+ lines.push(`request.body = '${indent(body, 2)}'`);
88
+ }
89
+ else {
90
+ const headers = contentType ? `{ 'Content-Type' => '${contentType}' }` : "{}";
91
+ lines.push(`request = Net::HTTPGenericRequest.new('${method}', ${body ? "true" : "false"}, true, uri.request_uri, ${headers})`);
92
+ if (body)
93
+ lines.push(`request.body = '${indent(body, 2)}'`);
94
+ }
84
95
  lines.push(``, `response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }`);
85
96
  lines.push(`data = JSON.parse(response.body)`);
86
97
  return { lang: "ruby", label: "Ruby", source: lines.join("\n") };
@@ -133,14 +144,16 @@ const generators = {
133
144
  `async fn main() -> Result<(), reqwest::Error> {`,
134
145
  ` let client = reqwest::Client::new();`,
135
146
  ];
136
- const m = method.toLowerCase();
147
+ const requestBuilder = rustShortcutMethod(method)
148
+ ? `client.${method.toLowerCase()}("${url}")`
149
+ : `client.request(reqwest::Method::from_bytes(b"${method}").unwrap(), "${url}")`;
137
150
  if (body) {
138
151
  lines.push(` let body = serde_json::json!(${indent(body, 4)});`);
139
- lines.push(` let response = client.${m}("${url}")`);
152
+ lines.push(` let response = ${requestBuilder}`);
140
153
  lines.push(` .json(&body)`);
141
154
  }
142
155
  else {
143
- lines.push(` let response = client.${m}("${url}")`);
156
+ lines.push(` let response = ${requestBuilder}`);
144
157
  }
145
158
  lines.push(` .send()`);
146
159
  lines.push(` .await?`);
@@ -156,12 +169,15 @@ const generators = {
156
169
  `using var client = new HttpClient();`,
157
170
  ``,
158
171
  ];
172
+ const httpMethod = csharpShortcutMethod(method)
173
+ ? `HttpMethod.${method[0] + method.slice(1).toLowerCase()}`
174
+ : `new HttpMethod("${method}")`;
159
175
  if (body) {
160
176
  lines.push(`var content = new StringContent("""`, ` ${indent(body, 4)}""", System.Text.Encoding.UTF8, "application/json");`);
161
- lines.push(`var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.${method[0] + method.slice(1).toLowerCase()}, "${url}") { Content = content });`);
177
+ lines.push(`var response = await client.SendAsync(new HttpRequestMessage(${httpMethod}, "${url}") { Content = content });`);
162
178
  }
163
179
  else {
164
- lines.push(`var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.${method[0] + method.slice(1).toLowerCase()}, "${url}"));`);
180
+ lines.push(`var response = await client.SendAsync(new HttpRequestMessage(${httpMethod}, "${url}"));`);
165
181
  }
166
182
  lines.push(`var data = await response.Content.ReadAsStringAsync();`);
167
183
  return { lang: "csharp", label: "C#", source: lines.join("\n") };
@@ -218,6 +234,31 @@ function pythonDict(jsonStr) {
218
234
  .replace(/: false/g, ": False")
219
235
  .replace(/: null/g, ": None");
220
236
  }
237
+ function pythonShortcutMethod(method) {
238
+ return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(method);
239
+ }
240
+ function rubyShortcutMethod(method) {
241
+ switch (method) {
242
+ case "GET":
243
+ return "Get";
244
+ case "POST":
245
+ return "Post";
246
+ case "PUT":
247
+ return "Put";
248
+ case "DELETE":
249
+ return "Delete";
250
+ case "PATCH":
251
+ return "Patch";
252
+ default:
253
+ return undefined;
254
+ }
255
+ }
256
+ function rustShortcutMethod(method) {
257
+ return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(method);
258
+ }
259
+ function csharpShortcutMethod(method) {
260
+ return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(method);
261
+ }
221
262
  /** Indent all lines of a multi-line string except the first. */
222
263
  function indent(str, spaces) {
223
264
  const pad = " ".repeat(spaces);
@@ -1,3 +1,4 @@
1
+ import { type Token } from "marked";
1
2
  /**
2
3
  * Shared code block renderer used by all markdown rendering.
3
4
  * Outputs the prose-code-block wrapper with copy button and Shiki highlighting.
@@ -9,6 +10,11 @@ export interface PageHeading {
9
10
  text: string;
10
11
  id: string;
11
12
  }
13
+ /**
14
+ * Lex markdown into tokens using the shared Sourcey Marked instance.
15
+ * This keeps directive support and heading parsing aligned with rendering.
16
+ */
17
+ export declare function lexMarkdown(input?: string): Token[];
12
18
  /**
13
19
  * Extract h2/h3 headings from a markdown string by lexing the token tree.
14
20
  * No rendering needed; pure token walk.
@@ -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;AAgJD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGzD;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"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAC;AAKzD;;;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,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CAGnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGzD;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"}
@@ -137,12 +137,21 @@ const marked = new Marked(videoExtension, iframeExtension, {
137
137
  },
138
138
  },
139
139
  });
140
+ /**
141
+ * Lex markdown into tokens using the shared Sourcey Marked instance.
142
+ * This keeps directive support and heading parsing aligned with rendering.
143
+ */
144
+ export function lexMarkdown(input) {
145
+ if (!input)
146
+ return [];
147
+ return marked.lexer(input);
148
+ }
140
149
  /**
141
150
  * Extract h2/h3 headings from a markdown string by lexing the token tree.
142
151
  * No rendering needed; pure token walk.
143
152
  */
144
153
  export function extractHeadings(input) {
145
- const tokens = marked.lexer(input);
154
+ const tokens = lexMarkdown(input);
146
155
  const headings = [];
147
156
  for (const token of tokens) {
148
157
  if (token.type === "heading") {
@@ -164,7 +173,7 @@ export function extractHeadings(input) {
164
173
  export function extractFirstParagraph(input) {
165
174
  if (!input)
166
175
  return "";
167
- const tokens = marked.lexer(input);
176
+ const tokens = lexMarkdown(input);
168
177
  for (const token of tokens) {
169
178
  if (token.type === "paragraph") {
170
179
  const raw = token.raw.trim();
@@ -2,6 +2,8 @@ import type { Plugin } from "vite";
2
2
  export interface SourceyPluginOptions {
3
3
  /** Additional file paths to watch (specs, markdown) */
4
4
  watchPaths: string[];
5
+ /** Current public base URL, used for dev routes under subpaths. */
6
+ baseUrl?: () => string;
5
7
  /** SSR render function: given a URL path, return HTML or null */
6
8
  render: (url: string) => Promise<string | null>;
7
9
  /** Optional: generate search index JSON on demand */
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAIlD,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iEAAiE;IACjE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAyGnE"}
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAKlD,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IACvB,iEAAiE;IACjE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CA4GnE"}
@@ -1,11 +1,12 @@
1
1
  import { resolve, extname } from "node:path";
2
+ import { normalizeBaseUrl } from "./site-url.js";
2
3
  /**
3
4
  * Vite plugin for Sourcey.
4
5
  * - Injects SSR middleware that renders pages on the fly
5
6
  * - Watches spec and markdown files; triggers full reload on change
6
7
  */
7
8
  export function sourceyPlugin(options) {
8
- const { watchPaths, render, searchIndex } = options;
9
+ const { watchPaths, baseUrl, render, searchIndex } = options;
9
10
  const watchSet = new Set(watchPaths.map((p) => resolve(p)));
10
11
  return {
11
12
  name: "sourcey",
@@ -37,6 +38,9 @@ export function sourceyPlugin(options) {
37
38
  // This runs BEFORE Vite's static file handler
38
39
  server.middlewares.use(async (req, res, next) => {
39
40
  const url = req.url ?? "/";
41
+ const pathname = url.split("?", 1)[0] ?? "/";
42
+ const currentBaseUrl = normalizeBaseUrl(baseUrl?.());
43
+ const baseSearchPath = currentBaseUrl ? `${currentBaseUrl}search-index.json` : "/search-index.json";
40
44
  // Let Vite handle its own requests
41
45
  if (url.startsWith("/@") ||
42
46
  url.startsWith("/__vite") ||
@@ -45,7 +49,7 @@ export function sourceyPlugin(options) {
45
49
  return next();
46
50
  }
47
51
  // Serve search index on demand
48
- if (url === "/search-index.json" && searchIndex) {
52
+ if (searchIndex && (pathname === "/search-index.json" || pathname === baseSearchPath)) {
49
53
  try {
50
54
  const json = await searchIndex();
51
55
  res.writeHead(200, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sourcey",
3
- "version": "3.4.11",
3
+ "version": "3.5.0",
4
4
  "description": "Precision documentation from OpenAPI, MCP, Doxygen, and Markdown. Static HTML you own.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -20,7 +20,7 @@
20
20
  "LICENSE"
21
21
  ],
22
22
  "scripts": {
23
- "build": "tsc && cp -r src/themes dist/ && cp src/client/*.js dist/client/",
23
+ "build": "tsc && cp -r src/themes dist/ && cp src/client/*.js dist/client/ && cp -r src/og/fonts dist/og/",
24
24
  "watch": "npm run build && tsc --watch --preserveWatchOutput",
25
25
  "test": "vitest run",
26
26
  "test:watch": "vitest",
@@ -31,8 +31,10 @@
31
31
  "prepublishOnly": "npm run build"
32
32
  },
33
33
  "dependencies": {
34
+ "@apidevtools/json-schema-ref-parser": "^13.0.5",
34
35
  "@preact/preset-vite": "^2.10.4",
35
36
  "@readme/openapi-parser": "^4.0.0",
37
+ "@resvg/resvg-js": "^2.6.2",
36
38
  "@tailwindcss/typography": "^0.5.19",
37
39
  "@tailwindcss/vite": "^4.2.2",
38
40
  "citty": "^0.1.6",
@@ -44,10 +46,11 @@
44
46
  "moxygen": "^2.1.1",
45
47
  "preact": "^10.28.4",
46
48
  "preact-render-to-string": "^6.6.6",
49
+ "satori": "^0.26.0",
47
50
  "shiki": "^4.0.2",
48
51
  "swagger2openapi": "^7.0.8",
49
52
  "tailwindcss": "^4.2.2",
50
- "vite": "^8.0.1"
53
+ "vite": "^8.0.9"
51
54
  },
52
55
  "devDependencies": {
53
56
  "@types/js-yaml": "^4.0.9",