@btst/stack 1.6.0 → 1.8.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 (85) hide show
  1. package/dist/api/index.cjs +7 -1
  2. package/dist/api/index.d.cts +2 -2
  3. package/dist/api/index.d.mts +2 -2
  4. package/dist/api/index.d.ts +2 -2
  5. package/dist/api/index.mjs +7 -1
  6. package/dist/client/index.cjs +6 -2
  7. package/dist/client/index.d.cts +2 -1
  8. package/dist/client/index.d.mts +2 -1
  9. package/dist/client/index.d.ts +2 -1
  10. package/dist/client/index.mjs +6 -2
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.mts +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/packages/better-stack/src/plugins/open-api/api/generator.cjs +300 -0
  15. package/dist/packages/better-stack/src/plugins/open-api/api/generator.mjs +284 -0
  16. package/dist/packages/better-stack/src/plugins/open-api/api/plugin.cjs +115 -0
  17. package/dist/packages/better-stack/src/plugins/open-api/api/plugin.mjs +113 -0
  18. package/dist/packages/better-stack/src/plugins/open-api/db.cjs +7 -0
  19. package/dist/packages/better-stack/src/plugins/open-api/db.mjs +5 -0
  20. package/dist/packages/better-stack/src/plugins/open-api/logo.cjs +8 -0
  21. package/dist/packages/better-stack/src/plugins/open-api/logo.mjs +6 -0
  22. package/dist/packages/better-stack/src/plugins/route-docs/client/components/loading/docs-skeleton.cjs +43 -0
  23. package/dist/packages/better-stack/src/plugins/route-docs/client/components/loading/docs-skeleton.mjs +41 -0
  24. package/dist/packages/better-stack/src/plugins/route-docs/client/components/pages/docs-page.cjs +794 -0
  25. package/dist/packages/better-stack/src/plugins/route-docs/client/components/pages/docs-page.mjs +788 -0
  26. package/dist/packages/better-stack/src/plugins/route-docs/client/plugin.cjs +111 -0
  27. package/dist/packages/better-stack/src/plugins/route-docs/client/plugin.mjs +106 -0
  28. package/dist/packages/better-stack/src/plugins/route-docs/generator.cjs +244 -0
  29. package/dist/packages/better-stack/src/plugins/route-docs/generator.mjs +227 -0
  30. package/dist/packages/ui/src/components/sheet.cjs +25 -0
  31. package/dist/packages/ui/src/components/sheet.mjs +24 -1
  32. package/dist/plugins/api/index.d.cts +2 -2
  33. package/dist/plugins/api/index.d.mts +2 -2
  34. package/dist/plugins/api/index.d.ts +2 -2
  35. package/dist/plugins/blog/api/index.d.cts +1 -1
  36. package/dist/plugins/blog/api/index.d.mts +1 -1
  37. package/dist/plugins/blog/api/index.d.ts +1 -1
  38. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  39. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  40. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  41. package/dist/plugins/blog/client/index.d.cts +1 -1
  42. package/dist/plugins/blog/client/index.d.mts +1 -1
  43. package/dist/plugins/blog/client/index.d.ts +1 -1
  44. package/dist/plugins/blog/query-keys.d.cts +2 -2
  45. package/dist/plugins/blog/query-keys.d.mts +2 -2
  46. package/dist/plugins/blog/query-keys.d.ts +2 -2
  47. package/dist/plugins/client/index.d.cts +2 -2
  48. package/dist/plugins/client/index.d.mts +2 -2
  49. package/dist/plugins/client/index.d.ts +2 -2
  50. package/dist/plugins/open-api/api/index.cjs +9 -0
  51. package/dist/plugins/open-api/api/index.d.cts +95 -0
  52. package/dist/plugins/open-api/api/index.d.mts +95 -0
  53. package/dist/plugins/open-api/api/index.d.ts +95 -0
  54. package/dist/plugins/open-api/api/index.mjs +2 -0
  55. package/dist/plugins/route-docs/client/index.cjs +10 -0
  56. package/dist/plugins/route-docs/client/index.d.cts +126 -0
  57. package/dist/plugins/route-docs/client/index.d.mts +126 -0
  58. package/dist/plugins/route-docs/client/index.d.ts +126 -0
  59. package/dist/plugins/route-docs/client/index.mjs +1 -0
  60. package/dist/plugins/route-docs/client.css +3 -0
  61. package/dist/plugins/route-docs/style.css +19 -0
  62. package/dist/shared/{stack.ByOugz9d.d.cts → stack.u9iYV6vt.d.cts} +28 -3
  63. package/dist/shared/{stack.ByOugz9d.d.mts → stack.u9iYV6vt.d.mts} +28 -3
  64. package/dist/shared/{stack.ByOugz9d.d.ts → stack.u9iYV6vt.d.ts} +28 -3
  65. package/package.json +28 -1
  66. package/src/api/index.ts +14 -2
  67. package/src/client/index.ts +11 -4
  68. package/src/plugins/open-api/api/generator.ts +433 -0
  69. package/src/plugins/open-api/api/index.ts +8 -0
  70. package/src/plugins/open-api/api/plugin.ts +243 -0
  71. package/src/plugins/open-api/db.ts +7 -0
  72. package/src/plugins/open-api/logo.ts +7 -0
  73. package/src/plugins/route-docs/client/components/loading/docs-skeleton.tsx +82 -0
  74. package/src/plugins/route-docs/client/components/loading/index.tsx +1 -0
  75. package/src/plugins/route-docs/client/components/pages/docs-page.tsx +1240 -0
  76. package/src/plugins/route-docs/client/index.ts +7 -0
  77. package/src/plugins/route-docs/client/plugin.tsx +187 -0
  78. package/src/plugins/route-docs/client.css +3 -0
  79. package/src/plugins/route-docs/generator.ts +385 -0
  80. package/src/plugins/route-docs/index.ts +12 -0
  81. package/src/plugins/route-docs/style.css +19 -0
  82. package/src/types.ts +34 -2
  83. package/dist/shared/{stack.CcI4sYJP.d.mts → stack.DLhzx1-D.d.cts} +1 -1
  84. package/dist/shared/{stack.CcI4sYJP.d.ts → stack.DLhzx1-D.d.mts} +1 -1
  85. package/dist/shared/{stack.CcI4sYJP.d.cts → stack.DLhzx1-D.d.ts} +1 -1
