@clarify-labs/renderer 0.1.0 → 0.4.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 (43) hide show
  1. package/output/{AppShell-DBgUlirU.cjs → AppShell-CZw1MrPG.cjs} +1119 -394
  2. package/output/AppShell-CZw1MrPG.cjs.map +1 -0
  3. package/output/{AppShell-C_bj6ZhV.js → AppShell-nQnuKyn2.js} +1098 -397
  4. package/output/AppShell-nQnuKyn2.js.map +1 -0
  5. package/output/client.cjs +1 -1
  6. package/output/client.js +1 -1
  7. package/output/components/Callout.d.ts +10 -0
  8. package/output/components/Card.d.ts +15 -0
  9. package/output/components/PageNavigation.d.ts +5 -0
  10. package/output/components/index.d.ts +5 -0
  11. package/output/context.d.ts +2 -0
  12. package/output/i18n.d.ts +5 -0
  13. package/output/index.cjs +1357 -346
  14. package/output/index.cjs.map +1 -1
  15. package/output/index.d.ts +2 -2
  16. package/output/index.js +1355 -347
  17. package/output/index.js.map +1 -1
  18. package/output/mdx/components.d.ts +3 -0
  19. package/output/mdx/primitives.d.ts +2 -2
  20. package/output/openapi/example-panels.d.ts +31 -0
  21. package/output/openapi/helpers.d.ts +24 -0
  22. package/output/openapi/index.d.ts +2 -19
  23. package/output/openapi/openapi-page.d.ts +19 -0
  24. package/output/openapi/request-code.d.ts +16 -0
  25. package/output/openapi/schema-properties.d.ts +15 -0
  26. package/output/openapi/spec-path.d.ts +2 -0
  27. package/output/openapi/types.d.ts +66 -0
  28. package/output/{render-Ca4Is683.js → render-BCiQn6Q1.js} +2 -2
  29. package/output/{render-Ca4Is683.js.map → render-BCiQn6Q1.js.map} +1 -1
  30. package/output/{render-CLI-MnH_.cjs → render-CZsdzmme.cjs} +2 -2
  31. package/output/{render-CLI-MnH_.cjs.map → render-CZsdzmme.cjs.map} +1 -1
  32. package/output/renderer.css +1636 -551
  33. package/output/server.cjs +1 -1
  34. package/output/server.js +1 -1
  35. package/output/shell/ContentActions.d.ts +1 -0
  36. package/output/shell/Header.d.ts +4 -3
  37. package/output/shell/icons.d.ts +4 -0
  38. package/output/shell/mobile.d.ts +2 -1
  39. package/output/types.d.ts +62 -9
  40. package/output/utils/path.d.ts +2 -0
  41. package/package.json +7 -1
  42. package/output/AppShell-C_bj6ZhV.js.map +0 -1
  43. package/output/AppShell-DBgUlirU.cjs.map +0 -1
package/output/index.js CHANGED
@@ -1,12 +1,13 @@
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";
1
+ import { A as remToPx, C as useBuiltInText, D as useOpenApis, E as useClarifyConfig, O as SectionProvider, S as BuiltWithClarify, T as OpenApisContext, _ as CodeGroup, a as Heading, b as CardGroup, c as Tag, d as useTheme, f as PageFooter, g as Code, h as Feedback, i as DocShell, k as useSectionStore, l as ThemeToggle, m as HeroPattern, n as ApiEndpointCard, o as Logo, p as GridPattern, r as Button, s as Prose, t as AppShell, u as ThemeProvider, v as Pre, w as ClarifyConfigContext, x as Callout, y as Card } from "./AppShell-nQnuKyn2.js";
2
+ import { t as render } from "./render-BCiQn6Q1.js";
3
+ import clsx from "clsx";
4
+ import { createElement, useState } from "react";
4
5
  import { Link, useLocation } from "react-router-dom";
5
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
- import clsx from "clsx";
7
+ import { CheckIcon, ChevronDown, ChevronDownIcon, ChevronRight, ChevronsUpDownIcon, ClipboardIcon, CodeIcon, LockKeyholeIcon, PackageIcon, ServerIcon, UnlockKeyholeIcon } from "lucide-react";
7
8
  import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
8
- import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
9
9
  import { slug } from "github-slugger";
10
+ import { snippetz } from "@scalar/snippetz";
10
11
  //#region \0rolldown/runtime.js
11
12
  var __defProp = Object.defineProperty;
12
13
  var __exportAll = (all, no_symbols) => {
@@ -22,6 +23,9 @@ var __exportAll = (all, no_symbols) => {
22
23
  //#region source/mdx/primitives.tsx
23
24
  var primitives_exports = /* @__PURE__ */ __exportAll({
24
25
  Button: () => Button,
26
+ Callout: () => Callout,
27
+ Card: () => Card,
28
+ CardGroup: () => CardGroup,
25
29
  CodeGroup: () => CodeGroup,
26
30
  Col: () => Col,
27
31
  Note: () => Note,
@@ -37,12 +41,12 @@ var primitives_exports = /* @__PURE__ */ __exportAll({
37
41
  });
38
42
  function wrapper(arg0) {
39
43
  const { children } = arg0;
40
- return /* @__PURE__ */ jsxs("article", {
44
+ return /* @__PURE__ */ jsx("article", {
41
45
  className: "clarify-mdx-page flex h-full flex-col pt-16 pb-10",
42
- children: [/* @__PURE__ */ jsx(Prose, {
46
+ children: /* @__PURE__ */ jsx(Prose, {
43
47
  className: "flex-auto",
44
48
  children
45
- }), /* @__PURE__ */ jsx(PageFooter, {})]
49
+ })
46
50
  });
47
51
  }
48
52
  function a(arg0) {
@@ -101,8 +105,8 @@ function InfoIcon(props) {
101
105
  function Note(arg0) {
102
106
  const { children } = arg0;
103
107
  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", {
108
+ className: "clarify-note my-6 flex gap-2.5 rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-ui-accent-border) bg-(--clarify-ui-accent-background) p-4 text-sm/6 text-(--clarify-theme-tokens-colors-foreground) dark:text-zinc-100 dark:[--tw-prose-links-hover:var(--clarify-ui-accent-text)] dark:[--tw-prose-links:var(--color-white)]",
109
+ children: [/* @__PURE__ */ jsx(InfoIcon, { className: "mt-1 h-4 w-4 flex-none fill-(--clarify-ui-accent-text) stroke-(--clarify-theme-tokens-colors-surface) dark:fill-(--clarify-ui-accent-background) dark:stroke-(--clarify-ui-accent-text)" }), /* @__PURE__ */ jsx("div", {
106
110
  className: "*:first:mt-0 *:last:mb-0",
107
111
  children
108
112
  })]
@@ -111,7 +115,7 @@ function Note(arg0) {
111
115
  function Row(arg0) {
112
116
  const { children } = arg0;
113
117
  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",
118
+ className: "clarify-row grid grid-cols-1 items-start gap-x-8 gap-y-10 xl:max-w-none xl:grid-cols-2",
115
119
  children
116
120
  });
117
121
  }
@@ -144,12 +148,15 @@ function Property(arg0) {
144
148
  className: "sr-only",
145
149
  children: "Name"
146
150
  }),
147
- /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { children: name }) }),
151
+ /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("span", {
152
+ className: "text-sm/5 font-semibold text-zinc-950 dark:text-white",
153
+ children: name
154
+ }) }),
148
155
  type ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("dt", {
149
156
  className: "sr-only",
150
157
  children: "Type"
151
158
  }), /* @__PURE__ */ jsx("dd", {
152
- className: "font-mono text-xs text-zinc-400 dark:text-zinc-500",
159
+ className: "font-mono text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-500",
153
160
  children: type
154
161
  })] }) : null,
155
162
  /* @__PURE__ */ jsx("dt", {
@@ -165,43 +172,7 @@ function Property(arg0) {
165
172
  });
166
173
  }
167
174
  //#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/";
175
+ //#region source/openapi/helpers.ts
205
176
  function isRecord(value) {
206
177
  return typeof value === "object" && value !== null && !Array.isArray(value);
207
178
  }
