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