@@ -0,0 +1,794 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const card = require('../../../../../../../ui/src/components/card.cjs');
7
+ const badge = require('../../../../../../../ui/src/components/badge.cjs');
8
+ const scrollArea = require('../../../../../../../ui/src/components/scroll-area.cjs');
9
+ const separator = require('../../../../../../../ui/src/components/separator.cjs');
10
+ const table = require('../../../../../../../ui/src/components/table.cjs');
11
+ const button = require('../../../../../../../ui/src/components/button.cjs');
12
+ const input = require('../../../../../../../ui/src/components/input.cjs');
13
+ const label = require('../../../../../../../ui/src/components/label.cjs');
14
+ const sheet = require('../../../../../../../ui/src/components/sheet.cjs');
15
+ const lucideReact = require('lucide-react');
16
+ const reactQuery = require('@tanstack/react-query');
17
+ const plugin = require('../../plugin.cjs');
18
+
19
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
20
+
21
+ const React__default = /*#__PURE__*/_interopDefaultCompat(React);
22
+
23
+ function escapeRegexForRoutePath(path) {
24
+ const PARAM_PLACEHOLDER = "\0PARAM\0";
25
+ const WILDCARD_PLACEHOLDER = "\0WILDCARD\0";
26
+ let result = path.replace(/:[^/]+/g, PARAM_PLACEHOLDER).replace(/\*/g, WILDCARD_PLACEHOLDER);
27
+ result = result.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
28
+ result = result.replace(new RegExp(PARAM_PLACEHOLDER, "g"), "[^/]+").replace(new RegExp(WILDCARD_PLACEHOLDER, "g"), ".*");
29
+ return result;
30
+ }
31
+ function HighlightedPath({ path }) {
32
+ const parts = path.split("/");
33
+ return /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xl break-all", children: parts.map((part, i) => {
34
+ const isParam = part.startsWith(":") || part.startsWith("*");
35
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__default.Fragment, { children: [
36
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "/" }),
37
+ isParam ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary font-semibold", children: part }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground", children: part })
38
+ ] }, i);
39
+ }) });
40
+ }
41
+ function ParameterCard({ param }) {
42
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4 space-y-2", children: [
43
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
44
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-sm text-primary font-semibold", children: param.name }),
45
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
46
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "font-mono text-xs", children: param.type }),
47
+ /* @__PURE__ */ jsxRuntime.jsx(
48
+ badge.Badge,
49
+ {
50
+ variant: param.required ? "destructive" : "outline",
51
+ className: "text-xs",
52
+ children: param.required ? "required" : "optional"
53
+ }
54
+ )
55
+ ] })
56
+ ] }),
57
+ param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: param.description }),
58
+ param.schema?.enum && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
59
+ "Values: ",
60
+ param.schema.enum.join(" | ")
61
+ ] })
62
+ ] });
63
+ }
64
+ function ParametersSection({
65
+ params,
66
+ title
67
+ }) {
68
+ if (params.length === 0) return null;
69
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
70
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wide", children: title }),
71
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block rounded-lg border overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
72
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
73
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[150px]", children: "Name" }),
74
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[120px]", children: "Type" }),
75
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[100px]", children: "Required" }),
76
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: "Description" })
77
+ ] }) }),
78
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: params.map((param) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
79
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-sm text-primary", children: param.name }) }),
80
+ /* @__PURE__ */ jsxRuntime.jsxs(table.TableCell, { children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "font-mono text-xs", children: param.type }),
82
+ param.schema?.enum && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: [
83
+ "(",
84
+ param.schema.enum.join(" | "),
85
+ ")"
86
+ ] })
87
+ ] }),
88
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(
89
+ badge.Badge,
90
+ {
91
+ variant: param.required ? "destructive" : "outline",
92
+ className: "text-xs",
93
+ children: param.required ? "required" : "optional"
94
+ }
95
+ ) }),
96
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "text-muted-foreground", children: param.description || "\u2014" })
97
+ ] }, param.name)) })
98
+ ] }) }),
99
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden space-y-3", children: params.map((param) => /* @__PURE__ */ jsxRuntime.jsx(ParameterCard, { param }, param.name)) })
100
+ ] });
101
+ }
102
+ function NavigationForm({
103
+ route,
104
+ siteBasePath
105
+ }) {
106
+ const [paramValues, setParamValues] = React.useState({});
107
+ const handleParamChange = (name, value) => {
108
+ setParamValues((prev) => ({ ...prev, [name]: value }));
109
+ };
110
+ const buildUrl = () => {
111
+ let url = route.path;
112
+ for (const param of route.pathParams) {
113
+ const value = paramValues[param.name] || `{${param.name}}`;
114
+ if (param.name === "_") {
115
+ url = url.replace("*", value);
116
+ } else if (url.includes(`*:${param.name}`)) {
117
+ url = url.replace(`*:${param.name}`, value);
118
+ } else {
119
+ url = url.replace(`:${param.name}`, value);
120
+ }
121
+ }
122
+ return `${siteBasePath}${url}`;
123
+ };
124
+ const handleVisit = () => {
125
+ const url = buildUrl();
126
+ const hasUnfilledParams = route.pathParams.some(
127
+ (p) => !paramValues[p.name]
128
+ );
129
+ if (hasUnfilledParams) {
130
+ return;
131
+ }
132
+ window.open(url, "_blank");
133
+ };
134
+ const allParamsFilled = route.pathParams.every((p) => paramValues[p.name]);
135
+ const previewUrl = buildUrl();
136
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { children: [
137
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "text-base flex items-center gap-2", children: [
138
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Navigation, { className: "h-4 w-4" }),
139
+ "Navigate to Route"
140
+ ] }) }),
141
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: "space-y-4", children: route.pathParams.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
142
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-4 grid-cols-1 sm:grid-cols-2", children: route.pathParams.map((param) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
143
+ /* @__PURE__ */ jsxRuntime.jsxs(label.Label, { htmlFor: `param-${param.name}`, className: "font-mono", children: [
144
+ ":",
145
+ param.name
146
+ ] }),
147
+ /* @__PURE__ */ jsxRuntime.jsx(
148
+ input.Input,
149
+ {
150
+ id: `param-${param.name}`,
151
+ placeholder: `Enter ${param.name}...`,
152
+ value: paramValues[param.name] || "",
153
+ onChange: (e) => handleParamChange(param.name, e.target.value)
154
+ }
155
+ )
156
+ ] }, param.name)) }),
157
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-center gap-3 pt-2", children: [
158
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "flex-1 text-xs bg-muted px-3 py-2 rounded-md font-mono text-muted-foreground break-all", children: previewUrl }),
159
+ /* @__PURE__ */ jsxRuntime.jsxs(
160
+ button.Button,
161
+ {
162
+ onClick: handleVisit,
163
+ disabled: !allParamsFilled,
164
+ className: "shrink-0",
165
+ children: [
166
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
167
+ "Visit"
168
+ ]
169
+ }
170
+ )
171
+ ] })
172
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-center gap-3", children: [
173
+ /* @__PURE__ */ jsxRuntime.jsxs("code", { className: "flex-1 text-sm bg-muted px-3 py-2 rounded-md font-mono break-all", children: [
174
+ siteBasePath,
175
+ route.path
176
+ ] }),
177
+ /* @__PURE__ */ jsxRuntime.jsxs(
178
+ button.Button,
179
+ {
180
+ onClick: () => window.open(`${siteBasePath}${route.path}`, "_blank"),
181
+ className: "shrink-0",
182
+ children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4 mr-2" }),
184
+ "Visit"
185
+ ]
186
+ }
187
+ )
188
+ ] }) })
189
+ ] });
190
+ }
191
+ function getMatchingSitemapEntries(route, sitemapEntries) {
192
+ const hasParams = route.pathParams.length > 0;
193
+ if (!hasParams) {
194
+ return sitemapEntries.filter((e) => {
195
+ try {
196
+ const url = new URL(e.url);
197
+ return url.pathname.endsWith(route.path);
198
+ } catch {
199
+ return false;
200
+ }
201
+ });
202
+ } else {
203
+ const routePattern = escapeRegexForRoutePath(route.path);
204
+ const regex = new RegExp(`${routePattern}$`);
205
+ return sitemapEntries.filter((e) => {
206
+ try {
207
+ const url = new URL(e.url);
208
+ return regex.test(url.pathname);
209
+ } catch {
210
+ return false;
211
+ }
212
+ });
213
+ }
214
+ }
215
+ function RouteSitemapSection({
216
+ route,
217
+ sitemapEntries
218
+ }) {
219
+ const matchingEntries = React.useMemo(
220
+ () => getMatchingSitemapEntries(route, sitemapEntries),
221
+ [route, sitemapEntries]
222
+ );
223
+ if (matchingEntries.length === 0) return null;
224
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { children: [
225
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "text-base flex items-center gap-2", children: [
226
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-4 w-4" }),
227
+ "Sitemap Entries",
228
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "ml-1", children: matchingEntries.length })
229
+ ] }) }),
230
+ /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { children: [
231
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block rounded-lg border overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
232
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
233
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: "URL" }),
234
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[120px]", children: "Last Modified" }),
235
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Priority" }),
236
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Actions" })
237
+ ] }) }),
238
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: matchingEntries.map((entry, idx) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
239
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(
240
+ "a",
241
+ {
242
+ href: entry.url,
243
+ target: "_blank",
244
+ rel: "noopener noreferrer",
245
+ className: "hover:underline",
246
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs text-primary truncate block max-w-[400px]", children: entry.url })
247
+ }
248
+ ) }),
249
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "text-xs text-muted-foreground", children: formatDate(entry.lastModified) }),
250
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "text-xs text-muted-foreground", children: entry.priority !== void 0 ? entry.priority : "\u2014" }),
251
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(
252
+ button.Button,
253
+ {
254
+ variant: "ghost",
255
+ size: "sm",
256
+ className: "h-7 px-2",
257
+ onClick: () => window.open(entry.url, "_blank"),
258
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
259
+ }
260
+ ) })
261
+ ] }, idx)) })
262
+ ] }) }),
263
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden space-y-3", children: matchingEntries.map((entry, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-3 space-y-2", children: [
264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(
266
+ "a",
267
+ {
268
+ href: entry.url,
269
+ target: "_blank",
270
+ rel: "noopener noreferrer",
271
+ className: "font-mono text-xs text-primary break-all hover:underline",
272
+ children: entry.url
273
+ }
274
+ ),
275
+ /* @__PURE__ */ jsxRuntime.jsx(
276
+ button.Button,
277
+ {
278
+ variant: "ghost",
279
+ size: "sm",
280
+ className: "h-7 w-7 p-0 shrink-0",
281
+ onClick: () => window.open(entry.url, "_blank"),
282
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
283
+ }
284
+ )
285
+ ] }),
286
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-muted-foreground", children: [
287
+ entry.lastModified && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate(entry.lastModified) }),
288
+ entry.priority !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
289
+ "Priority: ",
290
+ entry.priority
291
+ ] })
292
+ ] })
293
+ ] }, idx)) })
294
+ ] })
295
+ ] });
296
+ }
297
+ function RouteDetail({
298
+ route,
299
+ pluginName,
300
+ sitemapEntries,
301
+ siteBasePath
302
+ }) {
303
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
304
+ route.meta && (route.meta.title || route.meta.description) && /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { children: [
305
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "pb-3", children: route.meta.title && /* @__PURE__ */ jsxRuntime.jsx(card.CardTitle, { className: "text-lg sm:text-xl", children: route.meta.title }) }),
306
+ (route.meta.description || route.meta.tags && route.meta.tags.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { className: "space-y-3", children: [
307
+ route.meta.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm sm:text-base", children: route.meta.description }),
308
+ route.meta.tags && route.meta.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: route.meta.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", children: tag }, tag)) })
309
+ ] })
310
+ ] }),
311
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center gap-3 flex-wrap", children: [
312
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedPath, { path: route.path }) }),
313
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "outline", children: pluginName })
314
+ ] }),
315
+ /* @__PURE__ */ jsxRuntime.jsx(NavigationForm, { route, siteBasePath }),
316
+ /* @__PURE__ */ jsxRuntime.jsx(ParametersSection, { params: route.pathParams, title: "Path Parameters" }),
317
+ /* @__PURE__ */ jsxRuntime.jsx(ParametersSection, { params: route.queryParams, title: "Query Parameters" }),
318
+ /* @__PURE__ */ jsxRuntime.jsx(RouteSitemapSection, { route, sitemapEntries })
319
+ ] });
320
+ }
321
+ function getRouteAnchorId(pluginKey, routeKey) {
322
+ return `route-${pluginKey}-${routeKey}`;
323
+ }
324
+ function SidebarRouteItem({
325
+ route,
326
+ pluginKey,
327
+ onNavigate
328
+ }) {
329
+ const anchorId = getRouteAnchorId(pluginKey, route.key);
330
+ const handleClick = (e) => {
331
+ e.preventDefault();
332
+ const element = document.getElementById(anchorId);
333
+ if (element) {
334
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
335
+ window.history.pushState(null, "", `#${anchorId}`);
336
+ }
337
+ onNavigate?.();
338
+ };
339
+ return /* @__PURE__ */ jsxRuntime.jsxs(
340
+ "a",
341
+ {
342
+ href: `#${anchorId}`,
343
+ onClick: handleClick,
344
+ className: "flex items-center w-full justify-start font-mono text-xs h-auto py-2 px-3 rounded-md hover:bg-accent hover:text-accent-foreground transition-colors",
345
+ children: [
346
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "mr-2 h-3 w-3 shrink-0" }),
347
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: route.path })
348
+ ]
349
+ }
350
+ );
351
+ }
352
+ function SidebarPluginGroup({
353
+ plugin,
354
+ onNavigate
355
+ }) {
356
+ const [isExpanded, setIsExpanded] = React.useState(true);
357
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
358
+ /* @__PURE__ */ jsxRuntime.jsxs(
359
+ button.Button,
360
+ {
361
+ variant: "ghost",
362
+ size: "sm",
363
+ className: "w-full justify-between font-medium h-auto py-2",
364
+ onClick: () => setIsExpanded(!isExpanded),
365
+ children: [
366
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center", children: [
367
+ isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderOpen, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Folder, { className: "mr-2 h-4 w-4" }),
368
+ plugin.name
369
+ ] }),
370
+ /* @__PURE__ */ jsxRuntime.jsx(
371
+ lucideReact.ChevronRight,
372
+ {
373
+ className: `h-4 w-4 transition-transform ${isExpanded ? "rotate-90" : ""}`
374
+ }
375
+ )
376
+ ]
377
+ }
378
+ ),
379
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-2 space-y-0.5", children: plugin.routes.map((route) => /* @__PURE__ */ jsxRuntime.jsx(
380
+ SidebarRouteItem,
381
+ {
382
+ route,
383
+ pluginKey: plugin.key,
384
+ onNavigate
385
+ },
386
+ route.key
387
+ )) })
388
+ ] });
389
+ }
390
+ function SidebarContent({
391
+ schema,
392
+ onNavigate
393
+ }) {
394
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 space-y-4", children: schema.plugins.map((plugin) => /* @__PURE__ */ jsxRuntime.jsx(
395
+ SidebarPluginGroup,
396
+ {
397
+ plugin,
398
+ onNavigate
399
+ },
400
+ plugin.key
401
+ )) });
402
+ }
403
+ function RouteCard({
404
+ pluginName,
405
+ route,
406
+ hasParams,
407
+ staticUrl,
408
+ sitemapCount = 0,
409
+ onSelect
410
+ }) {
411
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-4 space-y-3", children: [
412
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
413
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onSelect, className: "text-left hover:underline", children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-sm text-primary break-all", children: route.path }) }),
414
+ staticUrl ? /* @__PURE__ */ jsxRuntime.jsx(
415
+ button.Button,
416
+ {
417
+ variant: "ghost",
418
+ size: "sm",
419
+ className: "h-8 w-8 p-0 shrink-0",
420
+ onClick: () => window.open(staticUrl, "_blank"),
421
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" })
422
+ }
423
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
424
+ button.Button,
425
+ {
426
+ variant: "ghost",
427
+ size: "sm",
428
+ className: "h-8 w-8 p-0 shrink-0",
429
+ onClick: onSelect,
430
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Navigation, { className: "h-4 w-4" })
431
+ }
432
+ )
433
+ ] }),
434
+ route.meta?.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: route.meta.title }),
435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
436
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "outline", className: "text-xs", children: pluginName }),
437
+ hasParams && /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", className: "text-xs", children: [
438
+ route.pathParams.length,
439
+ " param",
440
+ route.pathParams.length > 1 ? "s" : ""
441
+ ] }),
442
+ sitemapCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", className: "text-xs", children: [
443
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3 w-3 mr-1" }),
444
+ sitemapCount,
445
+ " in sitemap"
446
+ ] })
447
+ ] })
448
+ ] });
449
+ }
450
+ function formatDate(date) {
451
+ if (!date) return "\u2014";
452
+ const d = typeof date === "string" ? new Date(date) : date;
453
+ return d.toLocaleDateString(void 0, {
454
+ year: "numeric",
455
+ month: "short",
456
+ day: "numeric"
457
+ });
458
+ }
459
+ function SitemapSection({
460
+ entries,
461
+ schema
462
+ }) {
463
+ const [isExpanded, setIsExpanded] = React.useState(false);
464
+ const getPluginName = (pluginKey) => {
465
+ const plugin = schema.plugins.find((p) => p.key === pluginKey);
466
+ return plugin?.name || pluginKey;
467
+ };
468
+ if (entries.length === 0) return null;
469
+ const displayedEntries = isExpanded ? entries : entries.slice(0, 10);
470
+ const hasMore = entries.length > 10;
471
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { children: [
472
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "pb-3 sm:pb-6", children: /* @__PURE__ */ jsxRuntime.jsxs(card.CardTitle, { className: "text-lg flex items-center gap-2", children: [
473
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-5 w-5" }),
474
+ "Sitemap Entries",
475
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "ml-2", children: entries.length })
476
+ ] }) }),
477
+ /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { children: [
478
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block rounded-lg border overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
479
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
480
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: "URL" }),
481
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[100px]", children: "Plugin" }),
482
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[120px]", children: "Last Modified" }),
483
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Actions" })
484
+ ] }) }),
485
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: displayedEntries.map((entry, idx) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
486
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(
487
+ "a",
488
+ {
489
+ href: entry.url,
490
+ target: "_blank",
491
+ rel: "noopener noreferrer",
492
+ className: "hover:underline",
493
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs text-primary truncate block max-w-[400px]", children: entry.url })
494
+ }
495
+ ) }),
496
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "outline", className: "text-xs", children: getPluginName(entry.pluginKey) }) }),
497
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "text-xs text-muted-foreground", children: formatDate(entry.lastModified) }),
498
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(
499
+ button.Button,
500
+ {
501
+ variant: "ghost",
502
+ size: "sm",
503
+ className: "h-7 px-2",
504
+ onClick: () => window.open(entry.url, "_blank"),
505
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
506
+ }
507
+ ) })
508
+ ] }, `${entry.pluginKey}-${idx}`)) })
509
+ ] }) }),
510
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden space-y-3", children: displayedEntries.map((entry, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border p-3 space-y-2", children: [
511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
512
+ /* @__PURE__ */ jsxRuntime.jsx(
513
+ "a",
514
+ {
515
+ href: entry.url,
516
+ target: "_blank",
517
+ rel: "noopener noreferrer",
518
+ className: "font-mono text-xs text-primary break-all hover:underline",
519
+ children: entry.url
520
+ }
521
+ ),
522
+ /* @__PURE__ */ jsxRuntime.jsx(
523
+ button.Button,
524
+ {
525
+ variant: "ghost",
526
+ size: "sm",
527
+ className: "h-7 w-7 p-0 shrink-0",
528
+ onClick: () => window.open(entry.url, "_blank"),
529
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
530
+ }
531
+ )
532
+ ] }),
533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-muted-foreground", children: [
534
+ /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "outline", className: "text-xs", children: getPluginName(entry.pluginKey) }),
535
+ entry.lastModified && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate(entry.lastModified) })
536
+ ] })
537
+ ] }, idx)) }),
538
+ hasMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(
539
+ button.Button,
540
+ {
541
+ variant: "outline",
542
+ size: "sm",
543
+ onClick: () => setIsExpanded(!isExpanded),
544
+ children: isExpanded ? "Show less" : `Show all ${entries.length} entries`
545
+ }
546
+ ) })
547
+ ] })
548
+ ] });
549
+ }
550
+ function AllRoutesSection({
551
+ schema,
552
+ siteBasePath
553
+ }) {
554
+ const scrollToRoute = (pluginKey, routeKey) => {
555
+ const anchorId = getRouteAnchorId(pluginKey, routeKey);
556
+ const element = document.getElementById(anchorId);
557
+ if (element) {
558
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
559
+ window.history.pushState(null, "", `#${anchorId}`);
560
+ }
561
+ };
562
+ const allRoutes = React.useMemo(() => {
563
+ const routes = [];
564
+ for (const plugin of schema.plugins) {
565
+ for (const route of plugin.routes) {
566
+ const hasParams = route.pathParams.length > 0;
567
+ let sitemapCount = 0;
568
+ if (!hasParams) {
569
+ sitemapCount = plugin.sitemapEntries.filter((e) => {
570
+ try {
571
+ const url = new URL(e.url);
572
+ return url.pathname.endsWith(route.path);
573
+ } catch {
574
+ return false;
575
+ }
576
+ }).length;
577
+ } else {
578
+ const routePattern = escapeRegexForRoutePath(route.path);
579
+ const regex = new RegExp(`${routePattern}$`);
580
+ sitemapCount = plugin.sitemapEntries.filter((e) => {
581
+ try {
582
+ const url = new URL(e.url);
583
+ return regex.test(url.pathname);
584
+ } catch {
585
+ return false;
586
+ }
587
+ }).length;
588
+ }
589
+ routes.push({
590
+ pluginKey: plugin.key,
591
+ pluginName: plugin.name,
592
+ route,
593
+ hasParams,
594
+ staticUrl: hasParams ? null : `${siteBasePath}${route.path}`,
595
+ sitemapCount
596
+ });
597
+ }
598
+ }
599
+ return routes;
600
+ }, [schema, siteBasePath]);
601
+ if (allRoutes.length === 0) return null;
602
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { children: [
603
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "pb-3 sm:pb-6", children: /* @__PURE__ */ jsxRuntime.jsx(card.CardTitle, { className: "text-lg", children: "All Routes" }) }),
604
+ /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { children: [
605
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block rounded-lg border overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
606
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
607
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: "Route" }),
608
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[100px]", children: "Plugin" }),
609
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Params" }),
610
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Sitemap" }),
611
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[80px]", children: "Actions" })
612
+ ] }) }),
613
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: allRoutes.map(
614
+ ({
615
+ pluginKey,
616
+ pluginName,
617
+ route,
618
+ hasParams,
619
+ staticUrl,
620
+ sitemapCount
621
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
622
+ /* @__PURE__ */ jsxRuntime.jsxs(table.TableCell, { children: [
623
+ /* @__PURE__ */ jsxRuntime.jsx(
624
+ "button",
625
+ {
626
+ onClick: () => scrollToRoute(pluginKey, route.key),
627
+ className: "text-left hover:underline",
628
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-sm text-primary", children: route.path })
629
+ }
630
+ ),
631
+ route.meta?.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: route.meta.title })
632
+ ] }),
633
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "outline", className: "text-xs", children: pluginName }) }),
634
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: hasParams ? /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: route.pathParams.length }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) }),
635
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: sitemapCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", className: "text-xs", children: [
636
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3 w-3 mr-1" }),
637
+ sitemapCount
638
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) }),
639
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: staticUrl ? /* @__PURE__ */ jsxRuntime.jsx(
640
+ button.Button,
641
+ {
642
+ variant: "ghost",
643
+ size: "sm",
644
+ className: "h-7 px-2",
645
+ onClick: () => window.open(staticUrl, "_blank"),
646
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
647
+ }
648
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
649
+ button.Button,
650
+ {
651
+ variant: "ghost",
652
+ size: "sm",
653
+ className: "h-7 px-2",
654
+ onClick: () => scrollToRoute(pluginKey, route.key),
655
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Navigation, { className: "h-3 w-3" })
656
+ }
657
+ ) })
658
+ ] }, `${pluginKey}-${route.key}`)
659
+ ) })
660
+ ] }) }),
661
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden space-y-3", children: allRoutes.map(
662
+ ({
663
+ pluginKey,
664
+ pluginName,
665
+ route,
666
+ hasParams,
667
+ staticUrl,
668
+ sitemapCount
669
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
670
+ RouteCard,
671
+ {
672
+ pluginName,
673
+ route,
674
+ hasParams,
675
+ staticUrl,
676
+ sitemapCount,
677
+ onSelect: () => scrollToRoute(pluginKey, route.key)
678
+ },
679
+ `${pluginKey}-${route.key}`
680
+ )
681
+ ) })
682
+ ] })
683
+ ] });
684
+ }
685
+ function DocsPageComponent({
686
+ title = "Route Documentation",
687
+ description = "Documentation for all client routes in your application",
688
+ siteBasePath = "/pages"
689
+ }) {
690
+ const { data: schema } = reactQuery.useSuspenseQuery({
691
+ queryKey: plugin.ROUTE_DOCS_QUERY_KEY,
692
+ queryFn: plugin.generateSchema,
693
+ staleTime: Infinity
694
+ // Don't refetch - schema is static for this session
695
+ });
696
+ const [mobileMenuOpen, setMobileMenuOpen] = React.useState(false);
697
+ const totalRoutes = schema.plugins.reduce(
698
+ (sum, p) => sum + p.routes.length,
699
+ 0
700
+ );
701
+ const handleMobileNavigate = () => {
702
+ setMobileMenuOpen(false);
703
+ };
704
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-screen bg-background", children: [
705
+ /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "hidden md:block w-72 border-r bg-card shrink-0 sticky top-0 h-screen", children: [
706
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 border-b", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-sm text-muted-foreground uppercase tracking-wide", children: "Routes" }) }),
707
+ /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollArea, { className: "h-[calc(100vh-57px)]", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarContent, { schema }) })
708
+ ] }),
709
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden fixed top-0 left-0 right-0 z-40 bg-card border-b", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4", children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-sm text-muted-foreground uppercase tracking-wide", children: "Route Docs" }),
711
+ /* @__PURE__ */ jsxRuntime.jsxs(sheet.Sheet, { open: mobileMenuOpen, onOpenChange: setMobileMenuOpen, children: [
712
+ /* @__PURE__ */ jsxRuntime.jsx(sheet.SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { variant: "outline", size: "sm", children: [
713
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "h-4 w-4 mr-2" }),
714
+ "Routes"
715
+ ] }) }),
716
+ /* @__PURE__ */ jsxRuntime.jsxs(sheet.SheetContent, { side: "left", className: "w-80 p-0", children: [
717
+ /* @__PURE__ */ jsxRuntime.jsx(sheet.SheetHeader, { className: "p-4 border-b", children: /* @__PURE__ */ jsxRuntime.jsx(sheet.SheetTitle, { className: "text-left text-sm text-muted-foreground uppercase tracking-wide", children: "Routes" }) }),
718
+ /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollArea, { className: "h-[calc(100vh-57px)]", children: /* @__PURE__ */ jsxRuntime.jsx(
719
+ SidebarContent,
720
+ {
721
+ schema,
722
+ onNavigate: handleMobileNavigate
723
+ }
724
+ ) })
725
+ ] })
726
+ ] })
727
+ ] }) }),
728
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-auto pt-16 md:pt-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto p-4 sm:p-6 lg:p-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 sm:space-y-8", children: [
729
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
730
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl sm:text-3xl font-bold tracking-tight", children: title }),
731
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-2 text-sm sm:text-base", children: description })
732
+ ] }),
733
+ /* @__PURE__ */ jsxRuntime.jsx(separator.Separator, {}),
734
+ totalRoutes > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
735
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
736
+ /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", children: [
737
+ schema.plugins.length,
738
+ " plugins"
739
+ ] }),
740
+ /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", children: [
741
+ totalRoutes,
742
+ " routes"
743
+ ] }),
744
+ schema.allSitemapEntries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "secondary", children: [
745
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-3 w-3 mr-1" }),
746
+ schema.allSitemapEntries.length,
747
+ " sitemap entries"
748
+ ] })
749
+ ] }),
750
+ /* @__PURE__ */ jsxRuntime.jsx(AllRoutesSection, { schema, siteBasePath }),
751
+ schema.plugins.map((plugin) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
752
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pt-4", children: [
753
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Folder, { className: "h-6 w-6 text-muted-foreground" }),
754
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold", children: plugin.name }),
755
+ /* @__PURE__ */ jsxRuntime.jsxs(badge.Badge, { variant: "outline", children: [
756
+ plugin.routes.length,
757
+ " routes"
758
+ ] })
759
+ ] }),
760
+ plugin.routes.map((route) => /* @__PURE__ */ jsxRuntime.jsx(
761
+ "div",
762
+ {
763
+ id: getRouteAnchorId(plugin.key, route.key),
764
+ className: "scroll-mt-20 md:scroll-mt-4",
765
+ children: /* @__PURE__ */ jsxRuntime.jsx(
766
+ RouteDetail,
767
+ {
768
+ route,
769
+ pluginName: plugin.name,
770
+ sitemapEntries: plugin.sitemapEntries,
771
+ siteBasePath
772
+ }
773
+ )
774
+ },
775
+ route.key
776
+ )),
777
+ /* @__PURE__ */ jsxRuntime.jsx(separator.Separator, {})
778
+ ] }, plugin.key)),
779
+ /* @__PURE__ */ jsxRuntime.jsx(
780
+ SitemapSection,
781
+ {
782
+ entries: schema.allSitemapEntries,
783
+ schema
784
+ }
785
+ )
786
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(card.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(card.CardContent, { className: "py-8 sm:py-12 text-center", children: [
787
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No documented routes found." }),
788
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-2", children: "Add client plugins with routes to see documentation here." })
789
+ ] }) })
790
+ ] }) }) })
791
+ ] });
792
+ }
793
+
794
+ exports.DocsPageComponent = DocsPageComponent;