@@ -211,6 +182,16 @@ function isReference(value) {
211
182
  function resolveReferenceName(ref) {
212
183
  return ref.split("/").filter(Boolean).at(-1) ?? ref;
213
184
  }
185
+ function resolveOpenApiRef(spec, ref) {
186
+ if (!ref.startsWith("#/")) return void 0;
187
+ return ref.slice(2).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~")).reduce((current, part) => isRecord(current) ? current[part] : void 0, spec);
188
+ }
189
+ function resolveSchema(spec, schema, seen = /* @__PURE__ */ new Set()) {
190
+ if (!isReference(schema)) return schema;
191
+ if (seen.has(schema.$ref)) return schema;
192
+ seen.add(schema.$ref);
193
+ return resolveSchema(spec, resolveOpenApiRef(spec, schema.$ref), seen) ?? schema;
194
+ }
214
195
  function getPathItem(spec, path) {
215
196
  const pathItem = spec.paths?.[path];
216
197
  return isRecord(pathItem) ? pathItem : void 0;
@@ -220,7 +201,7 @@ function getOperationParameters(spec, path, operation) {
220
201
  const operationParameters = operation.parameters;
221
202
  return [...Array.isArray(pathParameters) ? pathParameters : [], ...Array.isArray(operationParameters) ? operationParameters : []].filter((parameter) => isRecord(parameter) && !isReference(parameter));
222
203
  }
223
- function getRequestBody(operation) {
204
+ function getRequestBody$1(operation) {
224
205
  const requestBody = operation.requestBody;
225
206
  return isRecord(requestBody) && !isReference(requestBody) ? requestBody : void 0;
226
207
  }
@@ -276,7 +257,7 @@ function getExampleEntries(mediaType) {
276
257
  const generated = schemaToExample(mediaType.schema);
277
258
  return typeof generated === "undefined" ? [] : [{
278
259
  key: "schema",
279
- title: "Schema example",
260
+ title: "schema",
280
261
  value: generated,
281
262
  generated: true
282
263
  }];
@@ -287,11 +268,14 @@ function getContentExample(mediaType) {
287
268
  function schemaToType(schema) {
288
269
  if (!isRecord(schema)) return void 0;
289
270
  if (isReference(schema)) return resolveReferenceName(schema.$ref);
271
+ if (typeof schema.const !== "undefined") return JSON.stringify(schema.const);
290
272
  if (Array.isArray(schema.enum)) return schema.enum.map(String).join(" | ");
291
273
  const oneOf = schema.oneOf ?? schema.anyOf;
292
274
  if (Array.isArray(oneOf)) return oneOf.map(schemaToType).filter(Boolean).join(" | ");
275
+ if (Array.isArray(schema.allOf)) return schema.allOf.map(schemaToType).filter(Boolean).join(" & ");
293
276
  if (schema.type === "array") return `${schemaToType(schema.items) ?? "unknown"}[]`;
294
- return typeof schema.type === "string" ? schema.type : void 0;
277
+ const type = Array.isArray(schema.type) ? schema.type.map(String).join(" | ") : schema.type;
278
+ return typeof type === "string" ? [type, typeof schema.format === "string" ? `<${schema.format}>` : void 0].filter(Boolean).join("") : void 0;
295
279
  }
296
280
  function schemaToExample(schema, depth = 0) {
297
281
  if (!isRecord(schema) || depth > 3) return void 0;
@@ -319,33 +303,6 @@ function stringifyExample(value) {
319
303
  if (typeof value === "string") return value;
320
304
  return JSON.stringify(value, null, 2);
321
305
  }
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
306
  function getResponseEntries(operation) {
350
307
  const responses = operation.responses;
351
308
  if (!isRecord(responses)) return [];
@@ -354,45 +311,6 @@ function getResponseEntries(operation) {
354
311
  response
355
312
  }));
356
313
  }
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
314
  function codeLanguageForMediaType(mediaType) {
397
315
  if (!mediaType) return "json";
398
316
  if (mediaType.includes("json")) return "json";
@@ -401,112 +319,523 @@ function codeLanguageForMediaType(mediaType) {
401
319
  if (mediaType.includes("xml")) return "xml";
402
320
  return "text";
403
321
  }
322
+ //#endregion
323
+ //#region source/openapi/request-code.ts
324
+ var snippetGenerator = snippetz();
325
+ function getDefaultServer(spec) {
326
+ const servers = spec.servers;
327
+ if (!Array.isArray(servers)) return { url: "https://api.example.com" };
328
+ const firstServer = servers.find(isRecord);
329
+ return firstServer && typeof firstServer.url === "string" ? firstServer : { url: "https://api.example.com" };
330
+ }
331
+ function expandServerUrl(server, serverVariables = {}) {
332
+ return (server.url ?? "https://api.example.com").replace(/\{([^}]+)\}/g, (_, name) => {
333
+ const fallback = server.variables?.[name]?.default ?? name;
334
+ return serverVariables[name] ?? fallback;
335
+ });
336
+ }
337
+ function buildOperationUrl(input) {
338
+ return `${expandServerUrl(input.server ?? getDefaultServer(input.spec), input.serverVariables).replace(/\/$/, "")}${input.path}`;
339
+ }
340
+ function getQueryString(parameters, auth) {
341
+ const queryString = parameters.filter((parameter) => parameter.in === "query" && parameter.name).map((parameter) => ({
342
+ name: parameter.name,
343
+ value: encodeUrlPlaceholders(`{${parameter.name}}`)
344
+ }));
345
+ if (auth?.scheme.type === "apiKey" && auth.scheme.in === "query" && auth.scheme.name) queryString.push({
346
+ name: auth.scheme.name,
347
+ value: auth.value
348
+ });
349
+ return queryString;
350
+ }
351
+ function isFormMediaType(mediaType) {
352
+ return mediaType.includes("multipart/form-data") || mediaType.includes("application/x-www-form-urlencoded");
353
+ }
354
+ function isBinarySchema(schema) {
355
+ return isRecord(schema) && schema.type === "string" && schema.format === "binary";
356
+ }
357
+ function getSchemaProperties(schema) {
358
+ return isRecord(schema) && isRecord(schema.properties) ? schema.properties : {};
359
+ }
360
+ function getFieldValue(name, value, schema) {
361
+ if (isRecord(value) && typeof value[name] !== "undefined") return value[name];
362
+ if (isBinarySchema(schema)) return `@${name}`;
363
+ }
364
+ function getFormParams(value, requestContent) {
365
+ const properties = getSchemaProperties(requestContent.value.schema);
366
+ return Array.from(new Set([...Object.keys(properties), ...isRecord(value) ? Object.keys(value) : []])).flatMap((name) => {
367
+ const fieldValue = getFieldValue(name, value, properties[name]);
368
+ if (typeof fieldValue === "undefined") return [];
369
+ const contentType = requestContent.value.encoding?.[name]?.contentType;
370
+ return [{
371
+ name,
372
+ value: typeof fieldValue === "string" ? fieldValue : stringifyExample(fieldValue),
373
+ ...contentType ? { contentType } : {}
374
+ }];
375
+ });
376
+ }
377
+ function getBodySize(requestBody) {
378
+ if (requestBody?.serialized) return requestBody.serialized.length;
379
+ return requestBody?.params?.reduce((size, param) => size + param.name.length + String(param.value ?? "").length, 0) ?? 0;
380
+ }
381
+ function getRequestBody(requestContent) {
382
+ const value = getContentExample(requestContent?.value);
383
+ if (!requestContent || typeof value === "undefined") return void 0;
384
+ if (isFormMediaType(requestContent.mediaType)) {
385
+ const params = getFormParams(value, requestContent);
386
+ return params.length > 0 ? { params } : void 0;
387
+ }
388
+ return { serialized: stringifyExample(value) };
389
+ }
390
+ function getAuthorizationValue(auth) {
391
+ if (auth.scheme.type === "http" && auth.scheme.scheme?.toLowerCase() === "bearer") return `Bearer ${auth.value}`;
392
+ if (auth.scheme.type === "http" && auth.scheme.scheme?.toLowerCase() === "basic") return `Basic ${auth.value}`;
393
+ if (auth.scheme.type === "oauth2" || auth.scheme.type === "openIdConnect") return `Bearer ${auth.value}`;
394
+ }
395
+ function getAuthHeaders(auth) {
396
+ if (!auth) return {};
397
+ if (auth.scheme.type === "apiKey" && auth.scheme.in === "header" && auth.scheme.name) return { [auth.scheme.name]: auth.value };
398
+ const authorization = getAuthorizationValue(auth);
399
+ return authorization ? { Authorization: authorization } : {};
400
+ }
401
+ function getRequestHeaders(requestContent, auth) {
402
+ return {
403
+ ...getAuthHeaders(auth),
404
+ Accept: "application/json",
405
+ ...requestContent ? { "Content-Type": requestContent.mediaType } : {}
406
+ };
407
+ }
408
+ function encodeUrlPlaceholders(url) {
409
+ return url.replace(/\{([^}]+)\}/g, (_, name) => `%7B${encodeURIComponent(name)}%7D`);
410
+ }
411
+ function decodeUrlPlaceholders(code) {
412
+ return code.replace(/%7B([^%]+)%7D/g, (_, name) => `{${decodeURIComponent(name)}}`);
413
+ }
414
+ function buildHarRequest(input) {
415
+ const requestBody = getRequestBody(input.requestContent);
416
+ const url = encodeUrlPlaceholders(buildOperationUrl(input));
417
+ return {
418
+ method: input.method,
419
+ url,
420
+ httpVersion: "HTTP/1.1",
421
+ cookies: [],
422
+ headers: Object.entries(getRequestHeaders(input.requestContent, input.auth)).map(([name, value]) => ({
423
+ name,
424
+ value
425
+ })),
426
+ queryString: getQueryString(input.parameters, input.auth),
427
+ headersSize: -1,
428
+ bodySize: getBodySize(requestBody),
429
+ postData: requestBody ? {
430
+ mimeType: input.requestContent?.mediaType ?? "",
431
+ ...requestBody.serialized ? { text: requestBody.serialized } : {},
432
+ ...requestBody.params ? { params: requestBody.params } : {}
433
+ } : void 0
434
+ };
435
+ }
436
+ function buildSnippet(input, target) {
437
+ return decodeUrlPlaceholders(snippetGenerator.print(target.target, target.client, buildHarRequest(input)) || "");
438
+ }
439
+ var requestSnippetOptions = [
440
+ {
441
+ languageKey: "shell",
442
+ title: "Shell",
443
+ language: "bash",
444
+ target: "shell",
445
+ client: "curl",
446
+ clientTitle: "cURL"
447
+ },
448
+ {
449
+ languageKey: "shell",
450
+ title: "Shell",
451
+ language: "bash",
452
+ target: "shell",
453
+ client: "wget",
454
+ clientTitle: "Wget"
455
+ },
456
+ {
457
+ languageKey: "shell",
458
+ title: "Shell",
459
+ language: "bash",
460
+ target: "shell",
461
+ client: "httpie",
462
+ clientTitle: "HTTPie"
463
+ },
464
+ {
465
+ languageKey: "javascript",
466
+ title: "JavaScript",
467
+ language: "javascript",
468
+ target: "js",
469
+ client: "fetch",
470
+ clientTitle: "Fetch"
471
+ },
472
+ {
473
+ languageKey: "javascript",
474
+ title: "JavaScript",
475
+ language: "javascript",
476
+ target: "js",
477
+ client: "axios",
478
+ clientTitle: "Axios"
479
+ },
480
+ {
481
+ languageKey: "javascript",
482
+ title: "JavaScript",
483
+ language: "javascript",
484
+ target: "js",
485
+ client: "ofetch",
486
+ clientTitle: "ofetch"
487
+ },
488
+ {
489
+ languageKey: "javascript",
490
+ title: "JavaScript",
491
+ language: "javascript",
492
+ target: "js",
493
+ client: "xhr",
494
+ clientTitle: "XHR"
495
+ },
496
+ {
497
+ languageKey: "typescript",
498
+ title: "TypeScript",
499
+ language: "typescript",
500
+ target: "js",
501
+ client: "fetch",
502
+ clientTitle: "Fetch"
503
+ },
504
+ {
505
+ languageKey: "typescript",
506
+ title: "TypeScript",
507
+ language: "typescript",
508
+ target: "js",
509
+ client: "axios",
510
+ clientTitle: "Axios"
511
+ },
512
+ {
513
+ languageKey: "typescript",
514
+ title: "TypeScript",
515
+ language: "typescript",
516
+ target: "js",
517
+ client: "ofetch",
518
+ clientTitle: "ofetch"
519
+ },
520
+ {
521
+ languageKey: "python",
522
+ title: "Python",
523
+ language: "python",
524
+ target: "python",
525
+ client: "requests",
526
+ clientTitle: "Requests"
527
+ },
528
+ {
529
+ languageKey: "python",
530
+ title: "Python",
531
+ language: "python",
532
+ target: "python",
533
+ client: "python3",
534
+ clientTitle: "http.client"
535
+ },
536
+ {
537
+ languageKey: "python",
538
+ title: "Python",
539
+ language: "python",
540
+ target: "python",
541
+ client: "httpx_sync",
542
+ clientTitle: "HTTPX"
543
+ },
544
+ {
545
+ languageKey: "python",
546
+ title: "Python",
547
+ language: "python",
548
+ target: "python",
549
+ client: "aiohttp",
550
+ clientTitle: "aiohttp"
551
+ },
552
+ {
553
+ languageKey: "go",
554
+ title: "Go",
555
+ language: "go",
556
+ target: "go",
557
+ client: "native",
558
+ clientTitle: "NewRequest"
559
+ },
560
+ {
561
+ languageKey: "node",
562
+ title: "Node.js",
563
+ language: "javascript",
564
+ target: "node",
565
+ client: "fetch",
566
+ clientTitle: "Fetch"
567
+ },
568
+ {
569
+ languageKey: "node",
570
+ title: "Node.js",
571
+ language: "javascript",
572
+ target: "node",
573
+ client: "axios",
574
+ clientTitle: "Axios"
575
+ },
576
+ {
577
+ languageKey: "node",
578
+ title: "Node.js",
579
+ language: "javascript",
580
+ target: "node",
581
+ client: "ofetch",
582
+ clientTitle: "ofetch"
583
+ },
584
+ {
585
+ languageKey: "node",
586
+ title: "Node.js",
587
+ language: "javascript",
588
+ target: "node",
589
+ client: "undici",
590
+ clientTitle: "undici"
591
+ },
592
+ {
593
+ languageKey: "java",
594
+ title: "Java",
595
+ language: "java",
596
+ target: "java",
597
+ client: "nethttp",
598
+ clientTitle: "java.net.http"
599
+ },
600
+ {
601
+ languageKey: "java",
602
+ title: "Java",
603
+ language: "java",
604
+ target: "java",
605
+ client: "okhttp",
606
+ clientTitle: "OkHttp"
607
+ },
608
+ {
609
+ languageKey: "java",
610
+ title: "Java",
611
+ language: "java",
612
+ target: "java",
613
+ client: "unirest",
614
+ clientTitle: "Unirest"
615
+ },
616
+ {
617
+ languageKey: "java",
618
+ title: "Java",
619
+ language: "java",
620
+ target: "java",
621
+ client: "asynchttp",
622
+ clientTitle: "AsyncHttp"
623
+ },
624
+ {
625
+ languageKey: "csharp",
626
+ title: "C#",
627
+ language: "csharp",
628
+ target: "csharp",
629
+ client: "httpclient",
630
+ clientTitle: "HttpClient"
631
+ },
632
+ {
633
+ languageKey: "csharp",
634
+ title: "C#",
635
+ language: "csharp",
636
+ target: "csharp",
637
+ client: "restsharp",
638
+ clientTitle: "RestSharp"
639
+ },
640
+ {
641
+ languageKey: "php",
642
+ title: "PHP",
643
+ language: "php",
644
+ target: "php",
645
+ client: "guzzle",
646
+ clientTitle: "Guzzle"
647
+ },
648
+ {
649
+ languageKey: "php",
650
+ title: "PHP",
651
+ language: "php",
652
+ target: "php",
653
+ client: "curl",
654
+ clientTitle: "cURL"
655
+ },
656
+ {
657
+ languageKey: "php",
658
+ title: "PHP",
659
+ language: "php",
660
+ target: "php",
661
+ client: "laravel",
662
+ clientTitle: "Laravel HTTP Client"
663
+ },
664
+ {
665
+ languageKey: "ruby",
666
+ title: "Ruby",
667
+ language: "ruby",
668
+ target: "ruby",
669
+ client: "native",
670
+ clientTitle: "net::http"
671
+ },
672
+ {
673
+ languageKey: "rust",
674
+ title: "Rust",
675
+ language: "rust",
676
+ target: "rust",
677
+ client: "reqwest",
678
+ clientTitle: "reqwest"
679
+ },
680
+ {
681
+ languageKey: "swift",
682
+ title: "Swift",
683
+ language: "swift",
684
+ target: "swift",
685
+ client: "nsurlsession",
686
+ clientTitle: "NSURLSession"
687
+ },
688
+ {
689
+ languageKey: "kotlin",
690
+ title: "Kotlin",
691
+ language: "kotlin",
692
+ target: "kotlin",
693
+ client: "okhttp",
694
+ clientTitle: "OkHttp"
695
+ },
696
+ {
697
+ languageKey: "powershell",
698
+ title: "PowerShell",
699
+ language: "powershell",
700
+ target: "powershell",
701
+ client: "restmethod",
702
+ clientTitle: "Invoke-RestMethod"
703
+ },
704
+ {
705
+ languageKey: "powershell",
706
+ title: "PowerShell",
707
+ language: "powershell",
708
+ target: "powershell",
709
+ client: "webrequest",
710
+ clientTitle: "Invoke-WebRequest"
711
+ }
712
+ ];
713
+ function buildRequestCodeExamples(input) {
714
+ return requestSnippetOptions.map((option) => ({
715
+ key: `${option.languageKey}:${option.client}`,
716
+ title: option.title,
717
+ language: option.language,
718
+ languageKey: option.languageKey,
719
+ clientKey: option.client,
720
+ clientTitle: option.clientTitle,
721
+ code: buildSnippet(input, option)
722
+ }));
723
+ }
724
+ //#endregion
725
+ //#region source/openapi/example-panels.tsx
404
726
  function SelectControl(arg0) {
405
- const { label, value, options, onChange } = arg0;
406
- if (options.length <= 1) return null;
727
+ const { label, value, options, onChange, icon, compact = false } = arg0;
728
+ const normalizedOptions = options.map((option) => typeof option === "string" ? {
729
+ value: option,
730
+ label: option
731
+ } : option);
732
+ const selectedOption = normalizedOptions.find((option) => option.value === value) ?? normalizedOptions[0];
733
+ const wrapperClassName = compact ? "clarify-api-select relative min-w-0 text-xs" : "clarify-api-select relative shrink-0 text-xs";
734
+ const buttonSizeClassName = compact ? "w-full min-w-0 max-w-32" : "min-w-28 max-w-48";
735
+ if (normalizedOptions.length <= 1) return null;
407
736
  return /* @__PURE__ */ jsx(Listbox, {
408
737
  value,
409
738
  onChange,
410
739
  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",
740
+ className: wrapperClassName,
412
741
  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",
742
+ "aria-label": label,
743
+ className: `clarify-api-select-button flex ${buttonSizeClassName} items-center justify-between gap-2 rounded-lg bg-black/30 px-2 py-1 font-mono text-xs font-medium whitespace-nowrap text-zinc-100 outline-hidden transition hover:bg-black/50 focus:ring-2 focus:ring-emerald-400/25 data-open:bg-white/10 data-open:ring-2 data-open:ring-emerald-400/25`,
414
744
  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", {
745
+ className: "flex min-w-0 items-center gap-1.5 overflow-hidden",
746
+ children: [icon ? /* @__PURE__ */ jsx("span", {
747
+ className: "shrink-0 text-zinc-500",
748
+ children: icon
749
+ }) : null, /* @__PURE__ */ jsx("span", {
420
750
  className: "truncate",
421
- children: value
751
+ children: selectedOption?.label ?? value
422
752
  })]
423
753
  }), /* @__PURE__ */ jsx(ChevronsUpDownIcon, {
424
754
  className: "h-3.5 w-3.5 shrink-0 text-zinc-500",
425
755
  "aria-hidden": "true"
426
756
  })]
427
757
  }), /* @__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, {
758
+ anchor: "bottom end",
759
+ className: "clarify-api-select-options z-30 mt-1 max-h-64 w-max min-w-(--button-width) max-w-[min(32rem,calc(100vw-2rem))] overflow-auto rounded-xl bg-zinc-900 p-1 text-xs shadow-lg shadow-black/20 ring-1 ring-white/10 [--anchor-gap:--spacing(1)] focus:outline-none",
760
+ children: normalizedOptions.map((option) => /* @__PURE__ */ jsxs(ListboxOption, {
761
+ value: option.value,
762
+ 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 whitespace-nowrap text-zinc-300 select-none data-focus:bg-white/10 data-focus:text-white data-selected:text-emerald-300",
763
+ children: [/* @__PURE__ */ jsx("span", { children: option.label }), /* @__PURE__ */ jsx(CheckIcon, {
437
764
  className: "h-3.5 w-3.5 shrink-0 opacity-0 group-data-selected:opacity-100",
438
765
  "aria-hidden": "true"
439
766
  })]
440
- }, option))
767
+ }, option.value))
441
768
  })]
