@clarify-labs/renderer 0.11.0 → 0.11.1

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 (58) hide show
  1. package/output/{ClarifyShell-BAjq876Z.cjs → ClarifyShell-C2XnkFQ6.cjs} +37 -21
  2. package/output/ClarifyShell-C2XnkFQ6.cjs.map +1 -0
  3. package/output/{ClarifyShell-GoSXvgMg.js → ClarifyShell-CwRtof1h.js} +37 -21
  4. package/output/ClarifyShell-CwRtof1h.js.map +1 -0
  5. package/output/{MermaidViewer-BZ8ghcFP.cjs → MermaidViewer-CTvMCE19.cjs} +2 -2
  6. package/output/{MermaidViewer-BZ8ghcFP.cjs.map → MermaidViewer-CTvMCE19.cjs.map} +1 -1
  7. package/output/{MermaidViewer-CkIxyqtf.js → MermaidViewer-CwkiQ2gO.js} +2 -2
  8. package/output/{MermaidViewer-CkIxyqtf.js.map → MermaidViewer-CwkiQ2gO.js.map} +1 -1
  9. package/output/{OpenApiOperation-C2vJztWZ.js → OpenApiOperation-CFo6_otd.js} +470 -123
  10. package/output/OpenApiOperation-CFo6_otd.js.map +1 -0
  11. package/output/{OpenApiOperation-D-5uE5v7.cjs → OpenApiOperation-D1WNrj5X.cjs} +470 -123
  12. package/output/OpenApiOperation-D1WNrj5X.cjs.map +1 -0
  13. package/output/{PageActions-bugd7GZh.js → PageActions-3eo05fb_.js} +47 -6
  14. package/output/PageActions-3eo05fb_.js.map +1 -0
  15. package/output/{PageActions-DJRXlGhz.cjs → PageActions-Lp_NeIKr.cjs} +46 -5
  16. package/output/PageActions-Lp_NeIKr.cjs.map +1 -0
  17. package/output/{SearchDialog-CBJjDs_9.js → SearchDialog-BvCBIFqs.js} +3 -3
  18. package/output/{SearchDialog-CBJjDs_9.js.map → SearchDialog-BvCBIFqs.js.map} +1 -1
  19. package/output/{SearchDialog-8AdCRp6K.cjs → SearchDialog-CM9DrE2Y.cjs} +3 -3
  20. package/output/{SearchDialog-8AdCRp6K.cjs.map → SearchDialog-CM9DrE2Y.cjs.map} +1 -1
  21. package/output/client.cjs +3 -3
  22. package/output/client.js +3 -3
  23. package/output/core/i18n.d.ts +1 -1
  24. package/output/core/types.d.ts +1 -1
  25. package/output/{i18n-BPrC45nD.js → i18n-BxXpRSFX.js} +9 -1
  26. package/output/i18n-BxXpRSFX.js.map +1 -0
  27. package/output/{i18n-wXINKKV0.cjs → i18n-DsjZ51U1.cjs} +9 -1
  28. package/output/i18n-DsjZ51U1.cjs.map +1 -0
  29. package/output/index.cjs +5 -5
  30. package/output/index.js +5 -5
  31. package/output/openapi/components/InlineListbox.d.ts +1 -0
  32. package/output/openapi/components/OpenApiRequestBodyEditor.d.ts +14 -0
  33. package/output/openapi/components/OpenApiResponseViewer.d.ts +6 -0
  34. package/output/openapi/components/useOpenApiRequestState.d.ts +9 -2
  35. package/output/openapi/lib/api-request.d.ts +1 -0
  36. package/output/openapi/lib/helpers.d.ts +8 -0
  37. package/output/openapi/types.d.ts +2 -0
  38. package/output/preview.cjs +14 -18
  39. package/output/preview.cjs.map +1 -1
  40. package/output/preview.js +14 -18
  41. package/output/preview.js.map +1 -1
  42. package/output/{render-FICIzeXz.cjs → render-CKG4X-me.cjs} +2 -2
  43. package/output/{render-FICIzeXz.cjs.map → render-CKG4X-me.cjs.map} +1 -1
  44. package/output/{render-XQiw_48i.js → render-vlp3hwW3.js} +2 -2
  45. package/output/{render-XQiw_48i.js.map → render-vlp3hwW3.js.map} +1 -1
  46. package/output/renderer.css +129 -48
  47. package/output/server.cjs +2 -2
  48. package/output/server.js +2 -2
  49. package/package.json +2 -1
  50. package/output/ClarifyShell-BAjq876Z.cjs.map +0 -1
  51. package/output/ClarifyShell-GoSXvgMg.js.map +0 -1
  52. package/output/OpenApiOperation-C2vJztWZ.js.map +0 -1
  53. package/output/OpenApiOperation-D-5uE5v7.cjs.map +0 -1
  54. package/output/PageActions-DJRXlGhz.cjs.map +0 -1
  55. package/output/PageActions-bugd7GZh.js.map +0 -1
  56. package/output/core/index.d.ts +0 -3
  57. package/output/i18n-BPrC45nD.js.map +0 -1
  58. package/output/i18n-wXINKKV0.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
- const require_i18n = require("./i18n-wXINKKV0.cjs");
3
- const require_PageActions = require("./PageActions-DJRXlGhz.cjs");
2
+ const require_i18n = require("./i18n-DsjZ51U1.cjs");
3
+ const require_PageActions = require("./PageActions-Lp_NeIKr.cjs");
4
4
  const require_remark = require("./remark-DTLbG8PK.cjs");
5
5
  let clsx = require("clsx");
6
6
  clsx = require_rolldown_runtime.__toESM(clsx, 1);
@@ -18,6 +18,7 @@ rehype_raw = require_rolldown_runtime.__toESM(rehype_raw, 1);
18
18
  let github_slugger = require("github-slugger");
19
19
  let shiki = require("shiki");
20
20
  let _scalar_snippetz = require("@scalar/snippetz");
21
+ let yaml = require("yaml");
21
22
  //#region source/components/AccordionGroup.tsx
