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