442
769
  })
443
770
  });
444
771
  }
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
- });
772
+ function getExampleLabel(example, t) {
773
+ return example.generated && example.title === "schema" ? t("openapi.schemaExample") : example.title;
774
+ }
775
+ function getLanguageOptions(codeOptions) {
776
+ const languages = /* @__PURE__ */ new Map();
777
+ for (const option of codeOptions ?? []) languages.set(option.languageKey, option.title);
778
+ return Array.from(languages, ([value, label]) => ({
779
+ value,
780
+ label
781
+ }));
782
+ }
783
+ function getClientOptions(codeOptions, languageKey) {
784
+ return (codeOptions ?? []).filter((option) => option.languageKey === languageKey).map((option) => ({
785
+ value: option.clientKey,
786
+ label: option.clientTitle
787
+ }));
788
+ }
789
+ function getServers(spec, operation) {
790
+ const operationServers = operation.servers;
791
+ const servers = Array.isArray(operationServers) ? operationServers : spec.servers;
792
+ if (!Array.isArray(servers)) return [{ url: "https://api.example.com" }];
793
+ const validServers = servers.filter((server) => isRecord(server) && typeof server.url === "string");
794
+ return validServers.length > 0 ? validServers : [{ url: "https://api.example.com" }];
795
+ }
796
+ function getServerKey(server, index) {
797
+ return `${index}:${server.url ?? ""}`;
798
+ }
799
+ function getServerLabel(server, index) {
800
+ return server.description ? `${server.description} (${server.url})` : server.url ?? `Server ${index + 1}`;
801
+ }
802
+ function defaultServerVariables(server) {
803
+ return Object.fromEntries(Object.entries(server?.variables ?? {}).map(([name, variable]) => [name, variable.default ?? variable.enum?.[0] ?? ""]));
804
+ }
805
+ function getSecuritySchemes(spec) {
806
+ const schemes = spec.components;
807
+ if (!isRecord(schemes) || !isRecord(schemes.securitySchemes)) return {};
808
+ return Object.fromEntries(Object.entries(schemes.securitySchemes).filter((entry) => isRecord(entry[1])));
809
+ }
810
+ function getSecurityRequirements(spec, operation) {
811
+ const operationSecurity = operation.security;
812
+ if (Array.isArray(operationSecurity)) return operationSecurity.filter(isRecord);
813
+ const specSecurity = spec.security;
814
+ return Array.isArray(specSecurity) ? specSecurity.filter(isRecord) : [];
815
+ }
816
+ function getAuthOptions(spec, operation) {
817
+ const schemes = getSecuritySchemes(spec);
818
+ const requirements = getSecurityRequirements(spec, operation);
819
+ const names = new Set(requirements.flatMap((requirement) => Object.keys(requirement)));
820
+ return Array.from(names).map((name) => ({
821
+ name,
822
+ scheme: schemes[name]
823
+ })).filter((option) => Boolean(option.scheme));
824
+ }
825
+ function authPlaceholder(auth) {
826
+ if (!auth) return "";
827
+ if (auth.scheme.type === "apiKey") return "{api_key}";
828
+ if (auth.scheme.type === "http" && auth.scheme.scheme?.toLowerCase() === "basic") return "{base64_credentials}";
829
+ return "{token}";
830
+ }
831
+ function authLabel(name, scheme) {
832
+ return `${name}${scheme.type === "apiKey" && scheme.in && scheme.name ? ` · ${scheme.in}: ${scheme.name}` : ""}`;
505
833
  }