22
23
  function AccordionGroup(arg0) {
23
24
  const { children, multiple = false, className, ...props } = arg0;
@@ -244,7 +245,7 @@ function Card(arg0) {
244
245
  }
245
246
  //#endregion
246
247
  //#region source/components/Mermaid.tsx
247
- var MermaidViewer = (0, react.lazy)(() => Promise.resolve().then(() => require("./MermaidViewer-BZ8ghcFP.cjs")));
248
+ var MermaidViewer = (0, react.lazy)(() => Promise.resolve().then(() => require("./MermaidViewer-CTvMCE19.cjs")));
248
249
  var mermaidModulePromise;
249
250
  async function loadMermaid() {
250
251
  mermaidModulePromise = mermaidModulePromise ?? import("mermaid").then((module) => module.default);
@@ -1446,6 +1447,31 @@ function resolveSchema(spec, schema, seen = /* @__PURE__ */ new Set()) {
1446
1447
  seen.add(schema.$ref);
1447
1448
  return resolveSchema(spec, resolveOpenApiRef$1(spec, schema.$ref), seen) ?? schema;
1448
1449
  }
1450
+ function mergeAllOfSchemas(spec, schemas) {
1451
+ const merged = {};
1452
+ const properties = {};
1453
+ const required = /* @__PURE__ */ new Set();
1454
+ for (const schema of schemas) {
1455
+ const resolved = resolveRequestSchema(spec, schema);
1456
+ if (!isRecord$1(resolved)) continue;
1457
+ Object.assign(merged, resolved);
1458
+ if (isRecord$1(resolved.properties)) Object.assign(properties, resolved.properties);
1459
+ if (Array.isArray(resolved.required)) resolved.required.forEach((name) => required.add(String(name)));
1460
+ }
1461
+ if (Object.keys(properties).length > 0) merged.properties = properties;
1462
+ if (required.size > 0) merged.required = [...required];
1463
+ delete merged.allOf;
1464
+ return merged;
1465
+ }
1466
+ function resolveRequestSchema(spec, schema) {
1467
+ const resolved = resolveSchema(spec, schema);
1468
+ if (!isRecord$1(resolved)) return resolved;
1469
+ const ownSchema = { ...resolved };
1470
+ const allOf = Array.isArray(ownSchema.allOf) ? ownSchema.allOf : [];
1471
+ if (allOf.length === 0) return ownSchema;
1472
+ delete ownSchema.allOf;
1473
+ return mergeAllOfSchemas(spec, [...allOf, ownSchema]);
1474
+ }
1449
1475
  function getPathItem$1(spec, path) {
1450
1476
  return resolveObjectRef(spec, spec.paths?.[path]);
1451
1477
  }
@@ -1465,6 +1491,7 @@ function resolveObjectRef(spec, value) {
1465
1491
  }
1466
1492
  function schemaHasType(schema, type) {
1467
1493
  if (!isRecord$1(schema)) return false;
1494
+ if (type === "null" && schema.nullable === true) return true;
1468
1495
  return schema.type === type || Array.isArray(schema.type) && schema.type.includes(type);
1469
1496
  }
1470
1497
  function getOperationParameters(spec, path, operation, source = "path") {
@@ -1534,7 +1561,7 @@ function getExampleEntries(mediaType, spec) {
1534
1561
  title: "Example",
1535
1562
  value: mediaType.example
1536
1563
  }];
1537
- const generated = schemaToExample(spec ? resolveSchema(spec, mediaType.schema) : mediaType.schema);
1564
+ const generated = schemaToExample(spec ? resolveRequestSchema(spec, mediaType.schema) : mediaType.schema);
1538
1565
  return typeof generated === "undefined" ? [] : [{
1539
1566
  key: "schema",
1540
1567
  title: "schema",
@@ -1542,6 +1569,34 @@ function getExampleEntries(mediaType, spec) {
1542
1569
  generated: true
1543
1570
  }];
1544
1571
  }
1572
+ function getParameterExampleEntries(parameter) {
1573
+ if (isRecord$1(parameter.examples)) {
1574
+ const examples = [];
1575
+ for (const [key, example] of Object.entries(parameter.examples)) {
1576
+ const value = getExampleValue(example);
1577
+ if (typeof value === "undefined") continue;
1578
+ const { title, summary } = getExampleTitle(key, example);
1579
+ examples.push({
1580
+ key,
1581
+ title,
1582
+ summary,
1583
+ value
1584
+ });
1585
+ }
1586
+ if (examples.length > 0) return examples;
1587
+ }
1588
+ return typeof parameter.example === "undefined" ? [] : [{
1589
+ key: "default",
1590
+ title: "Example",
1591
+ value: parameter.example
1592
+ }];
1593
+ }
1594
+ function getRequestExampleEntries(parameters, mediaType) {
1595
+ const entries = /* @__PURE__ */ new Map();
1596
+ for (const example of getExampleEntries(mediaType).filter((entry) => !entry.generated)) entries.set(example.key, example);
1597
+ for (const parameter of parameters) for (const example of getParameterExampleEntries(parameter)) if (!entries.has(example.key)) entries.set(example.key, example);
1598
+ return [...entries.values()];
1599
+ }
1545
1600
  function getContentExample(mediaType) {
1546
1601
  return getExampleEntries(mediaType)[0]?.value;
1547
1602
  }
@@ -1555,7 +1610,8 @@ function schemaToType(schema) {
1555
1610
  if (Array.isArray(schema.allOf)) return schema.allOf.map((branch) => schemaToType(branch)).filter(Boolean).join(" & ");
1556
1611
  if (schemaHasType(schema, "array")) return `${schemaToType(schema.items) ?? "unknown"}[]`;
1557
1612
  const type = Array.isArray(schema.type) ? schema.type.map(String).join(" | ") : schema.type;
1558
- return typeof type === "string" ? [type, typeof schema.format === "string" ? `<${schema.format}>` : void 0].filter(Boolean).join("") : void 0;
1613
+ const nullableType = schema.nullable === true && type !== "null" ? [type, "null"].filter(Boolean).join(" | ") : type;
1614
+ return typeof nullableType === "string" ? [nullableType, typeof schema.format === "string" ? `<${schema.format}>` : void 0].filter(Boolean).join("") : void 0;
1559
1615
  }
1560
1616
  function schemaToExample(schema, depth = 0) {
1561
1617
  if (!isRecord$1(schema) || depth > 3) return void 0;
@@ -1563,10 +1619,12 @@ function schemaToExample(schema, depth = 0) {
1563
1619
  if (typeof schema.default !== "undefined") return schema.default;
1564
1620
  if (Array.isArray(schema.enum)) return schema.enum[0];
1565
1621
  if (isReference(schema)) return { id: resolveReferenceName(schema.$ref) };
1622
+ const variant = Array.isArray(schema.oneOf) ? schema.oneOf[0] : Array.isArray(schema.anyOf) ? schema.anyOf[0] : void 0;
1623
+ if (typeof variant !== "undefined") return schemaToExample(variant, depth + 1);
1566
1624
  if (schemaHasType(schema, "array")) return [schemaToExample(schema.items, depth + 1) ?? "string"];
1567
1625
  if (schemaHasType(schema, "object") || isRecord$1(schema.properties)) {
1568
1626
  const properties = isRecord$1(schema.properties) ? schema.properties : {};
1569
- return Object.fromEntries(Object.entries(properties).slice(0, 8).map(([name, propertySchema]) => [name, schemaToExample(propertySchema, depth + 1) ?? exampleForType(schemaToType(propertySchema))]));
1627
+ return Object.fromEntries(Object.entries(properties).filter(([, propertySchema]) => !isRecord$1(propertySchema) || propertySchema.readOnly !== true).slice(0, 8).map(([name, propertySchema]) => [name, schemaToExample(propertySchema, depth + 1) ?? exampleForType(schemaToType(propertySchema))]));
1570
1628
  }
1571
1629
  return exampleForType(schemaToType(schema));
1572
1630
  }
@@ -1804,10 +1862,10 @@ function getQueryString(parameters, auth = []) {
1804
1862
  });
1805
1863
  return queryString;
1806
1864
  }
1807
- function isFormMediaType(mediaType) {
1865
+ function isFormMediaType$1(mediaType) {
1808
1866
  return mediaType.includes("multipart/form-data") || mediaType.includes("application/x-www-form-urlencoded");
1809
1867
  }
1810
- function isBinarySchema(schema) {
1868
+ function isBinarySchema$1(schema) {
1811
1869
  return isRecord$1(schema) && schema.type === "string" && schema.format === "binary";
1812
1870
  }
1813
1871
  function getSchemaProperties(schema) {
@@ -1815,7 +1873,7 @@ function getSchemaProperties(schema) {
1815
1873
  }
1816
1874
  function getFieldValue(name, value, schema) {
1817
1875
  if (isRecord$1(value) && typeof value[name] !== "undefined") return value[name];
1818
- if (isBinarySchema(schema)) return `@${name}`;
1876
+ if (isBinarySchema$1(schema)) return `@${name}`;
1819
1877
  }
1820
1878
  function getFormParams(value, requestContent) {
1821
1879
  const properties = getSchemaProperties(requestContent.value.schema);
@@ -1837,7 +1895,7 @@ function getBodySize(requestBody) {
1837
1895
  function getRequestBody(requestContent) {
1838
1896
  const value = getContentExample(requestContent?.value);
1839
1897
  if (!requestContent || typeof value === "undefined") return void 0;
1840
- if (isFormMediaType(requestContent.mediaType)) {
1898
+ if (isFormMediaType$1(requestContent.mediaType)) {
1841
1899
  const params = getFormParams(value, requestContent);
1842
1900
  return params.length > 0 ? { params } : void 0;
1843
1901
  }
@@ -3156,7 +3214,7 @@ function OptionContent(arg0) {
3156
3214
  })] });
3157
3215
  }
3158
3216
  function InlineListbox(arg0) {
3159
- const { label, value, options, onChange, compact = false, buttonContent, buttonClassName, className, invalid, describedBy, disabled = false } = arg0;
3217
+ const { label, value, options, onChange, compact = false, buttonContent, buttonClassName, className, invalid, describedBy, disabled = false, title } = arg0;
3160
3218
  const selected = options.find((option) => option.value === value);
3161
3219
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Listbox, {
3162
3220
  value,
@@ -3168,6 +3226,7 @@ function InlineListbox(arg0) {
3168
3226
  "aria-label": label,
3169
3227
  "aria-invalid": invalid || void 0,
3170
3228
  "aria-describedby": describedBy,
3229
+ title,
3171
3230
  className: (0, clsx.default)(buttonClassName ?? defaultButtonClassName, buttonClassName ? null : compact ? "min-h-7 max-w-32 px-2 py-0.5 text-xs" : "min-h-8 w-full px-2 text-xs"),
3172
3231
  children: buttonContent ?? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3173
3232
  className: "truncate",
@@ -3345,7 +3404,8 @@ function parseBodyObject(body) {
3345
3404
  return;
3346
3405
  }
3347
3406
  }
3348
- function buildRequestBody(body, mediaType) {
3407
+ function buildRequestBody(body, mediaType, files) {
3408
+ if (files[""] && !mediaType.includes("multipart/form-data")) return files[""];
3349
3409
  const values = parseBodyObject(body);
3350
3410
  if (mediaType.includes("application/x-www-form-urlencoded") && values) {
3351
3411
  const params = new URLSearchParams();
@@ -3354,7 +3414,18 @@ function buildRequestBody(body, mediaType) {
3354
3414
  }
3355
3415
  if (mediaType.includes("multipart/form-data") && values) {
3356
3416
  const form = new FormData();
3357
- Object.entries(values).forEach(([name, value]) => form.append(name, typeof value === "string" ? value : JSON.stringify(value)));
3417
+ Object.entries(values).forEach(([name, value]) => {
3418
+ const file = files[name];
3419
+ form.append(name, file ?? (typeof value === "string" ? value : JSON.stringify(value)));
3420
+ });
3421
+ Object.entries(files).forEach(([name, file]) => {
3422
+ if (name && !(name in values)) form.append(name, file);
3423
+ });
3424
+ return form;
3425
+ }
3426
+ if (mediaType.includes("multipart/form-data") && Object.keys(files).length > 0) {
3427
+ const form = new FormData();
3428
+ Object.entries(files).forEach(([name, file]) => form.append(name, file));
3358
3429
  return form;
3359
3430
  }
3360
3431
  return body;
@@ -3457,9 +3528,9 @@ function buildApiRequest(input) {
3457
3528
  }
3458
3529
  const url = new URL(joinPath(expandServerUrl(input.server, input.serverVariables ?? {}), path), input.baseUrl);
3459
3530
  query.forEach((value, key) => url.searchParams.append(key, value));
3460
- const body = input.body?.trim();
3531
+ const body = input.body?.trim() ?? "";
3461
3532
  const mediaType = input.mediaType || "application/json";
3462
- const requestBody = body && input.method.toUpperCase() !== "GET" && input.method.toUpperCase() !== "HEAD" ? buildRequestBody(body, mediaType) : void 0;
3533
+ const requestBody = (Boolean(body) || Object.keys(input.bodyFiles ?? {}).length > 0) && input.method.toUpperCase() !== "GET" && input.method.toUpperCase() !== "HEAD" ? buildRequestBody(body, mediaType, input.bodyFiles ?? {}) : void 0;
3463
3534
  if (requestBody && !(requestBody instanceof FormData)) headers.set("Content-Type", mediaType);
3464
3535
  return {
3465
3536
  url: url.toString(),
@@ -3518,6 +3589,157 @@ function OpenApiAuthPanel(arg0) {
3518
3589
  });
3519
3590
  }
3520
3591
  //#endregion
3592
+ //#region source/openapi/components/OpenApiRequestBodyEditor.tsx
3593
+ function parseBodyRecord(body) {
3594
+ try {
3595
+ const value = JSON.parse(body);
3596
+ return isRecord$1(value) ? value : {};
3597
+ } catch {
3598
+ return {};
3599
+ }
3600
+ }
3601
+ function isBinarySchema(schema) {
3602
+ return isRecord$1(schema) && schema.format === "binary";
3603
+ }
3604
+ function isTextMediaType(mediaType) {
3605
+ return mediaType.startsWith("text/") || mediaType.includes("json") || mediaType.includes("xml") || mediaType.includes("yaml") || mediaType.includes("javascript") || mediaType.includes("form");
3606
+ }
3607
+ function isFormMediaType(mediaType) {
3608
+ const normalized = mediaType.split(";", 1)[0].trim().toLowerCase();
3609
+ return normalized === "application/x-www-form-urlencoded" || normalized === "multipart/form-data";
3610
+ }
3611
+ function valueFromInput(schema, value) {
3612
+ if (!isRecord$1(schema)) return value;
3613
+ if (schemaHasType(schema, "integer")) return value === "" ? "" : Number.parseInt(value, 10);
3614
+ if (schemaHasType(schema, "number")) return value === "" ? "" : Number(value);
3615
+ if (schemaHasType(schema, "boolean")) return value === "true";
3616
+ if (schemaHasType(schema, "array") || schemaHasType(schema, "object")) try {
3617
+ return JSON.parse(value);
3618
+ } catch {
3619
+ return value;
3620
+ }
3621
+ return value;
3622
+ }
3623
+ function OpenApiRequestBodyEditor(arg0) {
3624
+ const { spec, mediaType, content, body, files, onBodyChange, onFileChange } = arg0;
3625
+ const schema = resolveSchema(spec, content?.schema);
3626
+ const schemaRecord = isRecord$1(schema) ? schema : void 0;
3627
+ const properties = isRecord$1(schemaRecord?.properties) ? schemaRecord.properties : void 0;
3628
+ const required = new Set(Array.isArray(schemaRecord?.required) ? schemaRecord.required.map(String) : []);
3629
+ const values = parseBodyRecord(body);
3630
+ function updateProperty(name, propertySchema, value) {
3631
+ onBodyChange(JSON.stringify({
3632
+ ...values,
3633
+ [name]: valueFromInput(propertySchema, value)
3634
+ }, null, 2));
3635
+ }
3636
+ function renderProperty(name, unresolvedSchema) {
3637
+ const propertySchema = resolveSchema(spec, unresolvedSchema);
3638
+ const propertyRecord = isRecord$1(propertySchema) ? propertySchema : void 0;
3639
+ const type = schemaToType(propertySchema) ?? "string";
3640
+ const value = values[name];
3641
+ const fieldId = `openapi-request-body-${name}`.replace(/[^a-zA-Z0-9_-]/g, "-");
3642
+ const options = Array.isArray(propertyRecord?.enum) ? propertyRecord.enum : [];
3643
+ const structured = schemaHasType(propertySchema, "array") || schemaHasType(propertySchema, "object");
3644
+ const serializedValue = structured && typeof value !== "undefined" ? JSON.stringify(value, null, 2) : String(value ?? "");
3645
+ let control;
3646
+ if (isBinarySchema(propertySchema)) control = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3647
+ id: fieldId,
3648
+ "aria-label": name,
3649
+ type: "file",
3650
+ required: required.has(name),
3651
+ onChange: (event) => onFileChange(name, event.target.files?.[0]),
3652
+ className: "min-h-8 w-full px-2 py-1 text-xs text-(--clarify-theme-tokens-colors-foreground) file:mr-2 file:rounded-(--clarify-theme-tokens-radius-md) file:border file:border-(--clarify-theme-tokens-colors-border) file:bg-(--clarify-ui-subtle-background) file:px-2 file:py-1 file:text-xs file:text-(--clarify-ui-text-strong)"
3653
+ });
3654
+ else if (options.length > 0) control = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
3655
+ id: fieldId,
3656
+ "aria-label": name,
3657
+ value: serializedValue,
3658
+ required: required.has(name),
3659
+ onChange: (event) => updateProperty(name, propertySchema, event.target.value),
3660
+ className: "h-8 w-full border-0 bg-transparent px-2 font-mono text-xs text-(--clarify-theme-tokens-colors-foreground) outline-hidden focus:bg-(--clarify-ui-hover-background)",
3661
+ children: [!required.has(name) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { value: "" }) : null, options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3662
+ value: String(option),
3663
+ children: String(option)
3664
+ }, String(option)))]
3665
+ });
3666
+ else if (schemaHasType(propertySchema, "boolean")) control = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3667
+ id: fieldId,
3668
+ "aria-label": name,
3669
+ type: "checkbox",
3670
+ checked: value === true,
3671
+ onChange: (event) => updateProperty(name, propertySchema, String(event.target.checked)),
3672
+ className: "size-4 accent-(--clarify-theme-tokens-colors-primary)"
3673
+ });
3674
+ else if (structured) control = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
3675
+ id: fieldId,
3676
+ "aria-label": name,
3677
+ value: serializedValue,
3678
+ required: required.has(name),
3679
+ rows: 3,
3680
+ spellCheck: false,
3681
+ onChange: (event) => updateProperty(name, propertySchema, event.target.value),
3682
+ className: "w-full resize-y border-0 bg-transparent p-2 font-mono text-xs/5 text-(--clarify-theme-tokens-colors-foreground) outline-hidden focus:bg-(--clarify-ui-hover-background)"
3683
+ });
3684
+ else control = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3685
+ id: fieldId,
3686
+ "aria-label": name,
3687
+ value: serializedValue,
3688
+ type: schemaHasType(propertySchema, "integer") || schemaHasType(propertySchema, "number") ? "number" : propertyRecord?.format === "date" ? "date" : propertyRecord?.format === "date-time" ? "datetime-local" : "text",
3689
+ required: required.has(name),
3690
+ onChange: (event) => updateProperty(name, propertySchema, event.target.value),
3691
+ className: "h-8 w-full border-0 bg-transparent px-2 font-mono text-xs text-(--clarify-theme-tokens-colors-foreground) outline-hidden focus:bg-(--clarify-ui-hover-background)"
3692
+ });
3693
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3694
+ className: "grid min-w-0 grid-cols-[minmax(0,1fr)_minmax(0,1.3fr)]",
3695
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3696
+ htmlFor: fieldId,
3697
+ className: "flex min-h-8 min-w-0 items-center gap-1.5 border-r border-(--clarify-theme-tokens-colors-border) px-2 text-xs text-(--clarify-ui-text-strong)",
3698
+ children: [
3699
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3700
+ className: "truncate font-mono",
3701
+ children: name
3702
+ }),
3703
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3704
+ className: "font-mono text-2xs text-(--clarify-ui-text-faint)",
3705
+ children: type
3706
+ }),
3707
+ required.has(name) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3708
+ className: "text-(--clarify-error-accent-text)",
3709
+ children: "*"
3710
+ }) : null
3711
+ ]
3712
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3713
+ className: "flex min-w-0 items-center",
3714
+ children: [control, files[name] ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3715
+ className: "sr-only",
3716
+ children: files[name].name
3717
+ }) : null]
3718
+ })]
3719
+ }, name);
3720
+ }
3721
+ if (properties && isFormMediaType(mediaType)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3722
+ className: "divide-y divide-(--clarify-theme-tokens-colors-border)",
3723
+ children: Object.entries(properties).map(([name, propertySchema]) => renderProperty(name, propertySchema))
3724
+ });
3725
+ if (isBinarySchema(schema) || !isTextMediaType(mediaType)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3726
+ className: "flex min-h-44 items-start p-3",
3727
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3728
+ "aria-label": mediaType,
3729
+ type: "file",
3730
+ onChange: (event) => onFileChange("", event.target.files?.[0]),
3731
+ className: "w-full text-xs text-(--clarify-theme-tokens-colors-foreground) file:mr-2 file:rounded-(--clarify-theme-tokens-radius-md) file:border file:border-(--clarify-theme-tokens-colors-border) file:bg-(--clarify-ui-subtle-background) file:px-2 file:py-1 file:text-xs file:text-(--clarify-ui-text-strong)"
3732
+ })
3733
+ });
3734
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
3735
+ "aria-label": mediaType,
3736
+ value: body,
3737
+ onChange: (event) => onBodyChange(event.target.value),
3738
+ spellCheck: false,
3739
+ className: "block h-full min-h-44 w-full resize-none border-0 bg-(--clarify-code-background) p-3 font-mono text-xs/5 text-(--clarify-code-text) outline-hidden focus:ring-2 focus:ring-inset focus:ring-(--clarify-theme-tokens-colors-primary)"
3740
+ });
3741
+ }
3742
+ //#endregion
3521
3743
  //#region source/openapi/components/OpenApiRequestFields.tsx
