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