506
834
  function CopyCodeButton(arg0) {
507
835
  const { code } = arg0;
836
+ const t = useBuiltInText();
508
837
  const [copied, setCopied] = useState(false);
509
- return /* @__PURE__ */ jsx("button", {
838
+ return /* @__PURE__ */ jsxs("button", {
510
839
  type: "button",
511
840
  onClick: () => {
512
841
  window.navigator.clipboard.writeText(code).then(() => {
@@ -514,64 +843,144 @@ function CopyCodeButton(arg0) {
514
843
  window.setTimeout(() => setCopied(false), 1e3);
515
844
  });
516
845
  },
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"
846
+ className: "flex items-center gap-1.5 rounded-full bg-black/ px-2.5 py-1.5 text-2xs font-medium text-zinc-400 transition hover:bg-black/50 hover:text-zinc-200 focus:bg-black/50 focus:text-zinc-200",
847
+ children: [copied ? /* @__PURE__ */ jsx(CheckIcon, {
848
+ className: "h-3.5 w-3.5 text-emerald-300",
849
+ "aria-hidden": "true"
850
+ }) : /* @__PURE__ */ jsx(ClipboardIcon, {
851
+ className: "h-3.5 w-3.5 text-zinc-500",
852
+ "aria-hidden": "true"
853
+ }), /* @__PURE__ */ jsx("span", { children: copied ? t("actions.copied") : t("actions.copy") })]
854
+ });
855
+ }
856
+ function ExampleMetaValue(arg0) {
857
+ const { label, value, options, onChange, className } = arg0;
858
+ if (options && options.length > 1 && onChange) return /* @__PURE__ */ jsx(SelectControl, {
859
+ label,
860
+ value,
861
+ options,
862
+ onChange
863
+ });
864
+ return /* @__PURE__ */ jsx("span", {
865
+ className,
866
+ children: value
867
+ });
868
+ }
869
+ function CodeToolbar(arg0) {
870
+ const { code, languageOptions, selectedLanguageKey, onSelectLanguage, clientOptions, selectedClientKey, onSelectClient } = arg0;
871
+ const t = useBuiltInText();
872
+ return /* @__PURE__ */ jsxs("div", {
873
+ className: "absolute top-3.5 right-4 left-4 z-10 flex items-center justify-between gap-3",
874
+ children: [/* @__PURE__ */ jsxs("div", {
875
+ className: "flex min-w-0 items-center gap-2",
876
+ children: [languageOptions && languageOptions.length > 1 && selectedLanguageKey && onSelectLanguage ? /* @__PURE__ */ jsx(SelectControl, {
877
+ label: t("openapi.language"),
878
+ value: selectedLanguageKey,
879
+ options: languageOptions,
880
+ onChange: onSelectLanguage,
881
+ icon: /* @__PURE__ */ jsx(CodeIcon, {
882
+ className: "h-3.5 w-3.5",
883
+ "aria-hidden": "true"
884
+ })
885
+ }) : null, clientOptions && clientOptions.length > 1 && selectedClientKey && onSelectClient ? /* @__PURE__ */ jsx(SelectControl, {
886
+ label: t("openapi.client"),
887
+ value: selectedClientKey,
888
+ options: clientOptions,
889
+ onChange: onSelectClient,
890
+ icon: /* @__PURE__ */ jsx(PackageIcon, {
891
+ className: "h-3.5 w-3.5",
892
+ "aria-hidden": "true"
893
+ })
894
+ }) : null]
895
+ }), /* @__PURE__ */ jsx(CopyCodeButton, { code })]
519
896
  });
520
897
  }
521
898
  function ApiExampleCodeGroup(arg0) {
522
- const { title, tag, label, code, language, examples, selectedExampleKey, onSelectExample } = arg0;
899
+ const { title, tag, tagOptions, onSelectTag, label, labelOptions, onSelectLabel, comfortableMeta = false, code, language, mediaTypes, selectedMediaType, onSelectMediaType, examples, selectedExampleKey, onSelectExample, languageOptions, selectedLanguageKey, onSelectLanguage, clientOptions, selectedClientKey, onSelectClient } = arg0;
900
+ const t = useBuiltInText();
901
+ const metaClassName = comfortableMeta ? "flex min-h-11 min-w-0 items-center gap-2 border-y border-t-transparent border-b-white/7.5 bg-zinc-900 px-4 py-2 dark:border-b-white/5 dark:bg-white/1" : "flex h-9 min-w-0 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";
523
902
  return /* @__PURE__ */ jsx("div", {
524
903
  className: "clarify-api-example my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10",
525
904
  children: /* @__PURE__ */ jsxs("div", {
526
905
  className: "not-prose",
527
906
  children: [
528
907
  /* @__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",
908
+ className: "clarify-api-example-header flex min-h-[calc(--spacing(12)+1px)] items-center gap-3 border-b border-zinc-700 bg-zinc-800 px-4 py-2 dark:border-zinc-800 dark:bg-transparent",
530
909
  children: [/* @__PURE__ */ jsx("h3", {
531
- className: "shrink-0 py-3 text-xs font-semibold text-white",
910
+ className: "mr-auto min-w-16 truncate py-1 text-xs font-semibold text-white",
532
911
  children: title
533
- }), examples && examples.length > 1 && selectedExampleKey && onSelectExample ? /* @__PURE__ */ jsx(ExamplePicker, {
534
- examples,
535
- selectedKey: selectedExampleKey,
536
- onSelect: onSelectExample
537
- }) : null]
912
+ }), /* @__PURE__ */ jsxs("div", {
913
+ className: "ml-auto flex min-w-0 items-center gap-2 whitespace-nowrap",
914
+ children: [mediaTypes && mediaTypes.length > 1 && selectedMediaType && onSelectMediaType ? /* @__PURE__ */ jsx(SelectControl, {
915
+ label: t("openapi.mediaType"),
916
+ value: selectedMediaType,
917
+ options: mediaTypes,
918
+ onChange: onSelectMediaType,
919
+ compact: true
920
+ }) : null, examples && examples.length > 1 && selectedExampleKey && onSelectExample ? /* @__PURE__ */ jsx(SelectControl, {
921
+ label: t("openapi.example"),
922
+ value: selectedExampleKey,
923
+ options: examples.map((example) => ({
924
+ value: example.key,
925
+ label: getExampleLabel(example, t)
926
+ })),
927
+ onChange: onSelectExample,
928
+ compact: true
929
+ }) : null]
930
+ })]
538
931
  }),
539
932
  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",
933
+ className: metaClassName,
541
934
  children: [
542
- tag ? /* @__PURE__ */ jsx("span", {
543
- className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400",
544
- children: tag
935
+ tag ? /* @__PURE__ */ jsx(ExampleMetaValue, {
936
+ label: t("openapi.status"),
937
+ value: tag,
938
+ options: tagOptions,
939
+ onChange: onSelectTag,
940
+ className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400"
545
941
  }) : 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
942
+ tag && label ? /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 shrink-0 rounded-full bg-zinc-500" }) : null,
943
+ label ? /* @__PURE__ */ jsx(ExampleMetaValue, {
944
+ label: t("openapi.mediaType"),
945
+ value: label,
946
+ options: labelOptions,
947
+ onChange: onSelectLabel,
948
+ className: "min-w-0 truncate font-mono text-xs text-zinc-400"
550
949
  }) : null
551
950
  ]
552
951
  }) : null,
553
952
  /* @__PURE__ */ jsxs("div", {
554
953
  className: "clarify-api-example-code group relative",
555
- children: [/* @__PURE__ */ jsx("pre", {
556
- className: "overflow-x-auto p-4 text-xs text-white",
954
+ children: [/* @__PURE__ */ jsx(CodeToolbar, {
955
+ code,
956
+ languageOptions,
957
+ selectedLanguageKey,
958
+ onSelectLanguage,
959
+ clientOptions,
960
+ selectedClientKey,
961
+ onSelectClient
962
+ }), /* @__PURE__ */ jsx("pre", {
963
+ className: `overflow-x-auto p-4 text-xs text-white ${languageOptions && languageOptions.length > 1 ? "pt-14" : ""}`,
557
964
  children: /* @__PURE__ */ jsx("code", {
558
965
  className: `language-${language}`,
559
966
  children: code
560
967
  })
561
- }), /* @__PURE__ */ jsx(CopyCodeButton, { code })]
968
+ })]
562
969
  })
563
970
  ]
564
971
  })
565
972
  });
566
973
  }
567
974
  function RequestExamplesPanel(arg0) {
568
- const { spec, path, method, parameters, requestContents } = arg0;
569
- const [selectedMediaType, setSelectedMediaType] = useState(requestContents[0]?.mediaType ?? "");
975
+ const { spec, path, method, parameters, requestContents, selectedMediaType, onSelectMediaType, selectedServer, serverVariables, auth } = arg0;
976
+ const t = useBuiltInText();
570
977
  const selectedContent = requestContents.find((content) => content.mediaType === selectedMediaType) ?? requestContents[0];
571
978
  const examples = getExampleEntries(selectedContent?.value);
572
979
  const [selectedExampleKey, setSelectedExampleKey] = useState(examples[0]?.key ?? "");
980
+ const [selectedLanguageKey, setSelectedLanguageKey] = useState("shell");
981
+ const [selectedClientKey, setSelectedClientKey] = useState("curl");
573
982
  const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
574
- const curl = buildCurlExample({
983
+ const codeOptions = buildRequestCodeExamples({
575
984
  spec,
576
985
  path,
577
986
  method,
@@ -583,32 +992,45 @@ function RequestExamplesPanel(arg0) {
583
992
  example: selectedExample?.value,
584
993
  examples: void 0
585
994
  }
586
- } : void 0
995
+ } : void 0,
996
+ server: selectedServer,
997
+ serverVariables,
998
+ auth
587
999
  });
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",
1000
+ const selectedLanguage = codeOptions.find((option) => option.languageKey === selectedLanguageKey) ?? codeOptions[0];
1001
+ const selectedCode = codeOptions.find((option) => option.languageKey === selectedLanguage.languageKey && option.clientKey === selectedClientKey) ?? selectedLanguage;
1002
+ const languageOptions = getLanguageOptions(codeOptions);
1003
+ const clientOptions = getClientOptions(codeOptions, selectedCode.languageKey);
1004
+ return /* @__PURE__ */ jsx(ApiExampleCodeGroup, {
1005
+ title: t("openapi.request"),
601
1006
  tag: method,
602
1007
  label: path,
603
- code: curl,
604
- language: "bash",
1008
+ code: selectedCode.code,
1009
+ language: selectedCode.language,
1010
+ mediaTypes: requestContents.map((content) => content.mediaType),
1011
+ selectedMediaType: selectedContent?.mediaType,
1012
+ onSelectMediaType: (value) => {
1013
+ onSelectMediaType(value);
1014
+ setSelectedExampleKey(getExampleEntries(requestContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
1015
+ },
605
1016
  examples,
606
1017
  selectedExampleKey: selectedExample?.key,
607
- onSelectExample: setSelectedExampleKey
608
- })] });
1018
+ onSelectExample: setSelectedExampleKey,
1019
+ languageOptions,
1020
+ selectedLanguageKey: selectedCode.languageKey,
1021
+ onSelectLanguage: (value) => {
1022
+ const nextCode = codeOptions.find((option) => option.languageKey === value);
1023
+ setSelectedLanguageKey(nextCode?.languageKey ?? value);
1024
+ setSelectedClientKey(nextCode?.clientKey ?? "");
1025
+ },
1026
+ clientOptions,
1027
+ selectedClientKey: selectedCode.clientKey,
1028
+ onSelectClient: setSelectedClientKey
1029
+ });
609
1030
  }