3522
3744
  function RequestField(arg0) {
3523
3745
  const { spec, parameter, value, enabled, onChange, onEnabledChange, issue } = arg0;
@@ -3554,7 +3776,7 @@ function RequestField(arg0) {
3554
3776
  children: description
3555
3777
  }),
3556
3778
  side: "bottom",
3557
- className: "mr-1 shrink-0 [&>[role=tooltip]]:w-80 [&>[role=tooltip]]:max-w-[min(20rem,calc(100vw-2rem))] [&>[role=tooltip]]:border [&>[role=tooltip]]:border-(--clarify-theme-tokens-colors-border) [&>[role=tooltip]]:bg-(--clarify-theme-tokens-colors-surface) [&>[role=tooltip]]:p-3 [&>[role=tooltip]]:text-(--clarify-ui-text) [&>[role=tooltip]]:shadow-xl",
3779
+ className: "mr-1 shrink-0 *:[[role=tooltip]]:w-80 *:[[role=tooltip]]:max-w-[min(20rem,calc(100vw-2rem))] *:[[role=tooltip]]:border *:[[role=tooltip]]:border-(--clarify-theme-tokens-colors-border) *:[[role=tooltip]]:bg-(--clarify-theme-tokens-colors-surface) *:[[role=tooltip]]:p-3 *:[[role=tooltip]]:text-(--clarify-ui-text) *:[[role=tooltip]]:shadow-xl",
3558
3780
  triggerClassName: "clarify-field-description-trigger clarify-ui-control inline-flex size-7 items-center justify-center rounded-md !border-b-0 text-(--clarify-ui-text-faint) transition-colors",
