@clarify-labs/renderer 0.1.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 (50) hide show
  1. package/LICENSE +661 -0
  2. package/output/AppShell-C_bj6ZhV.js +1928 -0
  3. package/output/AppShell-C_bj6ZhV.js.map +1 -0
  4. package/output/AppShell-DBgUlirU.cjs +2127 -0
  5. package/output/AppShell-DBgUlirU.cjs.map +1 -0
  6. package/output/app/AppShell.d.ts +7 -0
  7. package/output/client.cjs +3 -0
  8. package/output/client.d.ts +1 -0
  9. package/output/client.js +2 -0
  10. package/output/components/BuiltWithClarify.d.ts +1 -0
  11. package/output/components/Code.d.ts +18 -0
  12. package/output/components/Feedback.d.ts +1 -0
  13. package/output/components/PageFooter.d.ts +1 -0
  14. package/output/components/SectionProvider.d.ts +25 -0
  15. package/output/components/SiteLogo.d.ts +6 -0
  16. package/output/components/ThemeProvider.d.ts +13 -0
  17. package/output/components/ThemeToggle.d.ts +1 -0
  18. package/output/components/index.d.ts +82 -0
  19. package/output/components/patterns.d.ts +9 -0
  20. package/output/context.d.ts +6 -0
  21. package/output/index.cjs +870 -0
  22. package/output/index.cjs.map +1 -0
  23. package/output/index.d.ts +11 -0
  24. package/output/index.js +850 -0
  25. package/output/index.js.map +1 -0
  26. package/output/mdx/components.d.ts +50 -0
  27. package/output/mdx/primitives.d.ts +42 -0
  28. package/output/openapi/index.d.ts +20 -0
  29. package/output/openapi/utils.d.ts +12 -0
  30. package/output/render-CLI-MnH_.cjs +60 -0
  31. package/output/render-CLI-MnH_.cjs.map +1 -0
  32. package/output/render-Ca4Is683.js +55 -0
  33. package/output/render-Ca4Is683.js.map +1 -0
  34. package/output/renderer.css +3986 -0
  35. package/output/runtime/render.d.ts +2 -0
  36. package/output/runtime/server.d.ts +7 -0
  37. package/output/server.cjs +34 -0
  38. package/output/server.cjs.map +1 -0
  39. package/output/server.d.ts +1 -0
  40. package/output/server.js +33 -0
  41. package/output/server.js.map +1 -0
  42. package/output/shell/ContentActions.d.ts +7 -0
  43. package/output/shell/Header.d.ts +8 -0
  44. package/output/shell/Navigation.d.ts +5 -0
  45. package/output/shell/Search.d.ts +10 -0
  46. package/output/shell/index.d.ts +5 -0
  47. package/output/shell/mobile.d.ts +15 -0
  48. package/output/types.d.ts +121 -0
  49. package/output/utils/remToPx.d.ts +1 -0
  50. package/package.json +71 -0