610
1031
  function ResponseExamplesPanel(arg0) {
611
1032
  const { operation } = arg0;
1033
+ const t = useBuiltInText();
612
1034
  const responses = getResponseEntries(operation).filter(({ response }) => getMediaTypeEntries(response.content).length > 0);
613
1035
  const [selectedStatus, setSelectedStatus] = useState(responses.find(({ status }) => status.startsWith("2"))?.status ?? responses[0]?.status ?? "");
614
1036
  const selectedResponse = responses.find(({ status }) => status === selectedStatus) ?? responses[0];
@@ -620,40 +1042,328 @@ function ResponseExamplesPanel(arg0) {
620
1042
  const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
621
1043
  const responseCode = stringifyExample(selectedExample?.value);
622
1044
  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",
1045
+ return /* @__PURE__ */ jsx(ApiExampleCodeGroup, {
1046
+ title: t("openapi.response"),
646
1047
  tag: selectedResponse.status,
1048
+ tagOptions: responses.map(({ status }) => status),
1049
+ onSelectTag: (value) => {
1050
+ const nextContents = getMediaTypeEntries(responses.find(({ status }) => status === value)?.response.content);
1051
+ setSelectedStatus(value);
1052
+ setSelectedMediaType(nextContents[0]?.mediaType ?? "");
1053
+ setSelectedExampleKey(getExampleEntries(nextContents[0]?.value)[0]?.key ?? "");
1054
+ },
647
1055
  label: selectedContent.mediaType,
1056
+ labelOptions: responseContents.map((content) => content.mediaType),
1057
+ onSelectLabel: (value) => {
1058
+ setSelectedMediaType(value);
1059
+ setSelectedExampleKey(getExampleEntries(responseContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
1060
+ },
1061
+ comfortableMeta: true,
648
1062
  code: responseCode,
649
1063
  language: codeLanguageForMediaType(selectedContent.mediaType),
650
1064
  examples,
651
1065
  selectedExampleKey: selectedExample?.key,
652
1066
  onSelectExample: setSelectedExampleKey
1067
+ });
1068
+ }
1069
+ //#endregion
1070
+ //#region source/openapi/schema-properties.tsx
1071
+ function getSchemaDescription(schema) {
1072
+ const details = [
1073
+ Array.isArray(schema.enum) ? `enum: ${schema.enum.map(String).join(", ")}` : void 0,
1074
+ typeof schema.const !== "undefined" ? `const: ${String(schema.const)}` : void 0,
1075
+ typeof schema.default !== "undefined" ? `default: ${String(schema.default)}` : void 0,
1076
+ typeof schema.pattern === "string" ? `pattern: ${schema.pattern}` : void 0,
1077
+ typeof schema.minimum === "number" ? `minimum: ${String(schema.minimum)}` : void 0,
1078
+ typeof schema.maximum === "number" ? `maximum: ${String(schema.maximum)}` : void 0,
1079
+ typeof schema.additionalProperties === "boolean" ? `additionalProperties: ${String(schema.additionalProperties)}` : void 0
1080
+ ].filter(Boolean);
1081
+ return [typeof schema.description === "string" ? schema.description : void 0, details.length > 0 ? details.join("; ") : void 0].filter(Boolean).join(" ");
1082
+ }
1083
+ function getComposedBranches(schema) {
1084
+ const entries = [];
1085
+ for (const key of [
1086
+ "allOf",
1087
+ "oneOf",
1088
+ "anyOf"
1089
+ ]) {
1090
+ const items = schema[key];
1091
+ if (!Array.isArray(items)) continue;
1092
+ for (const [index, item] of items.entries()) entries.push({
1093
+ label: `${key}[${index}]`,
1094
+ schema: item
1095
+ });
1096
+ }
1097
+ return entries;
1098
+ }
1099
+ function getSchemaChildren(arg0) {
1100
+ const { spec, schema, path, required = [], depth = 0, seen = /* @__PURE__ */ new Set() } = arg0;
1101
+ if (depth > 12) return [];
1102
+ if (isReference(schema)) {
1103
+ if (seen.has(schema.$ref)) return [];
1104
+ return getSchemaChildren({
1105
+ spec,
1106
+ schema: resolveSchema(spec, schema),
1107
+ path,
1108
+ required,
1109
+ depth,
1110
+ seen: new Set([...seen, schema.$ref])
1111
+ });
1112
+ }
1113
+ if (!isRecord(schema)) return [];
1114
+ const arrayChildren = schema.type === "array" ? getSchemaChildren({
1115
+ spec,
1116
+ schema: schema.items,
1117
+ path: `${path}[]`,
1118
+ depth: depth + 1,
1119
+ seen
1120
+ }) : [];
1121
+ const objectRequired = Array.isArray(schema.required) ? schema.required.map(String) : required;
1122
+ const properties = isRecord(schema.properties) ? schema.properties : {};
1123
+ const propertyChildren = Object.entries(properties).map(([name, propertySchema]) => {
1124
+ const resolvedProperty = resolveSchema(spec, propertySchema);
1125
+ const property = isRecord(resolvedProperty) ? resolvedProperty : isRecord(propertySchema) ? propertySchema : {};
1126
+ const isArray = isRecord(property) && property.type === "array";
1127
+ const childPath = path ? `${path}.${name}` : name;
1128
+ const children = getSchemaChildren({
1129
+ spec,
1130
+ schema: isArray ? property.items : propertySchema,
1131
+ path: isArray ? `${childPath}[]` : childPath,
1132
+ depth: depth + 1,
1133
+ seen
1134
+ });
1135
+ return {
1136
+ key: childPath,
1137
+ name,
1138
+ type: schemaToType(propertySchema),
1139
+ description: getSchemaDescription(property),
1140
+ required: objectRequired.includes(name),
1141
+ children
1142
+ };
1143
+ });
1144
+ const additionalPropertyChildren = isRecord(schema.additionalProperties) ? [{
1145
+ key: `${path || "root"}.*`,
1146
+ name: "*",
1147
+ type: schemaToType(schema.additionalProperties),
1148
+ description: getSchemaDescription(schema.additionalProperties),
1149
+ required: false,
1150
+ children: getSchemaChildren({
1151
+ spec,
1152
+ schema: schema.additionalProperties,
1153
+ path: `${path || "root"}.*`,
1154
+ depth: depth + 1,
1155
+ seen
1156
+ })
1157
+ }] : [];
1158
+ const composedChildren = getComposedBranches(schema).map(({ label, schema: branchSchema }) => ({
1159
+ key: `${path || "root"}.${label}`,
1160
+ name: label,
1161
+ type: schemaToType(branchSchema),
1162
+ description: isRecord(resolveSchema(spec, branchSchema)) ? getSchemaDescription(resolveSchema(spec, branchSchema)) : void 0,
1163
+ required: false,
1164
+ children: getSchemaChildren({
1165
+ spec,
1166
+ schema: branchSchema,
1167
+ path: `${path || "root"}.${label}`,
1168
+ required: objectRequired,
1169
+ depth: depth + 1,
1170
+ seen
1171
+ })
1172
+ }));
1173
+ return [
1174
+ ...arrayChildren,
1175
+ ...propertyChildren,
1176
+ ...additionalPropertyChildren,
1177
+ ...composedChildren
1178
+ ];
1179
+ }
1180
+ function getRootSchemaNode(spec, schema) {
1181
+ if (isReference(schema)) {
1182
+ const resolvedSchema = resolveSchema(spec, schema);
1183
+ const resolved = isRecord(resolvedSchema) ? resolvedSchema : {};
1184
+ return {
1185
+ key: schema.$ref,
1186
+ name: resolveReferenceName(schema.$ref),
1187
+ type: schemaToType(schema),
1188
+ description: getSchemaDescription(resolved),
1189
+ required: false,
1190
+ children: getSchemaChildren({
1191
+ spec,
1192
+ schema: resolvedSchema,
1193
+ path: resolveReferenceName(schema.$ref),
1194
+ seen: new Set([schema.$ref])
1195
+ })
1196
+ };
1197
+ }
1198
+ if (!isRecord(schema)) return void 0;
1199
+ return {
1200
+ key: "root",
1201
+ name: "body",
1202
+ type: schemaToType(schema),
1203
+ description: getSchemaDescription(schema),
1204
+ required: false,
1205
+ children: getSchemaChildren({
1206
+ spec,
1207
+ schema,
1208
+ path: ""
1209
+ })
1210
+ };
1211
+ }
1212
+ function SchemaNode(arg0) {
1213
+ const { node, depth = 0 } = arg0;
1214
+ const t = useBuiltInText();
1215
+ const [expanded, setExpanded] = useState(depth < 1);
1216
+ const hasChildren = node.children.length > 0;
1217
+ const type = [node.type, node.required ? t("openapi.requiredBadge") : void 0].filter(Boolean).join(", ") || void 0;
1218
+ const description = node.description || (node.required ? t("openapi.required") : t("openapi.optional"));
1219
+ const rowClassName = clsx("flex min-w-0 items-start rounded py-0.5 text-left", depth > 0 ? "-mx-2 w-[calc(100%+1rem)] px-2" : "w-full px-1");
1220
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
1221
+ className: "min-w-0 flex-1",
1222
+ children: [/* @__PURE__ */ jsxs("div", {
1223
+ className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5",
1224
+ children: [/* @__PURE__ */ jsx("span", {
1225
+ className: "text-sm/5 font-semibold text-zinc-950 dark:text-white",
1226
+ children: node.name
1227
+ }), type ? /* @__PURE__ */ jsx("span", {
1228
+ className: "font-mono text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-500",
1229
+ children: type
1230
+ }) : null]
1231
+ }), description ? /* @__PURE__ */ jsx("div", {
1232
+ className: "mt-0.5 text-sm/5 text-zinc-600 dark:text-zinc-400",
1233
+ children: description
1234
+ }) : null]
1235
+ }), hasChildren ? /* @__PURE__ */ jsx("span", {
1236
+ className: "ml-2 flex h-5 w-5 flex-none items-center justify-center text-zinc-500 dark:text-zinc-400",
1237
+ "aria-hidden": "true",
1238
+ children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
1239
+ }) : null] });
1240
+ return /* @__PURE__ */ jsxs("li", {
1241
+ className: "clarify-schema-node m-0 px-0 py-2 first:pt-0 last:pb-0",
1242
+ children: [hasChildren ? /* @__PURE__ */ jsx("button", {
1243
+ type: "button",
1244
+ "aria-label": expanded ? t("openapi.collapse") : t("openapi.expand"),
1245
+ "aria-expanded": expanded,
1246
+ onClick: () => setExpanded((value) => !value),
1247
+ className: clsx(rowClassName, "cursor-pointer transition"),
1248
+ children: content
1249
+ }) : /* @__PURE__ */ jsx("div", {
1250
+ className: rowClassName,
1251
+ children: content
1252
+ }), hasChildren && expanded ? /* @__PURE__ */ jsx(SchemaTree, {
1253
+ nodes: node.children,
1254
+ depth: depth + 1
1255
+ }) : null]
1256
+ });
1257
+ }
1258
+ function SchemaTree(arg0) {
1259
+ const { nodes, depth = 0 } = arg0;
1260
+ if (nodes.length === 0) return null;
1261
+ return /* @__PURE__ */ jsx("ul", {
1262
+ role: "list",
1263
+ className: clsx("m-0 list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5", depth > 0 && "mt-2 rounded-lg bg-zinc-950/[0.025] px-2 py-1 dark:bg-white/[0.04]"),
1264
+ children: nodes.map((node) => /* @__PURE__ */ jsx(SchemaNode, {
1265
+ node,
1266
+ depth
1267
+ }, node.key))
1268
+ });
1269
+ }
1270
+ function SchemaProperties(arg0) {
1271
+ const { title, schema, spec } = arg0;
1272
+ const root = getRootSchemaNode(spec, schema);
1273
+ if (!root || root.children.length === 0) return null;
1274
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx("div", {
1275
+ className: "clarify-schema-properties my-6",
1276
+ children: /* @__PURE__ */ jsx(SchemaTree, { nodes: root.children })
653
1277
  })] });