3559
3781
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.InfoIcon, {
3560
3782
  className: "size-4",
@@ -3600,7 +3822,7 @@ function RequestField(arg0) {
3600
3822
  })
3601
3823
  }),
3602
3824
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3603
- className: (0, clsx.default)("col-start-2 flex min-w-0 items-center border-t border-(--clarify-theme-tokens-colors-border) sm:col-start-3 sm:row-start-1 sm:border-t-0", !enabled && "opacity-45"),
3825
+ className: (0, clsx.default)("col-start-2 flex min-w-0 items-center border-t border-(--clarify-theme-tokens-colors-border) sm:col-start-3 sm:row-start-1 sm:border-t-0", !enabled && "bg-(--clarify-ui-subtle-background)"),
3604
3826
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3605
3827
  className: "min-w-0 flex-1",
3606
3828
  children: itemOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiInlineListbox, {
@@ -3713,6 +3935,57 @@ function parseJson(value) {
3713
3935
  return;
3714
3936
  }
3715
3937
  }
3938
+ var textLanguages = {
3939
+ "application/graphql": "graphql",
3940
+ "application/javascript": "javascript",
3941
+ "application/sql": "sql",
3942
+ "application/typescript": "typescript",
3943
+ "application/xml": "xml",
3944
+ "application/x-httpd-php": "php",
3945
+ "application/x-sh": "shellscript",
3946
+ "application/xhtml+xml": "html",
3947
+ "application/x-www-form-urlencoded": "http",
3948
+ "text/css": "css",
3949
+ "text/csv": "csv",
3950
+ "text/html": "html",
3951
+ "text/javascript": "javascript",
3952
+ "text/markdown": "markdown",
3953
+ "text/plain": "text",
3954
+ "text/xml": "xml"
3955
+ };
3956
+ function normalizedMediaType(contentType) {
3957
+ return contentType.split(";", 1)[0].trim().toLowerCase();
3958
+ }
3959
+ function getResponseTextPreview(contentType, body) {
3960
+ const mediaType = normalizedMediaType(contentType);
3961
+ if (mediaType === "application/json" || mediaType.endsWith("+json")) {
3962
+ const parsed = parseJson(body);
3963
+ return {
3964
+ code: typeof parsed === "undefined" ? body : JSON.stringify(parsed, null, 2),
3965
+ language: "json"
3966
+ };
3967
+ }
3968
+ if (mediaType === "application/yaml" || mediaType === "application/x-yaml" || mediaType === "text/yaml" || mediaType === "text/x-yaml" || mediaType.endsWith("+yaml")) try {
3969
+ return {
3970
+ code: (0, yaml.stringify)((0, yaml.parse)(body)).trimEnd(),
3971
+ language: "yaml"
3972
+ };
3973
+ } catch {
3974
+ return {
3975
+ code: body,
3976
+ language: "yaml"
3977
+ };
3978
+ }
3979
+ const language = textLanguages[mediaType] ?? (mediaType.startsWith("text/") ? mediaType.slice(5) || "text" : void 0);
3980
+ return language ? {
3981
+ code: body,
3982
+ language
3983
+ } : void 0;
3984
+ }
3985
+ function canPreviewResponse(contentType) {
3986
+ const mediaType = normalizedMediaType(contentType);
3987
+ return Boolean(getResponseTextPreview(contentType, "") || mediaType.startsWith("image/") || mediaType.startsWith("audio/") || mediaType.startsWith("video/"));
3988
+ }
3716
3989
  function ResponseState(arg0) {
3717
3990
  const { icon: Icon, title, description, tone = "default" } = arg0;
3718
3991
  const error = tone === "error";
@@ -3741,38 +4014,6 @@ function ResponseState(arg0) {
3741
4014
  })