@@ -0,0 +1,850 @@
1
+ import { C as BuiltWithClarify, E as remToPx, S as Pre, T as useSectionStore, _ as GridPattern, a as Heading, b as Code, c as Tag, d as useTheme, f as PageFooter, g as useOpenApis, h as useClarifyConfig, i as DocShell, l as ThemeToggle, m as OpenApisContext, n as ApiEndpointCard, o as Logo, p as ClarifyConfigContext, r as Button, s as Prose, t as AppShell, u as ThemeProvider, v as HeroPattern, w as SectionProvider, x as CodeGroup, y as Feedback } from "./AppShell-C_bj6ZhV.js";
2
+ import { t as render } from "./render-Ca4Is683.js";
3
+ import { createElement, useRef, useState } from "react";
4
+ import { Link, useLocation } from "react-router-dom";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
+ import clsx from "clsx";
7
+ import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
8
+ import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
9
+ import { slug } from "github-slugger";
10
+ //#region \0rolldown/runtime.js
11
+ var __defProp = Object.defineProperty;
12
+ var __exportAll = (all, no_symbols) => {
13
+ let target = {};
14
+ for (var name in all) __defProp(target, name, {
15
+ get: all[name],
16
+ enumerable: true
17
+ });
18
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
19
+ return target;
20
+ };
21
+ //#endregion
22
+ //#region source/mdx/primitives.tsx
23
+ var primitives_exports = /* @__PURE__ */ __exportAll({
24
+ Button: () => Button,
25
+ CodeGroup: () => CodeGroup,
26
+ Col: () => Col,
27
+ Note: () => Note,
28
+ Properties: () => Properties,
29
+ Property: () => Property,
30
+ Row: () => Row,
31
+ a: () => a,
32
+ code: () => code,
33
+ h2: () => h2,
34
+ h3: () => h3,
35
+ pre: () => pre,
36
+ wrapper: () => wrapper
37
+ });
38
+ function wrapper(arg0) {
39
+ const { children } = arg0;
40
+ return /* @__PURE__ */ jsxs("article", {
41
+ className: "clarify-mdx-page flex h-full flex-col pt-16 pb-10",
42
+ children: [/* @__PURE__ */ jsx(Prose, {
43
+ className: "flex-auto",
44
+ children
45
+ }), /* @__PURE__ */ jsx(PageFooter, {})]
46
+ });
47
+ }
48
+ function a(arg0) {
49
+ const { href = "", ...props } = arg0;
50
+ if (href.startsWith("/") && !href.startsWith("//")) return /* @__PURE__ */ jsx(Link, {
51
+ to: href,
52
+ ...props
53
+ });
54
+ return /* @__PURE__ */ jsx("a", {
55
+ href,
56
+ ...props
57
+ });
58
+ }
59
+ var code = Code;
60
+ var pre = Pre;
61
+ function h2(props) {
62
+ return createElement(Heading, {
63
+ level: 2,
64
+ ...props
65
+ });
66
+ }
67
+ function h3(props) {
68
+ return createElement(Heading, {
69
+ level: 3,
70
+ ...props
71
+ });
72
+ }
73
+ function InfoIcon(props) {
74
+ return /* @__PURE__ */ jsxs("svg", {
75
+ viewBox: "0 0 16 16",
76
+ "aria-hidden": "true",
77
+ ...props,
78
+ children: [
79
+ /* @__PURE__ */ jsx("circle", {
80
+ cx: "8",
81
+ cy: "8",
82
+ r: "8",
83
+ strokeWidth: "0"
84
+ }),
85
+ /* @__PURE__ */ jsx("path", {
86
+ fill: "none",
87
+ strokeLinecap: "round",
88
+ strokeLinejoin: "round",
89
+ strokeWidth: "1.5",
90
+ d: "M6.75 7.75h1.5v3.5"
91
+ }),
92
+ /* @__PURE__ */ jsx("circle", {
93
+ cx: "8",
94
+ cy: "4",
95
+ r: ".5",
96
+ fill: "none"
97
+ })
98
+ ]
99
+ });
100
+ }
101
+ function Note(arg0) {
102
+ const { children } = arg0;
103
+ return /* @__PURE__ */ jsxs("div", {
104
+ className: "clarify-note my-6 flex gap-2.5 rounded-2xl border border-emerald-500/20 bg-emerald-50/50 p-4 text-sm/6 text-emerald-900 dark:border-emerald-500/30 dark:bg-emerald-500/5 dark:text-emerald-200 dark:[--tw-prose-links-hover:var(--color-emerald-300)] dark:[--tw-prose-links:var(--color-white)]",
105
+ children: [/* @__PURE__ */ jsx(InfoIcon, { className: "mt-1 h-4 w-4 flex-none fill-emerald-500 stroke-white dark:fill-emerald-200/20 dark:stroke-emerald-200" }), /* @__PURE__ */ jsx("div", {
106
+ className: "*:first:mt-0 *:last:mb-0",
107
+ children
108
+ })]
109
+ });
110
+ }
111
+ function Row(arg0) {
112
+ const { children } = arg0;
113
+ return /* @__PURE__ */ jsx("div", {
114
+ className: "clarify-row grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2",
115
+ children
116
+ });
117
+ }
118
+ function Col(arg0) {
119
+ const { children, sticky = false } = arg0;
120
+ return /* @__PURE__ */ jsx("div", {
121
+ className: clsx("clarify-col *:first:mt-0 *:last:mb-0", sticky && "xl:sticky xl:top-24"),
122
+ children
123
+ });
124
+ }
125
+ function Properties(arg0) {
126
+ const { children } = arg0;
127
+ return /* @__PURE__ */ jsx("div", {
128
+ className: "clarify-properties my-6",
129
+ children: /* @__PURE__ */ jsx("ul", {
130
+ role: "list",
131
+ className: "m-0 list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5",
132
+ children
133
+ })
134
+ });
135
+ }
136
+ function Property(arg0) {
137
+ const { name, children, type } = arg0;
138
+ return /* @__PURE__ */ jsx("li", {
139
+ className: "clarify-property m-0 px-0 py-4 first:pt-0 last:pb-0",
140
+ children: /* @__PURE__ */ jsxs("dl", {
141
+ className: "m-0 flex flex-wrap items-center gap-x-3 gap-y-2",
142
+ children: [
143
+ /* @__PURE__ */ jsx("dt", {
144
+ className: "sr-only",
145
+ children: "Name"
146
+ }),
147
+ /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { children: name }) }),
148
+ type ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("dt", {
149
+ className: "sr-only",
150
+ children: "Type"
151
+ }), /* @__PURE__ */ jsx("dd", {
152
+ className: "font-mono text-xs text-zinc-400 dark:text-zinc-500",
153
+ children: type
154
+ })] }) : null,
155
+ /* @__PURE__ */ jsx("dt", {
156
+ className: "sr-only",
157
+ children: "Description"
158
+ }),
159
+ /* @__PURE__ */ jsx("dd", {
160
+ className: "w-full flex-none *:first:mt-0 *:last:mb-0",
161
+ children
162
+ })
163
+ ]
164
+ })
165
+ });
166
+ }
167
+ //#endregion
168
+ //#region source/openapi/utils.ts
169
+ var OPENAPI_HTTP_METHODS = [
170
+ "get",
171
+ "put",
172
+ "post",
173
+ "delete",
174
+ "options",
175
+ "head",
176
+ "patch",
177
+ "trace"
178
+ ];
179
+ function isOpenAPIHttpMethod(method) {
180
+ return OPENAPI_HTTP_METHODS.includes(method.toLowerCase());
181
+ }
182
+ function getOpenApiOperation(spec, path, method) {
183
+ if (!isOpenAPIHttpMethod(method)) return void 0;
184
+ return spec.paths?.[path]?.[method.toLowerCase()];
185
+ }
186
+ function listOpenApiOperations(spec) {
187
+ const paths = spec.paths ?? {};
188
+ const operations = [];
189
+ for (const [path, pathItem] of Object.entries(paths)) {
190
+ if (!pathItem) continue;
191
+ for (const method of OPENAPI_HTTP_METHODS) {
192
+ const operation = pathItem[method];
193
+ if (operation) operations.push({
194
+ path,
195
+ method,
196
+ operation
197
+ });
198
+ }
199
+ }
200
+ return operations;
201
+ }
202
+ //#endregion
203
+ //#region source/openapi/index.tsx
204
+ var VIRTUAL_PREFIX = "virtual:clarify-page/";
205
+ function isRecord(value) {
206
+ return typeof value === "object" && value !== null && !Array.isArray(value);
207
+ }
208
+ function isReference(value) {
209
+ return isRecord(value) && typeof value.$ref === "string";
210
+ }
211
+ function resolveReferenceName(ref) {
212
+ return ref.split("/").filter(Boolean).at(-1) ?? ref;
213
+ }
214
+ function getPathItem(spec, path) {
215
+ const pathItem = spec.paths?.[path];
216
+ return isRecord(pathItem) ? pathItem : void 0;
217
+ }
218
+ function getOperationParameters(spec, path, operation) {
219
+ const pathParameters = getPathItem(spec, path)?.parameters;
220
+ const operationParameters = operation.parameters;
221
+ return [...Array.isArray(pathParameters) ? pathParameters : [], ...Array.isArray(operationParameters) ? operationParameters : []].filter((parameter) => isRecord(parameter) && !isReference(parameter));
222
+ }
223
+ function getRequestBody(operation) {
224
+ const requestBody = operation.requestBody;
225
+ return isRecord(requestBody) && !isReference(requestBody) ? requestBody : void 0;
226
+ }
227
+ function getMediaTypeEntries(content) {
228
+ if (!isRecord(content)) return [];
229
+ return Object.entries(content).filter(([, value]) => isRecord(value) && !isReference(value)).map(([mediaType, value]) => ({
230
+ mediaType,
231
+ value
232
+ })).sort((a, z) => {
233
+ return (a.mediaType.includes("json") ? 0 : 1) - (z.mediaType.includes("json") ? 0 : 1);
234
+ });
235
+ }
236
+ function getJsonLikeContent(content) {
237
+ return getMediaTypeEntries(content)[0];
238
+ }
239
+ function getExampleValue(example) {
240
+ if (isRecord(example) && "value" in example) return example.value;
241
+ if (isRecord(example) && "externalValue" in example) return void 0;
242
+ return example;
243
+ }
244
+ function getExampleTitle(key, example) {
245
+ if (isRecord(example)) {
246
+ const summary = typeof example.summary === "string" ? example.summary : void 0;
247
+ return {
248
+ title: summary ?? key,
249
+ summary
250
+ };
251
+ }
252
+ return { title: key };
253
+ }
254
+ function getExampleEntries(mediaType) {
255
+ if (!mediaType) return [];
256
+ if (isRecord(mediaType.examples)) {
257
+ const examples = [];
258
+ for (const [key, example] of Object.entries(mediaType.examples)) {
259
+ const value = getExampleValue(example);
260
+ if (typeof value === "undefined") continue;
261
+ const { title, summary } = getExampleTitle(key, example);
262
+ examples.push({
263
+ key,
264
+ title,
265
+ summary,
266
+ value
267
+ });
268
+ }
269
+ if (examples.length > 0) return examples;
270
+ }
271
+ if (typeof mediaType.example !== "undefined") return [{
272
+ key: "default",
273
+ title: "Example",
274
+ value: mediaType.example
275
+ }];
276
+ const generated = schemaToExample(mediaType.schema);
277
+ return typeof generated === "undefined" ? [] : [{
278
+ key: "schema",
279
+ title: "Schema example",
280
+ value: generated,
281
+ generated: true
282
+ }];
283
+ }
284
+ function getContentExample(mediaType) {
285
+ return getExampleEntries(mediaType)[0]?.value;
286
+ }
287
+ function schemaToType(schema) {
288
+ if (!isRecord(schema)) return void 0;
289
+ if (isReference(schema)) return resolveReferenceName(schema.$ref);
290
+ if (Array.isArray(schema.enum)) return schema.enum.map(String).join(" | ");
291
+ const oneOf = schema.oneOf ?? schema.anyOf;
292
+ if (Array.isArray(oneOf)) return oneOf.map(schemaToType).filter(Boolean).join(" | ");
293
+ if (schema.type === "array") return `${schemaToType(schema.items) ?? "unknown"}[]`;
294
+ return typeof schema.type === "string" ? schema.type : void 0;
295
+ }
296
+ function schemaToExample(schema, depth = 0) {
297
+ if (!isRecord(schema) || depth > 3) return void 0;
298
+ if (typeof schema.example !== "undefined") return schema.example;
299
+ if (typeof schema.default !== "undefined") return schema.default;
300
+ if (Array.isArray(schema.enum)) return schema.enum[0];
301
+ if (isReference(schema)) return { id: resolveReferenceName(schema.$ref) };
302
+ if (schema.type === "array") return [schemaToExample(schema.items, depth + 1) ?? "string"];
303
+ if (schema.type === "object" || isRecord(schema.properties)) {
304
+ const properties = isRecord(schema.properties) ? schema.properties : {};
305
+ return Object.fromEntries(Object.entries(properties).slice(0, 8).map(([name, propertySchema]) => [name, schemaToExample(propertySchema, depth + 1) ?? exampleForType(schemaToType(propertySchema))]));
306
+ }
307
+ return exampleForType(schemaToType(schema));
308
+ }
309
+ function exampleForType(type) {
310
+ if (!type) return "string";
311
+ if (type.endsWith("[]")) return [];
312
+ if (type.includes("integer") || type.includes("number")) return 42;
313
+ if (type.includes("boolean")) return true;
314
+ if (type.includes("object")) return {};
315
+ return "string";
316
+ }
317
+ function stringifyExample(value) {
318
+ if (typeof value === "undefined") return "";
319
+ if (typeof value === "string") return value;
320
+ return JSON.stringify(value, null, 2);
321
+ }
322
+ function shellQuote(value) {
323
+ return `'${value.replace(/'/g, `'"'"'`)}'`;
324
+ }
325
+ function getServerUrl(spec) {
326
+ const servers = spec.servers;
327
+ if (!Array.isArray(servers)) return "";
328
+ const firstServer = servers.find(isRecord);
329
+ return typeof firstServer?.url === "string" ? firstServer.url : "";
330
+ }
331
+ function buildOperationUrl(spec, path, parameters) {
332
+ const query = parameters.filter((parameter) => parameter.in === "query" && parameter.name).map((parameter) => `${parameter.name}={${parameter.name}}`).join("&");
333
+ return `${getServerUrl(spec).replace(/\/$/, "")}${path}${query ? `?${query}` : ""}`;
334
+ }
335
+ function buildCurlExample(arg0) {
336
+ const { spec, path, method, parameters, requestContent } = arg0;
337
+ const url = buildOperationUrl(spec, path, parameters);
338
+ const lines = [`curl ${method === "GET" ? "-G " : ""}${shellQuote(url)}`];
339
+ if (method !== "GET") lines.push(` -X ${method}`);
340
+ lines.push(" -H 'Authorization: Bearer {token}'");
341
+ lines.push(" -H 'Accept: application/json'");
342
+ const requestExample = getContentExample(requestContent?.value);
343
+ if (requestContent && typeof requestExample !== "undefined") {
344
+ lines.push(` -H 'Content-Type: ${requestContent.mediaType}'`);
345
+ lines.push(` -d ${shellQuote(stringifyExample(requestExample))}`);
346
+ }
347
+ return lines.join(" \\\n");
348
+ }
349
+ function getResponseEntries(operation) {
350
+ const responses = operation.responses;
351
+ if (!isRecord(responses)) return [];
352
+ return Object.entries(responses).filter(([, response]) => isRecord(response) && !isReference(response)).map(([status, response]) => ({
353
+ status,
354
+ response
355
+ }));
356
+ }
357
+ function SchemaProperties(arg0) {
358
+ const { title, schema } = arg0;
359
+ const targetSchema = isReference(schema) ? void 0 : schema;
360
+ const properties = isRecord(targetSchema) && isRecord(targetSchema.properties) ? targetSchema.properties : void 0;
361
+ const required = isRecord(targetSchema) && Array.isArray(targetSchema.required) ? targetSchema.required.map(String) : [];
362
+ if (!properties || Object.keys(properties).length === 0) return null;
363
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx(Properties, { children: Object.entries(properties).map(([name, propertySchema]) => {
364
+ const property = isRecord(propertySchema) ? propertySchema : {};
365
+ const type = schemaToType(propertySchema);
366
+ const description = typeof property.description === "string" ? property.description : void 0;
367
+ const isRequired = required.includes(name);
368
+ return /* @__PURE__ */ jsx(Property, {
369
+ name,
370
+ type: isRequired && type ? `${type}, required` : type,
371
+ children: description ?? (isRequired ? "Required." : "Optional.")
372
+ }, name);
373
+ }) })] });
374
+ }
375
+ function ParameterList(arg0) {
376
+ const { title, parameters } = arg0;
377
+ if (parameters.length === 0) return null;
378
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx(Properties, { children: parameters.map((parameter) => /* @__PURE__ */ jsx(Property, {
379
+ name: parameter.name ?? "parameter",
380
+ type: [schemaToType(parameter.schema), parameter.required ? "required" : void 0].filter(Boolean).join(", ") || void 0,
381
+ children: parameter.description ?? `${parameter.in ?? "Operation"} parameter.`
382
+ }, `${parameter.in}-${parameter.name}`)) })] });
383
+ }
384
+ function ResponseList(arg0) {
385
+ const { operation } = arg0;
386
+ const responses = getResponseEntries(operation);
387
+ if (responses.length === 0) return null;
388
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: "Responses" }), /* @__PURE__ */ jsx(Properties, { children: responses.map(({ status, response }) => {
389
+ return /* @__PURE__ */ jsx(Property, {
390
+ name: status,
391
+ type: schemaToType(getJsonLikeContent(response.content)?.value.schema),
392
+ children: response.description ?? "Response."
393
+ }, status);
394
+ }) })] });
395
+ }
396
+ function codeLanguageForMediaType(mediaType) {
397
+ if (!mediaType) return "json";
398
+ if (mediaType.includes("json")) return "json";
399
+ if (mediaType.includes("yaml") || mediaType.includes("yml")) return "yaml";
400
+ if (mediaType.startsWith("text/")) return "text";
401
+ if (mediaType.includes("xml")) return "xml";
402
+ return "text";
403
+ }
404
+ function SelectControl(arg0) {
405
+ const { label, value, options, onChange } = arg0;
406
+ if (options.length <= 1) return null;
407
+ return /* @__PURE__ */ jsx(Listbox, {
408
+ value,
409
+ onChange,
410
+ children: /* @__PURE__ */ jsxs("div", {
411
+ className: "clarify-api-select relative flex flex-col gap-1 text-[0.625rem]/5 font-semibold tracking-widest text-zinc-400 uppercase",
412
+ children: [/* @__PURE__ */ jsxs(ListboxButton, {
413
+ className: "clarify-api-select-button flex min-w-32 items-center justify-between gap-2 rounded-lg border border-white/10 bg-zinc-900 px-2.5 py-1.5 font-mono text-xs font-medium tracking-normal text-zinc-100 outline-hidden transition hover:border-white/20 focus:border-emerald-400 focus:ring-2 focus:ring-emerald-400/20 data-open:border-emerald-400 data-open:ring-2 data-open:ring-emerald-400/20",
414
+ children: [/* @__PURE__ */ jsxs("span", {
415
+ className: "flex flex-col items-start gap-0.5 truncate",
416
+ children: [/* @__PURE__ */ jsx("span", {
417
+ className: "font-sans text-[0.625rem]/4 font-semibold tracking-widest text-zinc-500 uppercase",
418
+ children: label
419
+ }), /* @__PURE__ */ jsx("span", {
420
+ className: "truncate",
421
+ children: value
422
+ })]
423
+ }), /* @__PURE__ */ jsx(ChevronsUpDownIcon, {
424
+ className: "h-3.5 w-3.5 shrink-0 text-zinc-500",
425
+ "aria-hidden": "true"
426
+ })]
427
+ }), /* @__PURE__ */ jsx(ListboxOptions, {
428
+ anchor: "bottom start",
429
+ className: "clarify-api-select-options z-30 mt-1 max-h-64 w-(--button-width) min-w-40 overflow-auto rounded-xl border border-white/10 bg-zinc-900 p-1 text-xs shadow-lg shadow-black/20 [--anchor-gap:--spacing(1)] focus:outline-none",
430
+ children: options.map((option) => /* @__PURE__ */ jsxs(ListboxOption, {
431
+ value: option,
432
+ className: "clarify-api-select-option group flex cursor-default items-center justify-between gap-3 rounded-lg px-2.5 py-2 font-mono text-xs text-zinc-300 select-none data-focus:bg-white/10 data-focus:text-white data-selected:text-emerald-300",
433
+ children: [/* @__PURE__ */ jsx("span", {
434
+ className: "truncate",
435
+ children: option
436
+ }), /* @__PURE__ */ jsx(CheckIcon, {
437
+ className: "h-3.5 w-3.5 shrink-0 opacity-0 group-data-selected:opacity-100",
438
+ "aria-hidden": "true"
439
+ })]
440
+ }, option))
441
+ })]
442
+ })
443
+ });
444
+ }
445
+ function ExamplePicker(arg0) {
446
+ const { examples, selectedKey, onSelect } = arg0;
447
+ const scrollerRef = useRef(null);
448
+ if (examples.length <= 1) return null;
449
+ function scrollBy(direction) {
450
+ const el = scrollerRef.current;
451
+ if (!el) return;
452
+ el.scrollBy({
453
+ left: direction * Math.max(120, el.clientWidth * .6),
454
+ behavior: "smooth"
455
+ });
456
+ }
457
+ return /* @__PURE__ */ jsxs("div", {
458
+ className: "relative -mr-1 flex min-w-0 flex-1 items-center gap-1",
459
+ children: [
460
+ /* @__PURE__ */ jsx("button", {
461
+ type: "button",
462
+ "aria-label": "Scroll examples left",
463
+ onClick: () => scrollBy(-1),
464
+ className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-zinc-500 transition hover:bg-white/5 hover:text-zinc-200",
465
+ children: /* @__PURE__ */ jsx("svg", {
466
+ viewBox: "0 0 20 20",
467
+ fill: "currentColor",
468
+ className: "h-3 w-3",
469
+ children: /* @__PURE__ */ jsx("path", {
470
+ fillRule: "evenodd",
471
+ d: "M12.79 5.23a.75.75 0 010 1.06L9.06 10l3.73 3.71a.75.75 0 11-1.06 1.06l-4.25-4.24a.75.75 0 010-1.06l4.25-4.24a.75.75 0 011.06 0z",
472
+ clipRule: "evenodd"
473
+ })
474
+ })
475
+ }),
476
+ /* @__PURE__ */ jsx("div", {
477
+ ref: scrollerRef,
478
+ className: "flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto whitespace-nowrap scroll-smooth scrollbar-none [&::-webkit-scrollbar]:hidden",
479
+ children: examples.map((example) => /* @__PURE__ */ jsx("button", {
480
+ type: "button",
481
+ onClick: () => onSelect(example.key),
482
+ title: example.summary,
483
+ className: ["shrink-0 rounded-md px-2 py-0.5 text-xs font-medium transition", example.key === selectedKey ? "bg-white/10 text-white" : "text-zinc-400 hover:bg-white/5 hover:text-zinc-200"].join(" "),
484
+ children: example.title
485
+ }, example.key))
486
+ }),
487
+ /* @__PURE__ */ jsx("button", {
488
+ type: "button",
489
+ "aria-label": "Scroll examples right",
490
+ onClick: () => scrollBy(1),
491
+ className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-zinc-500 transition hover:bg-white/5 hover:text-zinc-200",
492
+ children: /* @__PURE__ */ jsx("svg", {
493
+ viewBox: "0 0 20 20",
494
+ fill: "currentColor",
495
+ className: "h-3 w-3",
496
+ children: /* @__PURE__ */ jsx("path", {
497
+ fillRule: "evenodd",
498
+ d: "M7.21 14.77a.75.75 0 010-1.06L10.94 10 7.21 6.29a.75.75 0 111.06-1.06l4.25 4.24a.75.75 0 010 1.06l-4.25 4.24a.75.75 0 01-1.06 0z",
499
+ clipRule: "evenodd"
500
+ })
501
+ })
502
+ })
503
+ ]
504
+ });
505
+ }
506
+ function CopyCodeButton(arg0) {
507
+ const { code } = arg0;
508
+ const [copied, setCopied] = useState(false);
509
+ return /* @__PURE__ */ jsx("button", {
510
+ type: "button",
511
+ onClick: () => {
512
+ window.navigator.clipboard.writeText(code).then(() => {
513
+ setCopied(true);
514
+ window.setTimeout(() => setCopied(false), 1e3);
515
+ });
516
+ },
517
+ className: "absolute top-3.5 right-4 rounded-full bg-white/5 px-3 py-1 text-2xs font-medium text-zinc-400 opacity-0 transition hover:bg-white/10 hover:text-zinc-200 group-hover:opacity-100 focus:opacity-100",
518
+ children: copied ? "Copied!" : "Copy"
519
+ });
520
+ }
521
+ function ApiExampleCodeGroup(arg0) {
522
+ const { title, tag, label, code, language, examples, selectedExampleKey, onSelectExample } = arg0;
523
+ return /* @__PURE__ */ jsx("div", {
524
+ className: "clarify-api-example my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10",
525
+ children: /* @__PURE__ */ jsxs("div", {
526
+ className: "not-prose",
527
+ children: [
528
+ /* @__PURE__ */ jsxs("div", {
529
+ className: "clarify-api-example-header flex min-h-[calc(--spacing(12)+1px)] flex-wrap items-center gap-x-4 border-b border-zinc-700 bg-zinc-800 px-4 dark:border-zinc-800 dark:bg-transparent",
530
+ children: [/* @__PURE__ */ jsx("h3", {
531
+ className: "shrink-0 py-3 text-xs font-semibold text-white",
532
+ children: title
533
+ }), examples && examples.length > 1 && selectedExampleKey && onSelectExample ? /* @__PURE__ */ jsx(ExamplePicker, {
534
+ examples,
535
+ selectedKey: selectedExampleKey,
536
+ onSelect: onSelectExample
537
+ }) : null]
538
+ }),
539
+ tag || label ? /* @__PURE__ */ jsxs("div", {
540
+ className: "flex h-9 items-center gap-2 border-y border-t-transparent border-b-white/7.5 bg-zinc-900 px-4 dark:border-b-white/5 dark:bg-white/1",
541
+ children: [
542
+ tag ? /* @__PURE__ */ jsx("span", {
543
+ className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400",
544
+ children: tag
545
+ }) : null,
546
+ tag && label ? /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 rounded-full bg-zinc-500" }) : null,
547
+ label ? /* @__PURE__ */ jsx("span", {
548
+ className: "font-mono text-xs text-zinc-400",
549
+ children: label
550
+ }) : null
551
+ ]
552
+ }) : null,
553
+ /* @__PURE__ */ jsxs("div", {
554
+ className: "clarify-api-example-code group relative",
555
+ children: [/* @__PURE__ */ jsx("pre", {
556
+ className: "overflow-x-auto p-4 text-xs text-white",
557
+ children: /* @__PURE__ */ jsx("code", {
558
+ className: `language-${language}`,
559
+ children: code
560
+ })
561
+ }), /* @__PURE__ */ jsx(CopyCodeButton, { code })]
562
+ })
563
+ ]
564
+ })
565
+ });
566
+ }
567
+ function RequestExamplesPanel(arg0) {
568
+ const { spec, path, method, parameters, requestContents } = arg0;
569
+ const [selectedMediaType, setSelectedMediaType] = useState(requestContents[0]?.mediaType ?? "");
570
+ const selectedContent = requestContents.find((content) => content.mediaType === selectedMediaType) ?? requestContents[0];
571
+ const examples = getExampleEntries(selectedContent?.value);
572
+ const [selectedExampleKey, setSelectedExampleKey] = useState(examples[0]?.key ?? "");
573
+ const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
574
+ const curl = buildCurlExample({
575
+ spec,
576
+ path,
577
+ method,
578
+ parameters,
579
+ requestContent: selectedContent ? {
580
+ ...selectedContent,
581
+ value: {
582
+ ...selectedContent.value,
583
+ example: selectedExample?.value,
584
+ examples: void 0
585
+ }
586
+ } : void 0
587
+ });
588
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
589
+ className: "mb-3 flex flex-wrap gap-3",
590
+ children: /* @__PURE__ */ jsx(SelectControl, {
591
+ label: "Media type",
592
+ value: selectedContent?.mediaType ?? "",
593
+ options: requestContents.map((content) => content.mediaType),
594
+ onChange: (value) => {
595
+ setSelectedMediaType(value);
596
+ setSelectedExampleKey(getExampleEntries(requestContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
597
+ }
598
+ })
599
+ }), /* @__PURE__ */ jsx(ApiExampleCodeGroup, {
600
+ title: "Request",
601
+ tag: method,
602
+ label: path,
603
+ code: curl,
604
+ language: "bash",
605
+ examples,
606
+ selectedExampleKey: selectedExample?.key,
607
+ onSelectExample: setSelectedExampleKey
608
+ })] });
609
+ }
610
+ function ResponseExamplesPanel(arg0) {
611
+ const { operation } = arg0;
612
+ const responses = getResponseEntries(operation).filter(({ response }) => getMediaTypeEntries(response.content).length > 0);
613
+ const [selectedStatus, setSelectedStatus] = useState(responses.find(({ status }) => status.startsWith("2"))?.status ?? responses[0]?.status ?? "");
614
+ const selectedResponse = responses.find(({ status }) => status === selectedStatus) ?? responses[0];
615
+ const responseContents = getMediaTypeEntries(selectedResponse?.response.content);
616
+ const [selectedMediaType, setSelectedMediaType] = useState(responseContents[0]?.mediaType ?? "");
617
+ const selectedContent = responseContents.find((content) => content.mediaType === selectedMediaType) ?? responseContents[0];
618
+ const examples = getExampleEntries(selectedContent?.value);
619
+ const [selectedExampleKey, setSelectedExampleKey] = useState(examples[0]?.key ?? "");
620
+ const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
621
+ const responseCode = stringifyExample(selectedExample?.value);
622
+ if (!selectedResponse || !selectedContent || !responseCode) return null;
623
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
624
+ className: "mb-3 flex flex-wrap gap-3",
625
+ children: [/* @__PURE__ */ jsx(SelectControl, {
626
+ label: "Status",
627
+ value: selectedResponse.status,
628
+ options: responses.map(({ status }) => status),
629
+ onChange: (value) => {
630
+ const nextContents = getMediaTypeEntries(responses.find(({ status }) => status === value)?.response.content);
631
+ setSelectedStatus(value);
632
+ setSelectedMediaType(nextContents[0]?.mediaType ?? "");
633
+ setSelectedExampleKey(getExampleEntries(nextContents[0]?.value)[0]?.key ?? "");
634
+ }
635
+ }), /* @__PURE__ */ jsx(SelectControl, {
636
+ label: "Media type",
637
+ value: selectedContent.mediaType,
638
+ options: responseContents.map((content) => content.mediaType),
639
+ onChange: (value) => {
640
+ setSelectedMediaType(value);
641
+ setSelectedExampleKey(getExampleEntries(responseContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
642
+ }
643
+ })]
644
+ }), /* @__PURE__ */ jsx(ApiExampleCodeGroup, {
645
+ title: "Response",
646
+ tag: selectedResponse.status,
647
+ label: selectedContent.mediaType,
648
+ code: responseCode,
649
+ language: codeLanguageForMediaType(selectedContent.mediaType),
650
+ examples,
651
+ selectedExampleKey: selectedExample?.key,
652
+ onSelectExample: setSelectedExampleKey
653
+ })] });
654
+ }
655
+ function EndpointExamples(arg0) {
656
+ const { spec, path, method, operation, parameters, requestContents } = arg0;
657
+ return /* @__PURE__ */ jsxs("div", {
658
+ className: "space-y-6",
659
+ children: [/* @__PURE__ */ jsx(RequestExamplesPanel, {
660
+ spec,
661
+ path,
662
+ method,
663
+ parameters,
664
+ requestContents
665
+ }), /* @__PURE__ */ jsx(ResponseExamplesPanel, { operation })]
666
+ });
667
+ }
668
+ function OpenApiHeader(arg0) {
669
+ const { spec } = arg0;
670
+ return /* @__PURE__ */ jsxs("header", {
671
+ className: "mb-16",
672
+ children: [
673
+ /* @__PURE__ */ jsx("p", {
674
+ className: "mb-3 font-mono text-xs/6 font-medium tracking-widest text-emerald-500 uppercase dark:text-emerald-400",
675
+ children: "OpenAPI Reference"
676
+ }),
677
+ /* @__PURE__ */ jsx("h1", { children: spec.info?.title ?? "API Documentation" }),
678
+ spec.info?.description ? /* @__PURE__ */ jsx("p", {
679
+ className: "lead",
680
+ children: spec.info.description
681
+ }) : null,
682
+ spec.info?.version ? /* @__PURE__ */ jsxs("p", {
683
+ className: "text-sm text-zinc-500 dark:text-zinc-400",
684
+ children: ["Version ", spec.info.version]
685
+ }) : null
686
+ ]
687
+ });
688
+ }
689
+ function OpenApiOperation(arg0) {
690
+ const { spec, path, method, operation } = arg0;
691
+ const id = slug(`${method.toLowerCase()} ${path}`);
692
+ const summary = operation.summary ?? `${method} ${path}`;
693
+ const description = operation.description;
694
+ const parameters = getOperationParameters(spec, path, operation);
695
+ const requestBody = getRequestBody(operation);
696
+ const requestContents = getMediaTypeEntries(requestBody?.content);
697
+ const requestSchema = requestContents[0]?.value.schema;
698
+ const groupedParameters = {
699
+ path: parameters.filter((parameter) => parameter.in === "path"),
700
+ query: parameters.filter((parameter) => parameter.in === "query"),
701
+ header: parameters.filter((parameter) => parameter.in === "header")
702
+ };
703
+ return /* @__PURE__ */ jsxs("section", {
704
+ className: "clarify-api-endpoint scroll-mt-24",
705
+ "aria-labelledby": id,
706
+ children: [/* @__PURE__ */ jsx(Heading, {
707
+ id,
708
+ tag: method,
709
+ label: path,
710
+ children: summary
711
+ }), /* @__PURE__ */ jsxs(Row, { children: [/* @__PURE__ */ jsxs(Col, { children: [
712
+ description ? /* @__PURE__ */ jsx("p", { children: description }) : null,
713
+ /* @__PURE__ */ jsx(ParameterList, {
714
+ title: "Path parameters",
715
+ parameters: groupedParameters.path
716
+ }),
717
+ /* @__PURE__ */ jsx(ParameterList, {
718
+ title: "Query parameters",
719
+ parameters: groupedParameters.query
720
+ }),
721
+ /* @__PURE__ */ jsx(ParameterList, {
722
+ title: "Headers",
723
+ parameters: groupedParameters.header
724
+ }),
725
+ requestBody && requestContents.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
726
+ /* @__PURE__ */ jsx("h3", { children: "Request body" }),
727
+ typeof requestBody.description === "string" ? /* @__PURE__ */ jsx("p", { children: requestBody.description }) : null,
728
+ /* @__PURE__ */ jsx(SchemaProperties, {
729
+ title: "Body properties",
730
+ schema: requestSchema
731
+ })
732
+ ] }) : null,
733
+ /* @__PURE__ */ jsx(ResponseList, { operation })
734
+ ] }), /* @__PURE__ */ jsx(Col, {
735
+ sticky: true,
736
+ children: /* @__PURE__ */ jsx(EndpointExamples, {
737
+ spec,
738
+ path,
739
+ method,
740
+ operation,
741
+ parameters,
742
+ requestContents
743
+ })
744
+ })] })]
745
+ });
746
+ }
747
+ function OpenApiPaths(arg0) {
748
+ const { spec } = arg0;
749
+ return /* @__PURE__ */ jsx("div", {
750
+ className: "clarify-api-endpoints space-y-16",
751
+ children: listOpenApiOperations(spec).map(({ path, method, operation }) => ({
752
+ path,
753
+ method: method.toUpperCase(),
754
+ operation
755
+ })).map(({ path, method, operation }) => /* @__PURE__ */ jsx(OpenApiOperation, {
756
+ spec,
757
+ path,
758
+ method,
759
+ operation
760
+ }, `${method}-${path}`))
761
+ });
762
+ }
763
+ function resolveRelativePath(fromDir, to) {
764
+ const parts = (fromDir + "/" + to).split("/").filter(Boolean);
765
+ const stack = [];
766
+ for (const part of parts) if (part === "..") stack.pop();
767
+ else if (part !== ".") stack.push(part);
768
+ return stack.join("/");
769
+ }
770
+ function normalizeSpecPath(specPath, currentRoutePath, routePrefix = "") {
771
+ if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath;
772
+ const normalizedRoutePrefix = routePrefix.replace(/^\/+|\/+$/g, "");
773
+ const normalizedSpecPath = specPath.startsWith("/") && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`) ? "/" + specPath.slice(normalizedRoutePrefix.length + 2) : specPath;
774
+ if (normalizedSpecPath.startsWith("/")) return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\//, "");
775
+ const fromDir = currentRoutePath === "/" ? "" : currentRoutePath?.replace(/^\//, "").replace(/\/[^/]*$/, "") ?? "";
776
+ return VIRTUAL_PREFIX + resolveRelativePath(normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`) ? fromDir.slice(normalizedRoutePrefix.length + 1) : fromDir, normalizedSpecPath);
777
+ }
778
+ function useOpenApiSpec(spec, specPath) {
779
+ const specs = useOpenApis();
780
+ const location = useLocation();
781
+ const config = useClarifyConfig();
782
+ if (spec) return spec;
783
+ if (!specPath) return null;
784
+ return specs[normalizeSpecPath(specPath, location.pathname, config.routePrefix)] ?? null;
785
+ }
786
+ function WarningBox(arg0) {
787
+ const { children, tone = "amber" } = arg0;
788
+ return /* @__PURE__ */ jsx("div", {
789
+ className: clsx("clarify-warning", tone === "red" ? "rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200" : "rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200"),
790
+ children
791
+ });
792
+ }
793
+ function OpenApiPage(arg0) {
794
+ const { spec, specPath } = arg0;
795
+ const resolved = useOpenApiSpec(spec, specPath);
796
+ if (!resolved) return /* @__PURE__ */ jsxs(WarningBox, { children: ["OpenAPI spec not found: ", specPath ?? "(未提供 spec 或 specPath)"] });
797
+ return /* @__PURE__ */ jsxs("article", {
798
+ className: "clarify-openapi-page flex h-full flex-col pt-16 pb-10",
799
+ children: [/* @__PURE__ */ jsxs(Prose, {
800
+ className: "flex-auto",
801
+ children: [/* @__PURE__ */ jsx(OpenApiHeader, { spec: resolved }), /* @__PURE__ */ jsx(OpenApiPaths, { spec: resolved })]
802
+ }), /* @__PURE__ */ jsx(PageFooter, {})]
803
+ });
804
+ }
805
+ function ApiEndpoint(arg0) {
806
+ const { spec, path, method } = arg0;
807
+ const op = getOpenApiOperation(spec, path, method);
808
+ if (!op) return /* @__PURE__ */ jsxs(WarningBox, {
809
+ tone: "red",
810
+ children: [
811
+ "Endpoint not found: ",
812
+ method.toUpperCase(),
813
+ " ",
814
+ path
815
+ ]
816
+ });
817
+ return /* @__PURE__ */ jsx(OpenApiOperation, {
818
+ spec,
819
+ path,
820
+ method: method.toUpperCase(),
821
+ operation: op
822
+ });
823
+ }
824
+ function OpenApiEndpoint(arg0) {
825
+ const { specPath, path, method } = arg0;
826
+ const spec = useOpenApiSpec(void 0, specPath);
827
+ if (!spec) return /* @__PURE__ */ jsxs(WarningBox, { children: ["OpenAPI spec not found: ", specPath] });
828
+ return /* @__PURE__ */ jsx(ApiEndpoint, {
829
+ spec,
830
+ path,
831
+ method
832
+ });
833
+ }
834
+ //#endregion
835
+ //#region source/mdx/components.ts
836
+ function useMDXComponents(components = {}) {
837
+ return {
838
+ ...components,
839
+ ...primitives_exports,
840
+ OpenApiPage,
841
+ ApiEndpoint,
842
+ OpenApiEndpoint,
843
+ ApiEndpointCard,
844
+ DocShell
845
+ };
846
+ }
847
+ //#endregion
848
+ export { ApiEndpoint, ApiEndpointCard, AppShell, BuiltWithClarify, Button, ClarifyConfigContext, Code, CodeGroup, DocShell, Feedback, GridPattern, Heading, HeroPattern, Logo, OpenApiEndpoint, OpenApiPage, OpenApisContext, PageFooter, Pre, Prose, SectionProvider, Tag, ThemeProvider, ThemeToggle, remToPx, render, useClarifyConfig, useMDXComponents, useOpenApis, useSectionStore, useTheme };
849
+
850
+ //# sourceMappingURL=index.js.map