654
1278
  }
1279
+ function ParameterList(arg0) {
1280
+ const { title, parameters } = arg0;
1281
+ const t = useBuiltInText();
1282
+ if (parameters.length === 0) return null;
1283
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: title }), /* @__PURE__ */ jsx(Properties, { children: parameters.map((parameter) => /* @__PURE__ */ jsx(Property, {
1284
+ name: parameter.name ?? t("openapi.parameter"),
1285
+ type: [schemaToType(parameter.schema), parameter.required ? t("openapi.requiredBadge") : void 0].filter(Boolean).join(", ") || void 0,
1286
+ children: parameter.description ?? t("openapi.operationParameter")
1287
+ }, `${parameter.in}-${parameter.name}`)) })] });
1288
+ }
1289
+ function ResponseList(arg0) {
1290
+ const { operation } = arg0;
1291
+ const t = useBuiltInText();
1292
+ const responses = getResponseEntries(operation);
1293
+ if (responses.length === 0) return null;
1294
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", { children: t("openapi.responses") }), /* @__PURE__ */ jsx(Properties, { children: responses.map(({ status, response }) => {
1295
+ return /* @__PURE__ */ jsx(Property, {
1296
+ name: status,
1297
+ type: schemaToType(getJsonLikeContent(response.content)?.value.schema),
1298
+ children: response.description ?? `${t("openapi.response")}.`
1299
+ }, status);
1300
+ }) })] });
1301
+ }
1302
+ //#endregion
1303
+ //#region source/openapi/spec-path.ts
1304
+ var VIRTUAL_PREFIX = "virtual:clarify-page/";
1305
+ function resolveRelativePath(fromDir, to) {
1306
+ const parts = (fromDir + "/" + to).split("/").filter(Boolean);
1307
+ const stack = [];
1308
+ for (const part of parts) if (part === "..") stack.pop();
1309
+ else if (part !== ".") stack.push(part);
1310
+ return stack.join("/");
1311
+ }
1312
+ function normalizeSpecPath(specPath, currentRoutePath, routePrefix = "") {
1313
+ if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath;
1314
+ const normalizedRoutePrefix = routePrefix.replace(/^\/+|\/+$/g, "");
1315
+ const normalizedSpecPath = specPath.startsWith("/") && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`) ? "/" + specPath.slice(normalizedRoutePrefix.length + 2) : specPath;
1316
+ if (normalizedSpecPath.startsWith("/")) return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\//, "");
1317
+ const fromDir = currentRoutePath === "/" ? "" : currentRoutePath?.replace(/^\//, "").replace(/\/[^/]*$/, "") ?? "";
1318
+ return VIRTUAL_PREFIX + resolveRelativePath(normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`) ? fromDir.slice(normalizedRoutePrefix.length + 1) : fromDir, normalizedSpecPath);
1319
+ }
1320
+ function useOpenApiSpec(spec, specPath) {
1321
+ const specs = useOpenApis();
1322
+ const location = useLocation();
1323
+ const config = useClarifyConfig();
1324
+ if (spec) return spec;
1325
+ if (!specPath) return null;
1326
+ return specs[normalizeSpecPath(specPath, location.pathname, config.routePrefix)] ?? null;
1327
+ }
1328
+ //#endregion
1329
+ //#region source/openapi/utils.ts
1330
+ var OPENAPI_HTTP_METHODS = [
1331
+ "get",
1332
+ "put",
1333
+ "post",
1334
+ "delete",
1335
+ "options",
1336
+ "head",
1337
+ "patch",
1338
+ "trace"
1339
+ ];
1340
+ function isOpenAPIHttpMethod(method) {
1341
+ return OPENAPI_HTTP_METHODS.includes(method.toLowerCase());
1342
+ }
1343
+ function getOpenApiOperation(spec, path, method) {
1344
+ if (!isOpenAPIHttpMethod(method)) return void 0;
1345
+ return spec.paths?.[path]?.[method.toLowerCase()];
1346
+ }
1347
+ function listOpenApiOperations(spec) {
1348
+ const paths = spec.paths ?? {};
1349
+ const operations = [];
1350
+ for (const [path, pathItem] of Object.entries(paths)) {
1351
+ if (!pathItem) continue;
1352
+ for (const method of OPENAPI_HTTP_METHODS) {
1353
+ const operation = pathItem[method];
1354
+ if (operation) operations.push({
1355
+ path,
1356
+ method,
1357
+ operation
1358
+ });
1359
+ }
1360
+ }
1361
+ return operations;
1362
+ }
1363
+ //#endregion
1364
+ //#region source/openapi/openapi-page.tsx
655
1365
  function EndpointExamples(arg0) {
656
- const { spec, path, method, operation, parameters, requestContents } = arg0;
1366
+ const { spec, path, method, operation, parameters, requestContents, selectedRequestMediaType, onSelectRequestMediaType, selectedServer, serverVariables, auth } = arg0;
657
1367
  return /* @__PURE__ */ jsxs("div", {
658
1368
  className: "space-y-6",
659
1369
  children: [/* @__PURE__ */ jsx(RequestExamplesPanel, {
@@ -661,93 +1371,416 @@ function EndpointExamples(arg0) {
661
1371
  path,
662
1372
  method,
663
1373
  parameters,
664
- requestContents
1374
+ requestContents,
1375
+ selectedMediaType: selectedRequestMediaType,
1376
+ onSelectMediaType: onSelectRequestMediaType,
1377
+ selectedServer,
1378
+ serverVariables,
1379
+ auth
665
1380
  }), /* @__PURE__ */ jsx(ResponseExamplesPanel, { operation })]
666
1381
  });
667
1382
  }
668
1383
  function OpenApiHeader(arg0) {
669
1384
  const { spec } = arg0;
1385
+ const t = useBuiltInText();
670
1386
  return /* @__PURE__ */ jsxs("header", {
671
1387
  className: "mb-16",
672
1388
  children: [
673
1389
  /* @__PURE__ */ jsx("p", {
674
1390
  className: "mb-3 font-mono text-xs/6 font-medium tracking-widest text-emerald-500 uppercase dark:text-emerald-400",
675
- children: "OpenAPI Reference"
1391
+ children: t("openapi.openApiReference")
676
1392
  }),
677
- /* @__PURE__ */ jsx("h1", { children: spec.info?.title ?? "API Documentation" }),
1393
+ /* @__PURE__ */ jsx("h1", { children: spec.info?.title ?? t("openapi.apiDocumentation") }),
678
1394
  spec.info?.description ? /* @__PURE__ */ jsx("p", {
679
1395
  className: "lead",
680
1396
  children: spec.info.description
681
1397
  }) : null,
682
- spec.info?.version ? /* @__PURE__ */ jsxs("p", {
1398
+ spec.info?.version ? /* @__PURE__ */ jsx("p", {
683
1399
  className: "text-sm text-zinc-500 dark:text-zinc-400",
684
- children: ["Version ", spec.info.version]
1400
+ children: t("openapi.version", { version: spec.info.version })
1401
+ }) : null
1402
+ ]
1403
+ });
1404
+ }
1405
+ var endpointMethodStyles = {
1406
+ GET: "bg-emerald-400/15 text-emerald-600 dark:bg-emerald-400/20 dark:text-emerald-300",
1407
+ POST: "bg-sky-400/15 text-sky-600 dark:bg-sky-400/20 dark:text-sky-300",
1408
+ PUT: "bg-amber-400/15 text-amber-600 dark:bg-amber-400/20 dark:text-amber-300",
1409
+ PATCH: "bg-amber-400/15 text-amber-600 dark:bg-amber-400/20 dark:text-amber-300",
1410
+ DELETE: "bg-rose-400/15 text-rose-600 dark:bg-rose-400/20 dark:text-rose-300"
1411
+ };
1412
+ function EndpointMethodBadge(arg0) {
1413
+ const { method } = arg0;
1414
+ return /* @__PURE__ */ jsx("span", {
1415
+ className: clsx("rounded-(--clarify-theme-tokens-radius-md) px-2.5 py-0.5 font-mono text-xs/6 font-black tracking-wide", endpointMethodStyles[method] ?? "bg-zinc-400/15 text-zinc-700 dark:bg-zinc-400/20 dark:text-zinc-200"),
1416
+ children: method
1417
+ });
1418
+ }
1419
+ function InlineListbox(arg0) {
1420
+ const { label, value, options, onChange, compact = false } = arg0;
1421
+ const selected = options.find((option) => option.value === value) ?? options[0];
1422
+ return /* @__PURE__ */ jsx(Listbox, {
1423
+ value: selected?.value ?? value,
1424
+ onChange,
1425
+ children: /* @__PURE__ */ jsxs("div", {
1426
+ className: "pointer-events-auto relative inline-flex min-w-0",
1427
+ children: [/* @__PURE__ */ jsxs(ListboxButton, {
1428
+ "aria-label": label,
1429
+ className: clsx("inline-flex min-w-0 items-center gap-1 rounded-md border border-zinc-200 bg-white font-mono font-semibold text-zinc-900 shadow-xs outline-hidden transition hover:border-zinc-300 hover:bg-zinc-50 data-open:border-zinc-300 data-open:bg-zinc-50 dark:border-white/10 dark:bg-zinc-950 dark:text-zinc-100 dark:hover:border-white/15 dark:hover:bg-zinc-900 dark:data-open:border-white/15 dark:data-open:bg-zinc-900", compact ? "max-w-32 px-1.5 py-0.5 text-xs" : "w-full px-2.5 py-1.5 text-xs"),
1430
+ children: [/* @__PURE__ */ jsx("span", {
1431
+ className: "truncate",
1432
+ children: selected?.label ?? value
1433
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, {
1434
+ className: "h-3.5 w-3.5 shrink-0 text-zinc-500 dark:text-zinc-400",
1435
+ "aria-hidden": "true"
1436
+ })]
1437
+ }), /* @__PURE__ */ jsx(ListboxOptions, {
1438
+ anchor: "bottom start",
1439
+ className: "z-30 mt-1 max-h-64 w-max min-w-(--button-width) max-w-[min(32rem,calc(100vw-2rem))] overflow-auto rounded-xl bg-white p-1 text-xs shadow-lg shadow-black/10 ring-1 ring-zinc-950/10 [--anchor-gap:--spacing(1)] focus:outline-none dark:bg-zinc-950 dark:ring-white/10",
1440
+ children: options.map((option) => /* @__PURE__ */ jsxs(ListboxOption, {
1441
+ value: option.value,
1442
+ className: "group flex cursor-default items-center justify-between gap-3 rounded-lg px-2.5 py-2 font-mono text-xs text-zinc-700 select-none data-focus:bg-zinc-100 data-selected:text-emerald-700 dark:text-zinc-200 dark:data-focus:bg-white/10 dark:data-selected:text-emerald-300",
1443
+ children: [/* @__PURE__ */ jsxs("span", {
1444
+ className: "min-w-0",
1445
+ children: [/* @__PURE__ */ jsx("span", {
1446
+ className: "block truncate",
1447
+ children: option.label
1448
+ }), option.description ? /* @__PURE__ */ jsx("span", {
1449
+ className: "mt-0.5 block truncate text-2xs text-zinc-500 dark:text-zinc-400",
1450
+ children: option.description
1451
+ }) : null]
1452
+ }), /* @__PURE__ */ jsx(CheckIcon, {
1453
+ className: "h-3.5 w-3.5 shrink-0 opacity-0 group-data-selected:opacity-100",
1454
+ "aria-hidden": "true"
1455
+ })]
1456
+ }, option.value))
1457
+ })]
1458
+ })
1459
+ });
1460
+ }
1461
+ function getServerPreviewUrl(server, variables) {
1462
+ return (server.url ?? "").replace(/\{([^}]+)\}/g, (_, name) => variables[name] ?? server.variables?.[name]?.default ?? `{${name}}`);
1463
+ }
1464
+ function ServerUrlValue(arg0) {
1465
+ const { server, variables, open, onToggle } = arg0;
1466
+ const url = getServerPreviewUrl(server, variables);
1467
+ return /* @__PURE__ */ jsxs("button", {
1468
+ type: "button",
1469
+ "aria-expanded": open,
1470
+ "aria-label": "Server",
1471
+ onClick: onToggle,
1472
+ className: clsx("flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-zinc-100/50 text-zinc-600 transition hover:bg-zinc-100 hover:text-zinc-950 dark:bg-white/5 dark:text-zinc-300 dark:hover:bg-white/10 dark:hover:text-white sm:w-auto sm:min-w-16 sm:max-w-[min(36%,16rem)] sm:px-1.5", open ? "bg-zinc-200 text-zinc-950 dark:bg-white/12 dark:text-white" : null),
1473
+ children: [/* @__PURE__ */ jsx("span", {
1474
+ className: "sm:hidden",
1475
+ children: /* @__PURE__ */ jsx(ServerIcon, {
1476
+ className: "h-4 w-4",
1477
+ "aria-hidden": "true"
1478
+ })
1479
+ }), /* @__PURE__ */ jsxs("span", {
1480
+ className: "hidden min-w-0 items-center gap-1 overflow-hidden sm:flex",
1481
+ children: [/* @__PURE__ */ jsx("span", {
1482
+ className: "truncate font-mono text-xs",
1483
+ children: url
1484
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, {
1485
+ className: "h-3.5 w-3.5 shrink-0 text-zinc-400",
1486
+ "aria-hidden": "true"
1487
+ })]
1488
+ })]
1489
+ });
1490
+ }
1491
+ function ServerVariableControl(arg0) {
1492
+ const { name, variable, value, onChange, compact = false } = arg0;
1493
+ if (variable?.enum?.length) return /* @__PURE__ */ jsx(InlineListbox, {
1494
+ label: name,
1495
+ value,
1496
+ options: variable.enum.map((option) => ({
1497
+ value: option,
1498
+ label: option
1499
+ })),
1500
+ onChange,
1501
+ compact
1502
+ });
1503
+ return /* @__PURE__ */ jsx("input", {
1504
+ "aria-label": name,
1505
+ value,
1506
+ placeholder: variable?.default ?? name,
1507
+ onChange: (event) => onChange(event.target.value),
1508
+ className: clsx("pointer-events-auto rounded-md border border-zinc-200 bg-white font-mono text-xs font-semibold text-zinc-900 shadow-xs outline-hidden transition placeholder:text-zinc-500 hover:border-zinc-300 hover:bg-zinc-50 focus:border-zinc-400 focus:bg-white dark:border-white/10 dark:bg-zinc-950 dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:hover:border-white/15 dark:hover:bg-zinc-900 dark:focus:border-white/20 dark:focus:bg-zinc-950", compact ? "mx-0.5 w-24 px-1.5 py-0.5" : "w-full px-2.5 py-1.5")
1509
+ });
1510
+ }
1511
+ function ServerPanel(arg0) {
1512
+ const { servers, selectedKey, selectedServer, variables, onSelectServer, onChangeVariable } = arg0;
1513
+ const variableEntries = Object.entries(selectedServer.variables ?? {});
1514
+ return /* @__PURE__ */ jsx("div", {
1515
+ className: "border-t border-zinc-200 bg-zinc-100/70 p-3 dark:border-white/10 dark:bg-zinc-900/60",
1516
+ children: /* @__PURE__ */ jsxs("div", {
1517
+ className: "grid gap-3 sm:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)]",
1518
+ children: [servers.length > 1 ? /* @__PURE__ */ jsxs("label", {
1519
+ className: "flex min-w-0 flex-col gap-1.5",
1520
+ children: [/* @__PURE__ */ jsx("span", {
1521
+ className: "text-2xs font-semibold text-zinc-700 dark:text-zinc-300",
1522
+ children: "Server"
1523
+ }), /* @__PURE__ */ jsx(InlineListbox, {
1524
+ label: "Server",
1525
+ value: selectedKey,
1526
+ options: servers.map((server, index) => ({
1527
+ value: getServerKey(server, index),
1528
+ label: getServerLabel(server, index),
1529
+ description: server.description
1530
+ })),
1531
+ onChange: onSelectServer
1532
+ })]
1533
+ }) : null, variableEntries.map(([name, variable]) => /* @__PURE__ */ jsxs("label", {
1534
+ className: "flex min-w-0 flex-col gap-1.5",
1535
+ children: [/* @__PURE__ */ jsx("span", {
1536
+ className: "text-2xs font-semibold text-zinc-700 dark:text-zinc-300",
1537
+ children: name
1538
+ }), /* @__PURE__ */ jsx(ServerVariableControl, {
1539
+ name,
1540
+ variable,
1541
+ value: variables[name] ?? variable.default ?? "",
1542
+ onChange: (value) => onChangeVariable(name, value)
1543
+ })]
1544
+ }, name))]
1545
+ })
1546
+ });
1547
+ }
1548
+ function AuthPanel(arg0) {
1549
+ const { authOptions, selectedAuthName, selectedAuth, authValues, onSelectAuth, onChangeAuthValue } = arg0;
1550
+ if (authOptions.length === 0) return null;
1551
+ return /* @__PURE__ */ jsx("div", {
1552
+ className: "border-t border-zinc-200 bg-zinc-100/70 p-3 dark:border-white/10 dark:bg-zinc-900/60",
1553
+ children: /* @__PURE__ */ jsxs("div", {
1554
+ className: "grid gap-3 sm:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)]",
1555
+ children: [/* @__PURE__ */ jsxs("label", {
1556
+ className: "flex min-w-0 flex-col gap-1.5",
1557
+ children: [/* @__PURE__ */ jsx("span", {
1558
+ className: "text-2xs font-semibold text-zinc-700 dark:text-zinc-300",
1559
+ children: "Auth"
1560
+ }), /* @__PURE__ */ jsx(InlineListbox, {
1561
+ label: "Auth",
1562
+ value: selectedAuthName,
1563
+ options: authOptions.map(({ name, scheme }) => ({
1564
+ value: name,
1565
+ label: name,
1566
+ description: authLabel(name, scheme)
1567
+ })),
1568
+ onChange: onSelectAuth
1569
+ })]
1570
+ }), selectedAuth ? /* @__PURE__ */ jsxs("label", {
1571
+ className: "flex min-w-0 flex-col gap-1.5",
1572
+ children: [/* @__PURE__ */ jsx("span", {
1573
+ className: "text-2xs font-semibold text-zinc-700 dark:text-zinc-300",
1574
+ children: "Credential"
1575
+ }), /* @__PURE__ */ jsxs("div", {
1576
+ className: "flex min-w-0 items-center rounded-md border border-zinc-200 bg-white px-2.5 py-1.5 shadow-xs dark:border-white/10 dark:bg-zinc-950",
1577
+ children: [/* @__PURE__ */ jsx("span", {
1578
+ className: "mr-2 shrink-0 font-mono text-2xs font-semibold text-zinc-600 dark:text-zinc-400",
1579
+ children: selectedAuth.scheme.type === "apiKey" ? selectedAuth.scheme.in ?? "apiKey" : selectedAuth.scheme.scheme ?? selectedAuth.scheme.type ?? "token"
1580
+ }), /* @__PURE__ */ jsx("input", {
1581
+ value: authValues[selectedAuth.name] ?? authPlaceholder(selectedAuth),
1582
+ onChange: (event) => onChangeAuthValue(selectedAuth.name, event.target.value),
1583
+ className: "min-w-0 flex-1 border-0 bg-transparent px-0 py-0 font-mono text-xs font-semibold text-zinc-900 outline-hidden placeholder:text-zinc-500 dark:text-zinc-100 dark:placeholder:text-zinc-500"
1584
+ })]
1585
+ })]
1586
+ }) : null]
1587
+ })
1588
+ });
1589
+ }
1590
+ function EndpointIdentity(arg0) {
1591
+ const { method, path, servers, selectedServerKey, selectedServer, serverVariables, serverOpen, authOptions, selectedAuthName, selectedAuth, authValues, authOpen, onSelectServer, onChangeServerVariable, onToggleServer, onToggleAuth, onSelectAuth, onChangeAuthValue } = arg0;
1592
+ const segments = path.split("/").filter(Boolean);
1593
+ return /* @__PURE__ */ jsxs("div", {
1594
+ className: "not-prose flex w-full flex-col overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-xs dark:border-white/10 dark:bg-zinc-950",
1595
+ children: [
1596
+ /* @__PURE__ */ jsxs("div", {
1597
+ className: "flex min-w-0 items-center gap-1.5 overflow-hidden px-2.5 py-2",
1598
+ children: [
1599
+ /* @__PURE__ */ jsx(EndpointMethodBadge, { method }),
1600
+ /* @__PURE__ */ jsx(ServerUrlValue, {
1601
+ server: selectedServer,
1602
+ variables: serverVariables,
1603
+ open: serverOpen,
1604
+ onToggle: onToggleServer
1605
+ }),
1606
+ /* @__PURE__ */ jsx("div", {
1607
+ className: "flex min-w-0 flex-1 items-center overflow-x-auto font-mono text-sm font-bold leading-6 whitespace-nowrap",
1608
+ children: segments.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
1609
+ className: "text-zinc-400",
1610
+ children: "/"
1611
+ }), segments.map((segment, index) => /* @__PURE__ */ jsxs("span", {
1612
+ className: "flex items-center",
1613
+ children: [index > 0 ? /* @__PURE__ */ jsx("span", {
1614
+ className: "text-zinc-400",
1615
+ children: "/"
1616
+ }) : null, /* @__PURE__ */ jsx("span", {
1617
+ className: "font-bold text-zinc-800 dark:text-white",
1618
+ children: segment
1619
+ })]
1620
+ }, `${segment}-${index}`))] }) : /* @__PURE__ */ jsx("span", {
1621
+ className: "font-bold text-zinc-800 dark:text-white",
1622
+ children: "/"
1623
+ })
1624
+ }),
1625
+ authOptions.length > 0 ? /* @__PURE__ */ jsx("button", {
1626
+ type: "button",
1627
+ "aria-expanded": authOpen,
1628
+ "aria-label": "Auth",
1629
+ onClick: onToggleAuth,
1630
+ className: clsx("ml-auto flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-zinc-600 transition hover:bg-zinc-100 hover:text-emerald-700 dark:text-zinc-300 dark:hover:bg-white/10 dark:hover:text-emerald-200", authOpen ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-400/15 dark:text-emerald-100" : "bg-zinc-50 dark:bg-white/5"),
1631
+ children: authOpen ? /* @__PURE__ */ jsx(UnlockKeyholeIcon, {
1632
+ className: "h-4 w-4",
1633
+ "aria-hidden": "true"
1634
+ }) : /* @__PURE__ */ jsx(LockKeyholeIcon, {
1635
+ className: "h-4 w-4",
1636
+ "aria-hidden": "true"
1637
+ })
1638
+ }) : null
1639
+ ]
1640
+ }),
1641
+ serverOpen ? /* @__PURE__ */ jsx(ServerPanel, {
1642
+ servers,
1643
+ selectedKey: selectedServerKey,
1644
+ selectedServer,
1645
+ variables: serverVariables,
1646
+ onSelectServer,
1647
+ onChangeVariable: onChangeServerVariable
1648
+ }) : null,
1649
+ authOpen ? /* @__PURE__ */ jsx(AuthPanel, {
1650
+ authOptions,
1651
+ selectedAuthName,
1652
+ selectedAuth,
1653
+ authValues,
1654
+ onSelectAuth,
1655
+ onChangeAuthValue
685
1656
  }) : null
686
1657
  ]
687
1658
  });
688
1659
  }