3742
4015
  });
3743
4016
  }
3744
- function JsonPreview(arg0) {
3745
- const { value } = arg0;
3746
- if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3747
- className: "space-y-1 border-l border-(--clarify-code-border) pl-3",
3748
- children: value.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3749
- className: "mr-2 text-(--clarify-code-faint)",
3750
- children: index
3751
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(JsonPreview, { value: item })] }, index))
3752
- });
3753
- if (isRecord$1(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3754
- className: "space-y-1 border-l border-(--clarify-code-border) pl-3",
3755
- children: Object.entries(value).map(([key, item]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3756
- className: "grid grid-cols-[minmax(5rem,auto)_1fr] gap-3",
3757
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3758
- className: "text-(--clarify-code-property)",
3759
- children: key
3760
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(JsonPreview, { value: item })]
3761
- }, key))
3762
- });
3763
- if (value === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3764
- className: "text-(--clarify-code-faint)",
3765
- children: "null"
3766
- });
3767
- if (typeof value === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3768
- className: "wrap-break-word text-(--clarify-code-string)",
3769
- children: value
3770
- });
3771
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3772
- className: "text-(--clarify-code-number)",
3773
- children: String(value)
3774
- });
3775
- }
3776
4017
  function CopyButton(arg0) {
3777
4018
  const { value } = arg0;
3778
4019
  const t = require_i18n.useBuiltInText();
@@ -3829,22 +4070,12 @@ function ResponseMedia(arg0) {
3829
4070
  function ResponsePreview(arg0) {
3830
4071
  const { exchange } = arg0;
3831
4072
  const t = require_i18n.useBuiltInText();
3832
- const contentType = exchange.contentType.toLowerCase();
4073
+ const contentType = normalizedMediaType(exchange.contentType);
3833
4074
  if (!exchange.size) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseState, {
3834
4075
  icon: lucide_react.FileX2Icon,
3835
4076
  title: t("openapi.responseBodyEmptyTitle"),
3836
4077
  description: t("openapi.responseBodyEmpty")
3837
4078
  });
3838
- if (contentType.includes("json")) {
3839
- const parsed = parseJson(exchange.body);
3840
- return typeof parsed === "undefined" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
3841
- className: "whitespace-pre-wrap wrap-break-word font-mono text-xs/5",
3842
- children: exchange.body
3843
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3844
- className: "overflow-auto font-mono text-xs/5",
3845
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(JsonPreview, { value: parsed })
3846
- });
3847
- }
3848
4079
  if (contentType.startsWith("image/")) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseMedia, {
3849
4080
  blob: exchange.blob,
3850
4081
  type: "image"
@@ -3857,15 +4088,19 @@ function ResponsePreview(arg0) {
3857
4088
  blob: exchange.blob,
3858
4089
  type: "video"
3859
4090
  });
3860
- if (contentType.includes("html")) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
4091
+ if (contentType === "text/html" || contentType === "application/xhtml+xml") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
3861
4092
  srcDoc: exchange.body,
3862
4093
  sandbox: "",
3863
4094
  title: "Response preview",
3864
4095
  className: "h-96 w-full border-0 bg-white"
3865
4096
  });
3866
- if (contentType.startsWith("text/") || contentType.includes("xml") || contentType.includes("yaml")) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
3867
- className: "whitespace-pre-wrap wrap-break-word font-mono text-xs/5",
3868
- children: exchange.body
4097
+ const textPreview = getResponseTextPreview(exchange.contentType, exchange.body);
4098
+ if (textPreview) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
4099
+ className: "max-h-128 overflow-auto whitespace-pre-wrap wrap-break-word font-mono text-xs/5",
4100
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightedCode, {
4101
+ code: textPreview.code,
4102
+ language: textPreview.language
4103
+ })
3869
4104
  });
