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