689
1660
  function OpenApiOperation(arg0) {
690
1661
  const { spec, path, method, operation } = arg0;
1662
+ const t = useBuiltInText();
691
1663
  const id = slug(`${method.toLowerCase()} ${path}`);
692
1664
  const summary = operation.summary ?? `${method} ${path}`;
693
1665
  const description = operation.description;
694
1666
  const parameters = getOperationParameters(spec, path, operation);
695
- const requestBody = getRequestBody(operation);
1667
+ const requestBody = getRequestBody$1(operation);
696
1668
  const requestContents = getMediaTypeEntries(requestBody?.content);
697
- const requestSchema = requestContents[0]?.value.schema;
1669
+ const [selectedRequestMediaType, setSelectedRequestMediaType] = useState(requestContents[0]?.mediaType ?? "");
1670
+ const selectedRequestContent = requestContents.find((content) => content.mediaType === selectedRequestMediaType) ?? requestContents[0];
1671
+ const requestSchema = selectedRequestContent?.value.schema;
1672
+ const servers = getServers(spec, operation);
1673
+ const [selectedServerKey, setSelectedServerKey] = useState(getServerKey(servers[0], 0));
1674
+ const selectedServer = servers.find((server, index) => getServerKey(server, index) === selectedServerKey) ?? servers[0];
1675
+ const [serverVariables, setServerVariables] = useState(defaultServerVariables(selectedServer));
1676
+ const [serverOpen, setServerOpen] = useState(false);
1677
+ const authOptions = getAuthOptions(spec, operation);
1678
+ const [selectedAuthName, setSelectedAuthName] = useState(authOptions[0]?.name ?? "");
1679
+ const selectedAuth = authOptions.find((option) => option.name === selectedAuthName);
1680
+ const [authValues, setAuthValues] = useState({});
1681
+ const [authOpen, setAuthOpen] = useState(false);
1682
+ const authInput = selectedAuth ? {
1683
+ name: selectedAuth.name,
1684
+ scheme: selectedAuth.scheme,
1685
+ value: authValues[selectedAuth.name] ?? authPlaceholder(selectedAuth)
1686
+ } : void 0;
698
1687
  const groupedParameters = {
699
1688
  path: parameters.filter((parameter) => parameter.in === "path"),
700
1689
  query: parameters.filter((parameter) => parameter.in === "query"),
701
1690
  header: parameters.filter((parameter) => parameter.in === "header")
702
1691
  };
703
1692
  return /* @__PURE__ */ jsxs("section", {
704
- className: "clarify-api-endpoint scroll-mt-24",
1693
+ className: "clarify-api-endpoint scroll-mt-24 py-16 first:pt-0 last:pb-0",
705
1694
  "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
1695
+ children: [
1696
+ /* @__PURE__ */ jsx(EndpointIdentity, {
1697
+ method,
1698
+ path,
1699
+ servers,
1700
+ selectedServerKey,
1701
+ selectedServer,
1702
+ serverVariables,
1703
+ serverOpen,
1704
+ authOptions,
1705
+ selectedAuthName,
1706
+ selectedAuth,
1707
+ authValues,
1708
+ authOpen,
1709
+ onSelectServer: (value) => {
1710
+ const nextServer = servers.find((server, index) => getServerKey(server, index) === value) ?? servers[0];
1711
+ setSelectedServerKey(value);
1712
+ setServerVariables(defaultServerVariables(nextServer));
1713
+ },
1714
+ onChangeServerVariable: (name, value) => setServerVariables((current) => ({
1715
+ ...current,
1716
+ [name]: value
1717
+ })),
1718
+ onToggleServer: () => {
1719
+ setServerOpen((current) => !current);
1720
+ setAuthOpen(false);
1721
+ },
1722
+ onToggleAuth: () => {
1723
+ setAuthOpen((current) => !current);
1724
+ setServerOpen(false);
1725
+ },
1726
+ onSelectAuth: setSelectedAuthName,
1727
+ onChangeAuthValue: (name, value) => setAuthValues((current) => ({
1728
+ ...current,
1729
+ [name]: value
1730
+ }))
720
1731
  }),
721
- /* @__PURE__ */ jsx(ParameterList, {
722
- title: "Headers",
723
- parameters: groupedParameters.header
1732
+ /* @__PURE__ */ jsx(Heading, {
1733
+ id,
1734
+ className: "mt-4",
1735
+ children: summary
724
1736
  }),
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
1737
+ /* @__PURE__ */ jsxs(Row, { children: [/* @__PURE__ */ jsxs(Col, { children: [
1738
+ description ? /* @__PURE__ */ jsx("p", { children: description }) : null,
1739
+ /* @__PURE__ */ jsx(ParameterList, {
1740
+ title: t("openapi.pathParameters"),
1741
+ parameters: groupedParameters.path
1742
+ }),
1743
+ /* @__PURE__ */ jsx(ParameterList, {
1744
+ title: t("openapi.queryParameters"),
1745
+ parameters: groupedParameters.query
1746
+ }),
1747
+ /* @__PURE__ */ jsx(ParameterList, {
1748
+ title: t("openapi.headers"),
1749
+ parameters: groupedParameters.header
1750
+ }),
1751
+ requestBody && requestContents.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1752
+ /* @__PURE__ */ jsx("h3", { children: t("openapi.requestBody") }),
1753
+ typeof requestBody.description === "string" ? /* @__PURE__ */ jsx("p", { children: requestBody.description }) : null,
1754
+ /* @__PURE__ */ jsx(SchemaProperties, {
1755
+ title: t("openapi.bodyProperties"),
1756
+ schema: requestSchema,
1757
+ spec
1758
+ })
1759
+ ] }) : null,
1760
+ /* @__PURE__ */ jsx(ResponseList, { operation })
1761
+ ] }), /* @__PURE__ */ jsx(Col, {
1762
+ sticky: true,
1763
+ children: /* @__PURE__ */ jsx(EndpointExamples, {
1764
+ spec,
1765
+ path,
1766
+ method,
1767
+ operation,
1768
+ parameters,
1769
+ requestContents,
1770
+ selectedRequestMediaType: selectedRequestContent?.mediaType ?? "",
1771
+ onSelectRequestMediaType: setSelectedRequestMediaType,
1772
+ selectedServer,
1773
+ serverVariables,
1774
+ auth: authInput
731
1775
  })
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
- })] })]
1776
+ })] })
1777
+ ]
745
1778
  });