3870
4105
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3871
4106
  className: "grid min-h-56 place-items-center text-xs text-(--clarify-code-faint)",
@@ -3972,7 +4207,10 @@ function HiddenCookies() {
3972
4207
  function OpenApiResponseViewer(arg0) {
3973
4208
  const { exchange, error } = arg0;
3974
4209
  const t = require_i18n.useBuiltInText();
3975
- const [bodyMode, setBodyMode] = (0, react.useState)("preview");
4210
+ const [bodyModeSelection, setBodyModeSelection] = (0, react.useState)();
4211
+ const previewAvailable = exchange ? canPreviewResponse(exchange.contentType) : false;
4212
+ const selectedBodyMode = bodyModeSelection && bodyModeSelection.exchange === exchange ? bodyModeSelection.mode : "preview";
4213
+ const activeBodyMode = previewAvailable ? selectedBodyMode : "raw";
3976
4214
  function downloadBody() {
3977
4215
  if (!exchange) return;
3978
4216
  const url = URL.createObjectURL(exchange.blob);
@@ -4054,12 +4292,15 @@ function OpenApiResponseViewer(arg0) {
4054
4292
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4055
4293
  role: "tablist",
4056
4294
  className: "flex",
4057
- children: ["preview", "raw"].map((mode) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4295
+ children: ["preview", "raw"].filter((mode) => mode === "raw" || previewAvailable).map((mode) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4058
4296
  type: "button",
4059
4297
  role: "tab",
4060
- "aria-selected": bodyMode === mode,
4061
- onClick: () => setBodyMode(mode),
4062
- className: (0, clsx.default)("border-b-2 px-2.5 py-1 text-2xs font-semibold", bodyMode === mode ? "border-(--clarify-theme-tokens-colors-primary) text-(--clarify-code-text)" : "border-transparent text-(--clarify-code-muted)"),
4298
+ "aria-selected": activeBodyMode === mode,
4299
+ onClick: () => setBodyModeSelection({
4300
+ exchange,
4301
+ mode
4302
+ }),
4303
+ className: (0, clsx.default)("border-b-2 px-2.5 py-1 text-2xs font-semibold", activeBodyMode === mode ? "border-(--clarify-theme-tokens-colors-primary) text-(--clarify-code-text)" : "border-transparent text-(--clarify-code-muted)"),
4063
4304
  children: mode === "preview" ? t("openapi.preview") : t("openapi.raw")
4064
4305
  }, mode))
4065
4306
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4078,7 +4319,7 @@ function OpenApiResponseViewer(arg0) {
4078
4319
  })]
4079
4320
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4080
4321
  className: "p-4",
4081
- children: bodyMode === "preview" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponsePreview, { exchange }) : exchange.size ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
4322
+ children: activeBodyMode === "preview" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponsePreview, { exchange }) : exchange.size ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
4082
4323
  className: "max-h-128 overflow-auto whitespace-pre-wrap wrap-break-word font-mono text-xs/5",
4083
4324
  children: exchange.body
4084
4325
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -4200,6 +4441,23 @@ function validateRequestParameters(spec, parameters, values) {
4200
4441
  }
4201
4442
  //#endregion
4202
4443
  //#region source/openapi/components/useOpenApiRequestState.ts
4444
+ function initialRequestBody(spec, content) {
4445
+ const example = getExampleEntries(content, spec)[0];
4446
+ if (!example?.generated) return stringifyExample(example?.value);
4447
+ const schema = resolveSchema(spec, content?.schema);
4448
+ if (isRecord$1(schema) && schema.format === "binary") return "";
4449
+ if (!isRecord$1(example.value) || !isRecord$1(schema) || !isRecord$1(schema.properties)) return stringifyExample(example.value);
4450
+ const value = { ...example.value };
4451
+ Object.entries(schema.properties).forEach(([name, propertySchema]) => {
4452
+ const resolved = resolveSchema(spec, propertySchema);
4453
+ if (isRecord$1(resolved) && resolved.format === "binary") delete value[name];
4454
+ });
4455
+ return stringifyExample(value);
4456
+ }
4457
+ function requestBodyForExample(spec, content, exampleKey) {
4458
+ const example = getExampleEntries(content, spec).find((entry) => !entry.generated && entry.key === exampleKey);
4459
+ return example ? stringifyExample(example.value) : initialRequestBody(spec, content);
4460
+ }
4203
4461
  function useOpenApiRequestTarget(spec, path, operation, operationSource) {
4204
4462
  const servers = getServers(spec, operation, path, operationSource);
4205
4463
  const [selectedServerKey, setSelectedServerKey] = (0, react.useState)(getServerKey(servers[0], 0));
@@ -4214,7 +4472,9 @@ function useOpenApiRequestTarget(spec, path, operation, operationSource) {
4214
4472
  const clearCredential = useOpenApiStore((state) => state.clearCredential);
4215
4473
  const requestContents = getMediaTypeEntries(getRequestBody$1(spec, operation)?.content, spec);
4216
4474
  const [mediaType, setMediaType] = (0, react.useState)(requestContents[0]?.mediaType ?? "");
4217
- const [body, setBody] = (0, react.useState)(stringifyExample(getExampleEntries((requestContents.find((entry) => entry.mediaType === mediaType) ?? requestContents[0])?.value, spec)[0]?.value));
4475
+ const selectedContent = requestContents.find((entry) => entry.mediaType === mediaType) ?? requestContents[0];
4476
+ const [body, setBody] = (0, react.useState)(initialRequestBody(spec, selectedContent?.value));
4477
+ const [bodyFiles, setBodyFiles] = (0, react.useState)({});
4218
4478
  function selectServer(value) {
4219
4479
  const nextServer = servers.find((server, index) => getServerKey(server, index) === value) ?? servers[0];
4220
4480
  setSelectedServerKey(value);
@@ -4223,7 +4483,20 @@ function useOpenApiRequestTarget(spec, path, operation, operationSource) {
4223
4483
  function selectMediaType(value) {
4224
4484
  const content = requestContents.find((entry) => entry.mediaType === value)?.value;
4225
4485
  setMediaType(value);
4226
- setBody(stringifyExample(getExampleEntries(content, spec)[0]?.value));
4486
+ setBody(initialRequestBody(spec, content));
4487
+ setBodyFiles({});
4488
+ }
4489
+ function applyBodyExample(exampleKey) {
4490
+ setBody(requestBodyForExample(spec, selectedContent?.value, exampleKey));
4491
+ setBodyFiles({});
4492
+ }
4493
+ function setBodyFile(name, file) {
4494
+ setBodyFiles((current) => {
4495
+ const next = { ...current };
4496
+ if (file) next[name] = file;
4497
+ else delete next[name];
4498
+ return next;
4499
+ });
4227
4500
  }
4228
4501
  return {
4229
4502
  servers,
@@ -4243,13 +4516,20 @@ function useOpenApiRequestTarget(spec, path, operation, operationSource) {
4243
4516
  clearCredential,
4244
4517
  requestContents,
4245
4518
  mediaType,
4519
+ selectedContent,
4246
4520
  body,
4247
4521
  setBody,
4522
+ bodyFiles,
4523
+ setBodyFile,
4524
+ applyBodyExample,
4248
4525
  selectMediaType
4249
4526
  };
4250
4527
  }
4251
- function useOpenApiParameterState(spec, parameters, initialParameterValue) {
4252
- const [parameterValues, setParameterValues] = (0, react.useState)(() => Object.fromEntries(parameters.map((parameter) => [parameterKey(parameter), initialParameterValue(parameter)])));
4528
+ function useOpenApiParameterState(spec, parameters, initialParameterValue, initialExampleKey = "") {
4529
+ const [parameterValues, setParameterValues] = (0, react.useState)(() => Object.fromEntries(parameters.map((parameter) => {
4530
+ const example = getParameterExampleEntries(parameter).find((entry) => entry.key === initialExampleKey);
4531
+ return [parameterKey(parameter), example ? stringifyExample(example.value) : initialParameterValue(parameter)];
4532
+ })));
4253
4533
  const [parameterEnabled, setParameterEnabled] = (0, react.useState)(() => Object.fromEntries(parameters.map((parameter) => [parameterKey(parameter), true])));
4254
4534
  const [parameterIssues, setParameterIssues] = (0, react.useState)({});
4255
4535
  function setParameterGroupValues(grouped, mode) {
@@ -4284,6 +4564,13 @@ function useOpenApiParameterState(spec, parameters, initialParameterValue) {
4284
4564
  return next;
4285
4565
  });
4286
4566
  }
4567
+ function applyParameterExample(exampleKey) {
4568
+ setParameterValues(Object.fromEntries(parameters.map((parameter) => {
4569
+ const example = getParameterExampleEntries(parameter).find((entry) => entry.key === exampleKey);
4570
+ return [parameterKey(parameter), example ? stringifyExample(example.value) : initialParameterValue(parameter)];
4571
+ })));
4572
+ setParameterIssues({});
4573
+ }
4287
4574
  function validate(parametersToValidate) {
4288
4575
  const issues = validateRequestParameters(spec, parametersToValidate, parameterValues);
4289
4576
  setParameterIssues(issues);
@@ -4296,6 +4583,7 @@ function useOpenApiParameterState(spec, parameters, initialParameterValue) {
4296
4583
  setParameterGroupValues,
4297
4584
  setParameterIncluded,
4298
4585
  updateParameterValue,
4586
+ applyParameterExample,
4299
4587
  validate
4300
4588
  };
4301
4589
  }
@@ -4335,6 +4623,7 @@ function useOpenApiRequestExecution() {
4335
4623
  //#endregion
4336
4624
  //#region source/openapi/components/OpenApiRequest.tsx
4337
4625
  function initialParameterValue(spec, parameter) {
4626
+ if (typeof parameter.example !== "undefined") return stringifyExample(parameter.example);
4338
4627
  const schema = resolveSchema(spec, parameter.schema);
4339
4628
  if (!isRecord$1(schema)) return "";
4340
4629
  return stringifyExample(schema.example ?? schema.default ?? (Array.isArray(schema.enum) ? schema.enum[0] : void 0));
@@ -4349,9 +4638,12 @@ function OpenApiRequestWorkbench(arg0) {
4349
4638
  const { spec, path, method, operation, operationSource = "path", compact = false, onClose } = arg0;
4350
4639
  const t = require_i18n.useBuiltInText();
4351
4640
  const parameters = getOperationParameters(spec, path, operation, operationSource);
4352
- const { servers, selectedServer, selectedServerKey, serverVariables, setServerVariables, serverVariableEntries, selectServer, authOptions, selectedAuthName, setSelectedAuthName, selectedAuth, credentialScope, credentials, setCredential, clearCredential, requestContents, mediaType, body, setBody, selectMediaType } = useOpenApiRequestTarget(spec, path, operation, operationSource);
4353
- const parameterState = useOpenApiParameterState(spec, parameters, (parameter) => initialParameterValue(spec, parameter));
4354
- const { parameterValues, parameterEnabled, parameterIssues, setParameterGroupValues, setParameterIncluded, updateParameterValue } = parameterState;
4641
+ const { servers, selectedServer, selectedServerKey, serverVariables, setServerVariables, serverVariableEntries, selectServer, authOptions, selectedAuthName, setSelectedAuthName, selectedAuth, credentialScope, credentials, setCredential, clearCredential, requestContents, mediaType, selectedContent, body, setBody, bodyFiles, setBodyFile, applyBodyExample, selectMediaType } = useOpenApiRequestTarget(spec, path, operation, operationSource);
4642
+ const requestExamples = getRequestExampleEntries(parameters, selectedContent?.value);
4643
+ const [selectedRequestExampleKey, setSelectedRequestExampleKey] = (0, react.useState)(requestExamples[0]?.key ?? "");
4644
+ const currentRequestExampleKey = requestExamples.some((example) => example.key === selectedRequestExampleKey) ? selectedRequestExampleKey : requestExamples[0]?.key ?? "";
4645
+ const parameterState = useOpenApiParameterState(spec, parameters, (parameter) => initialParameterValue(spec, parameter), currentRequestExampleKey);
4646
+ const { parameterValues, parameterEnabled, parameterIssues, setParameterGroupValues, setParameterIncluded, updateParameterValue, applyParameterExample } = parameterState;
4355
4647
  const { exchange, error, sending, execute } = useOpenApiRequestExecution();
4356
4648
  const parameterGroups = [
4357
4649
  "cookie",
@@ -4363,6 +4655,18 @@ function OpenApiRequestWorkbench(arg0) {
4363
4655
  })).filter((group) => group.parameters.length > 0);
4364
4656
  const pathParameters = parameters.filter((parameter) => parameter.in === "path");
4365
4657
  const hasRequestConfiguration = authOptions.length > 0 || serverVariableEntries.length > 0 || parameters.length > 0 || requestContents.length > 0;
4658
+ function applyRequestExample(exampleKey) {
4659
+ setSelectedRequestExampleKey(exampleKey);
4660
+ applyParameterExample(exampleKey);
4661
+ applyBodyExample(exampleKey);
4662
+ }
4663
+ function selectRequestMediaType(value) {
4664
+ const content = requestContents.find((entry) => entry.mediaType === value)?.value;
4665
+ const nextExampleKey = getRequestExampleEntries(parameters, content)[0]?.key ?? "";
4666
+ selectMediaType(value);
4667
+ setSelectedRequestExampleKey(nextExampleKey);
4668
+ applyParameterExample(nextExampleKey);
4669
+ }
4366
4670
  async function sendRequest() {
4367
4671
  const enabledParameters = parameters.filter((parameter) => parameterEnabled[parameterKey(parameter)] !== false);
4368
4672
  const issues = parameterState.validate(enabledParameters);
@@ -4381,6 +4685,7 @@ function OpenApiRequestWorkbench(arg0) {
4381
4685
  })),
4382
4686
  mediaType,
4383
4687
  body,
4688
+ bodyFiles,
4384
4689
  baseUrl: window.location.href
4385
4690
  }), t("openapi.requestCorsHint"));
4386
4691
  }
@@ -4431,44 +4736,84 @@ function OpenApiRequestWorkbench(arg0) {
4431
4736
  }, location);
4432
4737
  }