746
1779
  }
747
1780
  function OpenApiPaths(arg0) {
748
1781
  const { spec } = arg0;
749
1782
  return /* @__PURE__ */ jsx("div", {
750
- className: "clarify-api-endpoints space-y-16",
1783
+ className: "clarify-api-endpoints divide-y divide-zinc-200/70 dark:divide-white/10",
751
1784
  children: listOpenApiOperations(spec).map(({ path, method, operation }) => ({
752
1785
  path,
753
1786
  method: method.toUpperCase(),
@@ -760,29 +1793,6 @@ function OpenApiPaths(arg0) {
760
1793
  }, `${method}-${path}`))
761
1794
  });
762
1795
  }
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
1796
  function WarningBox(arg0) {
787
1797
  const { children, tone = "amber" } = arg0;
788
1798
  return /* @__PURE__ */ jsx("div", {
@@ -792,27 +1802,24 @@ function WarningBox(arg0) {
792
1802
  }
793
1803
  function OpenApiPage(arg0) {
794
1804
  const { spec, specPath } = arg0;
1805
+ const t = useBuiltInText();
795
1806
  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", {
1807
+ if (!resolved) return /* @__PURE__ */ jsx(WarningBox, { children: t("openapi.specNotFound", { specPath: specPath ?? t("openapi.specPathMissing") }) });
1808
+ return /* @__PURE__ */ jsx("article", {
798
1809
  className: "clarify-openapi-page flex h-full flex-col pt-16 pb-10",
799
- children: [/* @__PURE__ */ jsxs(Prose, {
1810
+ children: /* @__PURE__ */ jsxs(Prose, {
800
1811
  className: "flex-auto",
801
1812
  children: [/* @__PURE__ */ jsx(OpenApiHeader, { spec: resolved }), /* @__PURE__ */ jsx(OpenApiPaths, { spec: resolved })]
802
- }), /* @__PURE__ */ jsx(PageFooter, {})]
1813
+ })
803
1814
  });
804
1815
  }
805
1816
  function ApiEndpoint(arg0) {
806
1817
  const { spec, path, method } = arg0;
1818
+ const t = useBuiltInText();
807
1819
  const op = getOpenApiOperation(spec, path, method);
808
- if (!op) return /* @__PURE__ */ jsxs(WarningBox, {
1820
+ if (!op) return /* @__PURE__ */ jsx(WarningBox, {
809
1821
  tone: "red",
810
- children: [
811
- "Endpoint not found: ",
812
- method.toUpperCase(),
813
- " ",
814
- path
815
- ]
1822
+ children: t("openapi.endpointNotFound", { endpoint: `${method.toUpperCase()} ${path}` })
816
1823
  });
817
1824
  return /* @__PURE__ */ jsx(OpenApiOperation, {
818
1825
  spec,
@@ -823,8 +1830,9 @@ function ApiEndpoint(arg0) {
823
1830
  }
824
1831
  function OpenApiEndpoint(arg0) {
825
1832
  const { specPath, path, method } = arg0;
1833
+ const t = useBuiltInText();
826
1834
  const spec = useOpenApiSpec(void 0, specPath);
827
- if (!spec) return /* @__PURE__ */ jsxs(WarningBox, { children: ["OpenAPI spec not found: ", specPath] });
1835
+ if (!spec) return /* @__PURE__ */ jsx(WarningBox, { children: t("openapi.specNotFound", { specPath }) });
828
1836
  return /* @__PURE__ */ jsx(ApiEndpoint, {
829
1837
  spec,
830
1838
  path,
@@ -845,6 +1853,6 @@ function useMDXComponents(components = {}) {
845
1853
  };
846
1854
  }
847
1855
  //#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 };
1856
+ export { ApiEndpoint, ApiEndpointCard, AppShell, BuiltWithClarify, Button, Callout, Card, CardGroup, 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
1857
 
850
1858
  //# sourceMappingURL=index.js.map