4433
4738
  function renderHeader() {
4434
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4435
- className: "flex min-w-0 items-center gap-1.5 border-b border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) px-2.5 py-2",
4436
- children: [
4437
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointMethodBadge, { method: method.toUpperCase() }),
4438
- servers.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InlineListbox, {
4439
- label: t("openapi.server"),
4440
- value: selectedServerKey,
4441
- options: servers.map((server, index) => ({
4442
- value: getServerKey(server, index),
4443
- label: server.url ?? `Server ${index + 1}`,
4444
- description: server.description
4445
- })),
4446
- onChange: selectServer,
4447
- className: "min-w-0 max-w-48 shrink sm:max-w-48",
4448
- buttonClassName: "flex h-8 min-w-0 max-w-full items-center gap-1 rounded-(--clarify-theme-tokens-radius-md) px-2 text-xs font-medium text-(--clarify-ui-text-strong) outline-hidden transition hover:bg-(--clarify-ui-hover-background) focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--clarify-theme-tokens-colors-primary)"
4449
- }) : null,
4450
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4451
- className: "min-w-0 flex-1 overflow-x-auto border-l border-(--clarify-theme-tokens-colors-border) pl-2 font-mono text-xs text-(--clarify-theme-tokens-colors-foreground)",
4452
- children: path || "/"
4453
- }),
4454
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SendRequestButton, {
4455
- label: sending ? t("openapi.sendingRequest") : t("openapi.sendRequest"),
4456
- busy: sending,
4457
- text: t("openapi.sendRequest"),
4458
- onClick: sendRequest
4459
- }),
4460
- onClose ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4461
- type: "button",
4462
- onClick: onClose,
4463
- "aria-label": t("openapi.closeRequest"),
4464
- title: t("openapi.closeRequest"),
4465
- className: "grid size-8 shrink-0 place-items-center rounded-(--clarify-theme-tokens-radius-md) text-(--clarify-ui-text-soft) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-theme-tokens-colors-foreground) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--clarify-theme-tokens-colors-primary)",
4466
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XIcon, {
4467
- className: "size-4",
4468
- "aria-hidden": "true"
4469
- })
4470
- }) : null
4471
- ]
4739
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4740
+ className: "border-b border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface)",
4741
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4742
+ className: "grid min-w-0 grid-cols-[auto_auto_minmax(0,1fr)_auto_auto] items-center gap-1.5 px-2.5 py-2 lg:grid-cols-[auto_auto_minmax(0,1fr)_minmax(0,14rem)_auto_auto]",
4743
+ children: [
4744
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4745
+ className: "col-start-1 row-start-1",
4746
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointMethodBadge, { method: method.toUpperCase() })
4747
+ }),
4748
+ servers.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InlineListbox, {
4749
+ label: t("openapi.server"),
4750
+ value: selectedServerKey,
4751
+ options: servers.map((server, index) => ({
4752
+ value: getServerKey(server, index),
4753
+ label: server.url ?? `Server ${index + 1}`,
4754
+ description: server.description
4755
+ })),
4756
+ onChange: selectServer,
4757
+ title: selectedServer.url ?? t("openapi.server"),
4758
+ buttonContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ServerIcon, {
4759
+ className: "size-4",
4760
+ "aria-hidden": "true"
4761
+ }),
4762
+ className: "col-start-2 row-start-1 size-8 shrink-0",
4763
+ buttonClassName: "grid size-8 place-items-center rounded-(--clarify-theme-tokens-radius-md) bg-(--clarify-ui-subtle-background) text-(--clarify-ui-text-soft) outline-hidden transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong) focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--clarify-theme-tokens-colors-primary) data-open:bg-(--clarify-ui-active-background)"
4764
+ }) : null,
4765
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4766
+ className: "col-start-3 row-start-1 min-w-0 truncate border-l border-(--clarify-theme-tokens-colors-border) pl-2 font-mono text-xs text-(--clarify-theme-tokens-colors-foreground)",
4767
+ title: path || "/",
4768
+ children: path || "/"
4769
+ }),
4770
+ requestExamples.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4771
+ className: "col-span-full row-start-2 flex min-w-0 items-center gap-0.5 border-t border-(--clarify-theme-tokens-colors-border) pt-2 lg:col-span-1 lg:col-start-4 lg:row-start-1 lg:border-t-0 lg:pt-0",
4772
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InlineListbox, {
4773
+ label: t("openapi.requestExample"),
4774
+ value: currentRequestExampleKey,
4775
+ options: requestExamples.map((example) => ({
4776
+ value: example.key,
4777
+ label: example.title,
4778
+ description: example.summary
4779
+ })),
4780
+ onChange: applyRequestExample,
4781
+ className: "min-w-0 flex-1",
4782
+ buttonClassName: "flex h-8 w-full min-w-0 max-w-full items-center gap-1 rounded-(--clarify-theme-tokens-radius-md) px-2 text-xs font-medium text-(--clarify-ui-text-strong) outline-hidden transition hover:bg-(--clarify-ui-hover-background) focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--clarify-theme-tokens-colors-primary)"
4783
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4784
+ type: "button",
4785
+ title: t("openapi.resetToExample"),
4786
+ "aria-label": t("openapi.resetToExample"),
4787
+ onClick: () => applyRequestExample(currentRequestExampleKey),
4788
+ className: "grid size-8 shrink-0 place-items-center rounded-(--clarify-theme-tokens-radius-md) text-(--clarify-ui-text-faint) hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--clarify-theme-tokens-colors-primary)",
4789
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.RotateCcwIcon, {
4790
+ className: "size-3.5",
4791
+ "aria-hidden": "true"
4792
+ })
4793
+ })]
4794
+ }) : null,
4795
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4796
+ className: "col-start-4 row-start-1 lg:col-start-5",
4797
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SendRequestButton, {
4798
+ label: sending ? t("openapi.sendingRequest") : t("openapi.sendRequest"),
4799
+ busy: sending,
4800
+ text: t("openapi.sendRequest"),
4801
+ onClick: sendRequest
4802
+ })
4803
+ }),
4804
+ onClose ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4805
+ type: "button",
4806
+ onClick: onClose,
4807
+ "aria-label": t("openapi.closeRequest"),
4808
+ title: t("openapi.closeRequest"),
4809
+ className: "col-start-5 row-start-1 grid size-8 shrink-0 place-items-center rounded-(--clarify-theme-tokens-radius-md) text-(--clarify-ui-text-soft) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-theme-tokens-colors-foreground) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--clarify-theme-tokens-colors-primary) lg:col-start-6",
4810
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XIcon, {
4811
+ className: "size-4",
4812
+ "aria-hidden": "true"
4813
+ })
4814
+ }) : null
4815
+ ]
4816
+ })
4472
4817
  });
4473
4818
  }
4474
4819
  function renderVariables() {
@@ -4508,13 +4853,15 @@ function OpenApiRequestWorkbench(arg0) {
4508
4853
  value: entry.mediaType,
4509
4854
  label: entry.mediaType
4510
4855
  })),
4511
- onChange: selectMediaType
4512
- }) }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
4513
- "aria-label": t("openapi.requestBody"),
4514
- value: body,
4515
- onChange: (event) => setBody(event.target.value),
4516
- spellCheck: false,
4517
- className: "block h-full min-h-44 w-full resize-none border-0 bg-(--clarify-code-background) p-3 font-mono text-xs/5 text-(--clarify-code-text) outline-hidden focus:ring-2 focus:ring-inset focus:ring-(--clarify-theme-tokens-colors-primary)"
4856
+ onChange: selectRequestMediaType
4857
+ }) }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenApiRequestBodyEditor, {
4858
+ spec,
4859
+ mediaType,
4860
+ content: selectedContent?.value,
4861
+ body,
4862
+ files: bodyFiles,
4863
+ onBodyChange: setBody,
4864
+ onFileChange: setBodyFile
4518
4865
  })]
4519
4866
  });
4520
4867
  }
@@ -5142,4 +5489,4 @@ Object.defineProperty(exports, "primitives_exports", {
5142
5489
  }
5143
5490
  });
5144
5491
 
5145
- //# sourceMappingURL=OpenApiOperation-D-5uE5v7.cjs.map
5492
+ //# sourceMappingURL=OpenApiOperation-D1WNrj5X.cjs.map