@djangocfg/ui-tools 2.1.285 → 2.1.286
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/dist/DocsLayout-BCVU6TTX.cjs +2027 -0
- package/dist/DocsLayout-BCVU6TTX.cjs.map +1 -0
- package/dist/DocsLayout-ERETJLLV.mjs +2020 -0
- package/dist/DocsLayout-ERETJLLV.mjs.map +1 -0
- package/dist/{PlaygroundLayout-O52C6HK5.css → DocsLayout-MBFIB4NO.css} +1 -1
- package/dist/{PrettyCode.client-SGDGQTYT.cjs → PrettyCode.client-5GABIN2I.cjs} +57 -35
- package/dist/PrettyCode.client-5GABIN2I.cjs.map +1 -0
- package/dist/{PrettyCode.client-DW5LTG47.mjs → PrettyCode.client-IZTXXYHG.mjs} +57 -35
- package/dist/PrettyCode.client-IZTXXYHG.mjs.map +1 -0
- package/dist/chunk-IULI4XII.cjs +1129 -0
- package/dist/chunk-IULI4XII.cjs.map +1 -0
- package/dist/chunk-VZGQC3NG.mjs +1100 -0
- package/dist/chunk-VZGQC3NG.mjs.map +1 -0
- package/dist/index.cjs +88 -552
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -6
- package/dist/index.d.ts +18 -6
- package/dist/index.mjs +25 -496
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/tools/OpenapiViewer/.claude/.sidecar/activity.jsonl +4 -0
- package/src/tools/OpenapiViewer/.claude/.sidecar/map_cache.json +30 -0
- package/src/tools/OpenapiViewer/.claude/.sidecar/usage.json +5 -0
- package/src/tools/OpenapiViewer/.claude/project-map.md +23 -0
- package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +28 -2
- package/src/tools/OpenapiViewer/README.md +104 -51
- package/src/tools/OpenapiViewer/components/DocsLayout/ApiIntroSection.tsx +64 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/DocsView.tsx +137 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc.tsx +268 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/SchemaCopyMenu.tsx +139 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/Sidebar.tsx +211 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/SlideInPlayground.tsx +101 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/TryItSheet.tsx +57 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/anchor.ts +11 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +71 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/index.tsx +166 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/schemaFields.ts +121 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/sidebarLabel.ts +60 -0
- package/src/tools/OpenapiViewer/components/index.ts +5 -2
- package/src/tools/OpenapiViewer/components/shared/BodyFormEditor.tsx +422 -0
- package/src/tools/OpenapiViewer/components/shared/EndpointDraftSync.tsx +108 -0
- package/src/tools/OpenapiViewer/components/shared/EndpointResetButton.tsx +50 -0
- package/src/tools/OpenapiViewer/components/{PlaygroundLayout → shared}/RequestPanel.tsx +174 -87
- package/src/tools/OpenapiViewer/components/shared/SendButton.tsx +91 -0
- package/src/tools/OpenapiViewer/components/{PlaygroundLayout → shared}/ui.tsx +5 -4
- package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +82 -8
- package/src/tools/OpenapiViewer/hooks/useEndpointDraft.ts +142 -0
- package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +126 -13
- package/src/tools/OpenapiViewer/index.tsx +3 -7
- package/src/tools/OpenapiViewer/lazy.tsx +6 -27
- package/src/tools/OpenapiViewer/types.ts +44 -0
- package/src/tools/OpenapiViewer/utils/formatters.ts +2 -23
- package/src/tools/OpenapiViewer/utils/index.ts +3 -1
- package/src/tools/OpenapiViewer/utils/schemaExport.ts +206 -0
- package/src/tools/OpenapiViewer/utils/url.ts +202 -0
- package/src/tools/PrettyCode/PrettyCode.client.tsx +42 -8
- package/src/tools/PrettyCode/index.tsx +6 -0
- package/dist/PlaygroundLayout-DHUATCHB.cjs +0 -798
- package/dist/PlaygroundLayout-DHUATCHB.cjs.map +0 -1
- package/dist/PlaygroundLayout-NONWOVQR.mjs +0 -791
- package/dist/PlaygroundLayout-NONWOVQR.mjs.map +0 -1
- package/dist/PrettyCode.client-DW5LTG47.mjs.map +0 -1
- package/dist/PrettyCode.client-SGDGQTYT.cjs.map +0 -1
- package/dist/chunk-5FKE7OME.cjs +0 -369
- package/dist/chunk-5FKE7OME.cjs.map +0 -1
- package/dist/chunk-BKWDHJKF.mjs +0 -356
- package/dist/chunk-BKWDHJKF.mjs.map +0 -1
- package/src/tools/OpenapiViewer/components/PlaygroundLayout/EndpointList.tsx +0 -228
- package/src/tools/OpenapiViewer/components/PlaygroundLayout/index.tsx +0 -107
- /package/dist/{PlaygroundLayout-O52C6HK5.css.map → DocsLayout-MBFIB4NO.css.map} +0 -0
- /package/src/tools/OpenapiViewer/components/{PlaygroundLayout → shared}/ResponsePanel.tsx +0 -0
|
@@ -0,0 +1,2027 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkIULI4XII_cjs = require('./chunk-IULI4XII.cjs');
|
|
4
|
+
var chunk33AMWFBZ_cjs = require('./chunk-33AMWFBZ.cjs');
|
|
5
|
+
require('./chunk-2SMCH62O.cjs');
|
|
6
|
+
var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
|
|
7
|
+
var React6 = require('react');
|
|
8
|
+
var components = require('@djangocfg/ui-core/components');
|
|
9
|
+
var hooks = require('@djangocfg/ui-core/hooks');
|
|
10
|
+
var consola = require('consola');
|
|
11
|
+
var lucideReact = require('lucide-react');
|
|
12
|
+
var lib = require('@djangocfg/ui-core/lib');
|
|
13
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
14
|
+
|
|
15
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
|
|
17
|
+
var React6__default = /*#__PURE__*/_interopDefault(React6);
|
|
18
|
+
var consola__default = /*#__PURE__*/_interopDefault(consola);
|
|
19
|
+
|
|
20
|
+
function exampleFromSchema(schema, depth = 0) {
|
|
21
|
+
if (!schema || depth > 8) return null;
|
|
22
|
+
if (schema.example !== void 0) return schema.example;
|
|
23
|
+
if (schema.default !== void 0) return schema.default;
|
|
24
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
|
|
25
|
+
switch (schema.type) {
|
|
26
|
+
case "object": {
|
|
27
|
+
const out = {};
|
|
28
|
+
const props = schema.properties ?? {};
|
|
29
|
+
for (const [k, v] of Object.entries(props)) {
|
|
30
|
+
out[k] = exampleFromSchema(v, depth + 1);
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
case "array":
|
|
35
|
+
return [exampleFromSchema(schema.items, depth + 1)];
|
|
36
|
+
case "integer":
|
|
37
|
+
case "number":
|
|
38
|
+
return 0;
|
|
39
|
+
case "boolean":
|
|
40
|
+
return false;
|
|
41
|
+
case "string":
|
|
42
|
+
if (schema.format === "date-time") return (/* @__PURE__ */ new Date()).toISOString();
|
|
43
|
+
if (schema.format === "date") return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
44
|
+
if (schema.format === "email") return "user@example.com";
|
|
45
|
+
if (schema.format === "uri" || schema.format === "url") return "https://example.com";
|
|
46
|
+
if (schema.format === "uuid") return "00000000-0000-0000-0000-000000000000";
|
|
47
|
+
return "";
|
|
48
|
+
default:
|
|
49
|
+
if (schema.properties) {
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const [k, v] of Object.entries(schema.properties)) {
|
|
52
|
+
out[k] = exampleFromSchema(v, depth + 1);
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
chunkWGEGR3DF_cjs.__name(exampleFromSchema, "exampleFromSchema");
|
|
60
|
+
var HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
|
|
61
|
+
var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema, baseUrl) => {
|
|
62
|
+
const endpoints = [];
|
|
63
|
+
if (!schema.paths) return [];
|
|
64
|
+
for (const [path, methods] of Object.entries(schema.paths)) {
|
|
65
|
+
for (const method of HTTP_METHODS) {
|
|
66
|
+
const op = methods[method];
|
|
67
|
+
if (!op) continue;
|
|
68
|
+
const methodUpper = method.toUpperCase();
|
|
69
|
+
const summary = (op.summary || "").trim();
|
|
70
|
+
const description = op.description || summary || `${methodUpper} ${path}`;
|
|
71
|
+
const category = op.tags?.[0] || "Other";
|
|
72
|
+
const parameters = [];
|
|
73
|
+
const allParams = [...methods.parameters || [], ...op.parameters || []];
|
|
74
|
+
for (const param of allParams) {
|
|
75
|
+
parameters.push({
|
|
76
|
+
name: param.name,
|
|
77
|
+
type: param.schema?.type || "string",
|
|
78
|
+
required: param.required || false,
|
|
79
|
+
description: param.description
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const responses = [];
|
|
83
|
+
if (op.responses) {
|
|
84
|
+
for (const [code, response] of Object.entries(op.responses)) {
|
|
85
|
+
responses.push({
|
|
86
|
+
code,
|
|
87
|
+
description: response.description || `Response ${code}`
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
let requestBody;
|
|
92
|
+
if (op.requestBody) {
|
|
93
|
+
const content = op.requestBody.content;
|
|
94
|
+
const mediaType = content?.["application/json"] || content?.[Object.keys(content || {})[0]];
|
|
95
|
+
const rawSchema = mediaType?.schema;
|
|
96
|
+
requestBody = {
|
|
97
|
+
type: rawSchema?.type || "object",
|
|
98
|
+
description: op.requestBody.description,
|
|
99
|
+
schema: rawSchema,
|
|
100
|
+
example: rawSchema ? JSON.stringify(exampleFromSchema(rawSchema), null, 2) : void 0
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const endpoint = {
|
|
104
|
+
name: path.split("/").pop() || path,
|
|
105
|
+
method: methodUpper,
|
|
106
|
+
path: baseUrl ? chunkIULI4XII_cjs.joinUrl(baseUrl, path) : path,
|
|
107
|
+
summary,
|
|
108
|
+
description,
|
|
109
|
+
category,
|
|
110
|
+
parameters: parameters.length > 0 ? parameters : void 0,
|
|
111
|
+
requestBody,
|
|
112
|
+
responses: responses.length > 0 ? responses : void 0
|
|
113
|
+
};
|
|
114
|
+
endpoints.push(endpoint);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return endpoints;
|
|
118
|
+
}, "extractEndpoints");
|
|
119
|
+
var getCategories = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((endpoints) => {
|
|
120
|
+
const categories = /* @__PURE__ */ new Set();
|
|
121
|
+
endpoints.forEach((endpoint) => categories.add(endpoint.category));
|
|
122
|
+
return Array.from(categories).sort();
|
|
123
|
+
}, "getCategories");
|
|
124
|
+
var fetchSchema = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(async (url) => {
|
|
125
|
+
const response = await fetch(url, {
|
|
126
|
+
headers: {
|
|
127
|
+
"Accept": "application/json"
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(`Failed to fetch schema: ${response.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
return response.json();
|
|
134
|
+
}, "fetchSchema");
|
|
135
|
+
function useOpenApiSchema({
|
|
136
|
+
schemas,
|
|
137
|
+
defaultSchemaId,
|
|
138
|
+
baseUrl: configBaseUrl
|
|
139
|
+
}) {
|
|
140
|
+
const [loading, setLoading] = React6.useState(true);
|
|
141
|
+
const [error, setError] = React6.useState(null);
|
|
142
|
+
const [currentSchemaId, setCurrentSchemaId] = React6.useState(
|
|
143
|
+
defaultSchemaId || schemas[0]?.id
|
|
144
|
+
);
|
|
145
|
+
const [loadedSchemas, setLoadedSchemas] = React6.useState(
|
|
146
|
+
/* @__PURE__ */ new Map()
|
|
147
|
+
);
|
|
148
|
+
const currentSchema = React6.useMemo(
|
|
149
|
+
() => schemas.find((s) => s.id === currentSchemaId) || null,
|
|
150
|
+
[schemas, currentSchemaId]
|
|
151
|
+
);
|
|
152
|
+
const currentOpenApiSchema = React6.useMemo(
|
|
153
|
+
() => currentSchemaId ? loadedSchemas.get(currentSchemaId) : null,
|
|
154
|
+
[loadedSchemas, currentSchemaId]
|
|
155
|
+
);
|
|
156
|
+
const dereferencedSchema = React6.useMemo(
|
|
157
|
+
() => currentOpenApiSchema ? chunkIULI4XII_cjs.dereferenceSchema(currentOpenApiSchema) : null,
|
|
158
|
+
[currentOpenApiSchema]
|
|
159
|
+
);
|
|
160
|
+
const resolvedBaseUrl = React6.useMemo(
|
|
161
|
+
() => chunkIULI4XII_cjs.resolveBaseUrl({
|
|
162
|
+
schemaSource: currentSchema?.baseUrl,
|
|
163
|
+
config: configBaseUrl,
|
|
164
|
+
fromServers: currentOpenApiSchema?.servers?.[0]?.url
|
|
165
|
+
}),
|
|
166
|
+
[currentSchema?.baseUrl, configBaseUrl, currentOpenApiSchema]
|
|
167
|
+
);
|
|
168
|
+
const endpoints = React6.useMemo(
|
|
169
|
+
() => dereferencedSchema ? extractEndpoints(dereferencedSchema, resolvedBaseUrl) : [],
|
|
170
|
+
[dereferencedSchema, resolvedBaseUrl]
|
|
171
|
+
);
|
|
172
|
+
const categories = React6.useMemo(() => getCategories(endpoints), [endpoints]);
|
|
173
|
+
const schemaInfo = React6.useMemo(() => {
|
|
174
|
+
if (!currentOpenApiSchema?.info) return null;
|
|
175
|
+
const { title, version, description } = currentOpenApiSchema.info;
|
|
176
|
+
return {
|
|
177
|
+
title,
|
|
178
|
+
version,
|
|
179
|
+
description,
|
|
180
|
+
servers: currentOpenApiSchema.servers
|
|
181
|
+
};
|
|
182
|
+
}, [currentOpenApiSchema]);
|
|
183
|
+
React6.useEffect(() => {
|
|
184
|
+
if (!currentSchema) return;
|
|
185
|
+
if (loadedSchemas.has(currentSchema.id)) {
|
|
186
|
+
setLoading(false);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
setLoading(true);
|
|
190
|
+
setError(null);
|
|
191
|
+
fetchSchema(currentSchema.url).then((schema) => {
|
|
192
|
+
setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, schema));
|
|
193
|
+
consola__default.default.success(`Schema loaded: ${currentSchema.name}`);
|
|
194
|
+
setLoading(false);
|
|
195
|
+
}).catch((err) => {
|
|
196
|
+
consola__default.default.error(`Error loading schema from ${currentSchema.url}:`, err);
|
|
197
|
+
setError(err instanceof Error ? err.message : "Failed to load schema");
|
|
198
|
+
setLoading(false);
|
|
199
|
+
});
|
|
200
|
+
}, [currentSchema, loadedSchemas]);
|
|
201
|
+
const setCurrentSchema = React6.useCallback((schemaId) => {
|
|
202
|
+
setCurrentSchemaId(schemaId);
|
|
203
|
+
}, []);
|
|
204
|
+
const refresh = React6.useCallback(() => {
|
|
205
|
+
if (!currentSchema) return;
|
|
206
|
+
setLoading(true);
|
|
207
|
+
setError(null);
|
|
208
|
+
setLoadedSchemas((prev) => {
|
|
209
|
+
const next = new Map(prev);
|
|
210
|
+
next.delete(currentSchema.id);
|
|
211
|
+
return next;
|
|
212
|
+
});
|
|
213
|
+
fetchSchema(currentSchema.url).then((schema) => {
|
|
214
|
+
setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, schema));
|
|
215
|
+
consola__default.default.success(`Schema refreshed: ${currentSchema.name}`);
|
|
216
|
+
setLoading(false);
|
|
217
|
+
}).catch((err) => {
|
|
218
|
+
consola__default.default.error(`Error refreshing schema from ${currentSchema.url}:`, err);
|
|
219
|
+
setError(err instanceof Error ? err.message : "Failed to refresh schema");
|
|
220
|
+
setLoading(false);
|
|
221
|
+
});
|
|
222
|
+
}, [currentSchema]);
|
|
223
|
+
return {
|
|
224
|
+
loading,
|
|
225
|
+
error,
|
|
226
|
+
endpoints,
|
|
227
|
+
categories,
|
|
228
|
+
schemas,
|
|
229
|
+
currentSchema,
|
|
230
|
+
schemaInfo,
|
|
231
|
+
rawSchema: currentOpenApiSchema ?? null,
|
|
232
|
+
// Consumers expect ``undefined`` when no base URL was resolved (for
|
|
233
|
+
// conditional ``{ baseUrl?: … }`` plumbing). Turn the empty-string
|
|
234
|
+
// convention from the resolver into undefined at the API boundary.
|
|
235
|
+
resolvedBaseUrl: resolvedBaseUrl || void 0,
|
|
236
|
+
setCurrentSchema,
|
|
237
|
+
refresh
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
chunkWGEGR3DF_cjs.__name(useOpenApiSchema, "useOpenApiSchema");
|
|
241
|
+
var EMPTY_DRAFT = { parameters: {}, requestBody: "" };
|
|
242
|
+
function storageKey(schemaId, ep) {
|
|
243
|
+
if (!schemaId || !ep) return null;
|
|
244
|
+
return `openapi-playground:draft:${schemaId}:${ep.method}:${ep.path}`;
|
|
245
|
+
}
|
|
246
|
+
chunkWGEGR3DF_cjs.__name(storageKey, "storageKey");
|
|
247
|
+
function readDraft(key) {
|
|
248
|
+
if (!key || typeof window === "undefined") return EMPTY_DRAFT;
|
|
249
|
+
try {
|
|
250
|
+
const raw = window.localStorage.getItem(key);
|
|
251
|
+
if (!raw) return EMPTY_DRAFT;
|
|
252
|
+
const parsed = JSON.parse(raw);
|
|
253
|
+
return {
|
|
254
|
+
parameters: parsed?.parameters ?? {},
|
|
255
|
+
requestBody: typeof parsed?.requestBody === "string" ? parsed.requestBody : ""
|
|
256
|
+
};
|
|
257
|
+
} catch {
|
|
258
|
+
return EMPTY_DRAFT;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
chunkWGEGR3DF_cjs.__name(readDraft, "readDraft");
|
|
262
|
+
function writeDraft(key, value) {
|
|
263
|
+
if (!key || typeof window === "undefined") return;
|
|
264
|
+
try {
|
|
265
|
+
if (Object.keys(value.parameters).length === 0 && !value.requestBody) {
|
|
266
|
+
window.localStorage.removeItem(key);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
window.localStorage.setItem(key, JSON.stringify(value));
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
chunkWGEGR3DF_cjs.__name(writeDraft, "writeDraft");
|
|
274
|
+
function useEndpointDraft(schemaId, endpoint) {
|
|
275
|
+
const key = storageKey(schemaId, endpoint);
|
|
276
|
+
const [draft, setDraftSnapshot] = React6.useState(() => readDraft(key));
|
|
277
|
+
const loadedKeyRef = React6.useRef(key);
|
|
278
|
+
React6.useEffect(() => {
|
|
279
|
+
if (loadedKeyRef.current === key) return;
|
|
280
|
+
loadedKeyRef.current = key;
|
|
281
|
+
setDraftSnapshot(readDraft(key));
|
|
282
|
+
}, [key]);
|
|
283
|
+
const keyRef = React6.useRef(key);
|
|
284
|
+
React6.useEffect(() => {
|
|
285
|
+
keyRef.current = key;
|
|
286
|
+
}, [key]);
|
|
287
|
+
const latestRef = React6.useRef(draft);
|
|
288
|
+
React6.useEffect(() => {
|
|
289
|
+
latestRef.current = draft;
|
|
290
|
+
}, [draft]);
|
|
291
|
+
const setParameters = React6.useCallback((params) => {
|
|
292
|
+
const next = {
|
|
293
|
+
parameters: params,
|
|
294
|
+
requestBody: latestRef.current.requestBody
|
|
295
|
+
};
|
|
296
|
+
latestRef.current = next;
|
|
297
|
+
writeDraft(keyRef.current, next);
|
|
298
|
+
}, []);
|
|
299
|
+
const setRequestBody = React6.useCallback((body) => {
|
|
300
|
+
const next = {
|
|
301
|
+
parameters: latestRef.current.parameters,
|
|
302
|
+
requestBody: body
|
|
303
|
+
};
|
|
304
|
+
latestRef.current = next;
|
|
305
|
+
writeDraft(keyRef.current, next);
|
|
306
|
+
}, []);
|
|
307
|
+
const reset = React6.useCallback(() => {
|
|
308
|
+
latestRef.current = EMPTY_DRAFT;
|
|
309
|
+
if (keyRef.current && typeof window !== "undefined") {
|
|
310
|
+
try {
|
|
311
|
+
window.localStorage.removeItem(keyRef.current);
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
setDraftSnapshot(EMPTY_DRAFT);
|
|
316
|
+
}, []);
|
|
317
|
+
return { draft, setParameters, setRequestBody, reset };
|
|
318
|
+
}
|
|
319
|
+
chunkWGEGR3DF_cjs.__name(useEndpointDraft, "useEndpointDraft");
|
|
320
|
+
|
|
321
|
+
// src/tools/OpenapiViewer/components/shared/EndpointDraftSync.tsx
|
|
322
|
+
function EndpointDraftSync({ schemaId }) {
|
|
323
|
+
const { state, setParameters, setRequestBody, setActiveSchemaId } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
324
|
+
const ep = state.selectedEndpoint;
|
|
325
|
+
React6.useEffect(() => {
|
|
326
|
+
setActiveSchemaId(schemaId);
|
|
327
|
+
}, [schemaId, setActiveSchemaId]);
|
|
328
|
+
const { draft, setParameters: persistParams, setRequestBody: persistBody } = useEndpointDraft(schemaId, ep);
|
|
329
|
+
const lastLoadedKeyRef = React6.useRef(null);
|
|
330
|
+
const lastPersistedParamsRef = React6.useRef("");
|
|
331
|
+
const lastPersistedBodyRef = React6.useRef("");
|
|
332
|
+
const currentKey = ep ? `${ep.method}|${ep.path}` : null;
|
|
333
|
+
React6.useEffect(() => {
|
|
334
|
+
if (!ep || !currentKey) {
|
|
335
|
+
lastLoadedKeyRef.current = null;
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (lastLoadedKeyRef.current === currentKey) return;
|
|
339
|
+
lastLoadedKeyRef.current = currentKey;
|
|
340
|
+
const hasStoredParams = draft.parameters && Object.keys(draft.parameters).length > 0;
|
|
341
|
+
const hasStoredBody = typeof draft.requestBody === "string" && draft.requestBody !== "";
|
|
342
|
+
if (hasStoredParams) {
|
|
343
|
+
setParameters(draft.parameters);
|
|
344
|
+
lastPersistedParamsRef.current = JSON.stringify(draft.parameters);
|
|
345
|
+
} else {
|
|
346
|
+
lastPersistedParamsRef.current = JSON.stringify(state.parameters);
|
|
347
|
+
}
|
|
348
|
+
if (hasStoredBody) {
|
|
349
|
+
setRequestBody(draft.requestBody);
|
|
350
|
+
lastPersistedBodyRef.current = draft.requestBody;
|
|
351
|
+
} else {
|
|
352
|
+
lastPersistedBodyRef.current = state.requestBody;
|
|
353
|
+
}
|
|
354
|
+
}, [currentKey]);
|
|
355
|
+
React6.useEffect(() => {
|
|
356
|
+
if (!ep || lastLoadedKeyRef.current !== currentKey) return;
|
|
357
|
+
const serialised = JSON.stringify(state.parameters);
|
|
358
|
+
if (serialised === lastPersistedParamsRef.current) return;
|
|
359
|
+
lastPersistedParamsRef.current = serialised;
|
|
360
|
+
persistParams(state.parameters);
|
|
361
|
+
}, [state.parameters, ep, currentKey, persistParams]);
|
|
362
|
+
React6.useEffect(() => {
|
|
363
|
+
if (!ep || lastLoadedKeyRef.current !== currentKey) return;
|
|
364
|
+
if (state.requestBody === lastPersistedBodyRef.current) return;
|
|
365
|
+
lastPersistedBodyRef.current = state.requestBody;
|
|
366
|
+
persistBody(state.requestBody);
|
|
367
|
+
}, [state.requestBody, ep, currentKey, persistBody]);
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
chunkWGEGR3DF_cjs.__name(EndpointDraftSync, "EndpointDraftSync");
|
|
371
|
+
var METHOD_STYLES = {
|
|
372
|
+
GET: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25",
|
|
373
|
+
POST: "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25",
|
|
374
|
+
PUT: "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/25",
|
|
375
|
+
PATCH: "bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/25",
|
|
376
|
+
DELETE: "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/25"
|
|
377
|
+
};
|
|
378
|
+
var METHOD_FALLBACK = "bg-muted text-muted-foreground border-border";
|
|
379
|
+
function getMethodStyle(method) {
|
|
380
|
+
return METHOD_STYLES[method.toUpperCase()] ?? METHOD_FALLBACK;
|
|
381
|
+
}
|
|
382
|
+
chunkWGEGR3DF_cjs.__name(getMethodStyle, "getMethodStyle");
|
|
383
|
+
function getStatusStyle(status) {
|
|
384
|
+
if (status >= 500) return "bg-red-500/10 text-red-500 dark:text-red-400 border-red-500/25";
|
|
385
|
+
if (status >= 400) return "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/25";
|
|
386
|
+
if (status >= 300) return "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25";
|
|
387
|
+
return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25";
|
|
388
|
+
}
|
|
389
|
+
chunkWGEGR3DF_cjs.__name(getStatusStyle, "getStatusStyle");
|
|
390
|
+
function MethodBadge({ method }) {
|
|
391
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
|
|
392
|
+
"inline-flex shrink-0 items-center rounded border px-1.5 py-px",
|
|
393
|
+
"font-mono text-[10px] font-bold uppercase tracking-wider leading-none",
|
|
394
|
+
getMethodStyle(method)
|
|
395
|
+
), children: method });
|
|
396
|
+
}
|
|
397
|
+
chunkWGEGR3DF_cjs.__name(MethodBadge, "MethodBadge");
|
|
398
|
+
function StatusBadge({ status }) {
|
|
399
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
|
|
400
|
+
"inline-flex items-center rounded border px-1.5 py-px",
|
|
401
|
+
"font-mono text-[11px] font-bold leading-none",
|
|
402
|
+
getStatusStyle(status)
|
|
403
|
+
), children: status });
|
|
404
|
+
}
|
|
405
|
+
chunkWGEGR3DF_cjs.__name(StatusBadge, "StatusBadge");
|
|
406
|
+
function SectionLabel({ children }) {
|
|
407
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60 select-none", children });
|
|
408
|
+
}
|
|
409
|
+
chunkWGEGR3DF_cjs.__name(SectionLabel, "SectionLabel");
|
|
410
|
+
function Panel({ children, className }) {
|
|
411
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn("flex flex-col min-h-0 overflow-hidden", className), children });
|
|
412
|
+
}
|
|
413
|
+
chunkWGEGR3DF_cjs.__name(Panel, "Panel");
|
|
414
|
+
function ScrollArea({ children, className }) {
|
|
415
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn("flex-1 overflow-y-auto min-h-0", className), children });
|
|
416
|
+
}
|
|
417
|
+
chunkWGEGR3DF_cjs.__name(ScrollArea, "ScrollArea");
|
|
418
|
+
function EmptyState({
|
|
419
|
+
icon: Icon,
|
|
420
|
+
text,
|
|
421
|
+
className
|
|
422
|
+
}) {
|
|
423
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
className: lib.cn(
|
|
427
|
+
"flex flex-col items-center justify-center h-full gap-3 px-6 text-center",
|
|
428
|
+
className
|
|
429
|
+
),
|
|
430
|
+
children: [
|
|
431
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-7 w-7 text-muted-foreground/25" }),
|
|
432
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: text })
|
|
433
|
+
]
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
chunkWGEGR3DF_cjs.__name(EmptyState, "EmptyState");
|
|
438
|
+
function CollapsibleSection({
|
|
439
|
+
label,
|
|
440
|
+
action,
|
|
441
|
+
children,
|
|
442
|
+
defaultOpen = false
|
|
443
|
+
}) {
|
|
444
|
+
const [open, setOpen] = React6__default.default.useState(defaultOpen);
|
|
445
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0", children: [
|
|
446
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
447
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
448
|
+
"button",
|
|
449
|
+
{
|
|
450
|
+
type: "button",
|
|
451
|
+
onClick: () => setOpen((v) => !v),
|
|
452
|
+
className: "flex items-center gap-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60 hover:text-muted-foreground transition-colors py-1",
|
|
453
|
+
children: [
|
|
454
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: lib.cn("h-3 w-3 transition-transform", open && "rotate-90") }),
|
|
455
|
+
label
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
),
|
|
459
|
+
action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action })
|
|
460
|
+
] }),
|
|
461
|
+
open && /* @__PURE__ */ jsxRuntime.jsx("div", { children })
|
|
462
|
+
] });
|
|
463
|
+
}
|
|
464
|
+
chunkWGEGR3DF_cjs.__name(CollapsibleSection, "CollapsibleSection");
|
|
465
|
+
|
|
466
|
+
// src/tools/OpenapiViewer/components/DocsLayout/anchor.ts
|
|
467
|
+
function endpointAnchor(ep) {
|
|
468
|
+
const slug = ep.path.replace(/^https?:\/\/[^/]+/, "").replace(/[{}]/g, "").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
469
|
+
return `ep-${ep.method.toLowerCase()}-${slug}`;
|
|
470
|
+
}
|
|
471
|
+
chunkWGEGR3DF_cjs.__name(endpointAnchor, "endpointAnchor");
|
|
472
|
+
|
|
473
|
+
// src/tools/OpenapiViewer/components/DocsLayout/sidebarLabel.ts
|
|
474
|
+
function longestCommonPrefix(paths) {
|
|
475
|
+
if (paths.length === 0) return "";
|
|
476
|
+
if (paths.length === 1) return "";
|
|
477
|
+
const segments = paths.map((p) => p.split("/"));
|
|
478
|
+
const minLen = Math.min(...segments.map((s) => s.length));
|
|
479
|
+
const shared = [];
|
|
480
|
+
for (let i = 0; i < minLen; i++) {
|
|
481
|
+
const first = segments[0][i];
|
|
482
|
+
if (segments.every((s) => s[i] === first)) {
|
|
483
|
+
shared.push(first);
|
|
484
|
+
} else {
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
const joined = shared.join("/");
|
|
489
|
+
return joined;
|
|
490
|
+
}
|
|
491
|
+
chunkWGEGR3DF_cjs.__name(longestCommonPrefix, "longestCommonPrefix");
|
|
492
|
+
function sidebarLabel(ep, groupCommonPrefix) {
|
|
493
|
+
if (ep.summary) return ep.summary;
|
|
494
|
+
if (groupCommonPrefix && ep.path.startsWith(groupCommonPrefix)) {
|
|
495
|
+
const tail = ep.path.slice(groupCommonPrefix.length) || "/";
|
|
496
|
+
return tail;
|
|
497
|
+
}
|
|
498
|
+
return relativePath2(ep.path);
|
|
499
|
+
}
|
|
500
|
+
chunkWGEGR3DF_cjs.__name(sidebarLabel, "sidebarLabel");
|
|
501
|
+
function relativePath2(full) {
|
|
502
|
+
try {
|
|
503
|
+
return new URL(full).pathname;
|
|
504
|
+
} catch {
|
|
505
|
+
return full;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
chunkWGEGR3DF_cjs.__name(relativePath2, "relativePath");
|
|
509
|
+
function sidebarTooltip(ep) {
|
|
510
|
+
return `${ep.method} ${relativePath2(ep.path)}`;
|
|
511
|
+
}
|
|
512
|
+
chunkWGEGR3DF_cjs.__name(sidebarTooltip, "sidebarTooltip");
|
|
513
|
+
var METHOD_ORDER = {
|
|
514
|
+
GET: 0,
|
|
515
|
+
POST: 1,
|
|
516
|
+
PUT: 2,
|
|
517
|
+
PATCH: 3,
|
|
518
|
+
DELETE: 4
|
|
519
|
+
};
|
|
520
|
+
function groupEndpoints(list) {
|
|
521
|
+
const map = /* @__PURE__ */ new Map();
|
|
522
|
+
for (const ep of list) {
|
|
523
|
+
const arr = map.get(ep.category) ?? [];
|
|
524
|
+
arr.push(ep);
|
|
525
|
+
map.set(ep.category, arr);
|
|
526
|
+
}
|
|
527
|
+
const groups = Array.from(map.entries()).map(([category, endpoints]) => ({
|
|
528
|
+
category,
|
|
529
|
+
endpoints: [...endpoints].sort((a, b) => {
|
|
530
|
+
const byPath = a.path.localeCompare(b.path);
|
|
531
|
+
if (byPath !== 0) return byPath;
|
|
532
|
+
return (METHOD_ORDER[a.method] ?? 99) - (METHOD_ORDER[b.method] ?? 99);
|
|
533
|
+
}),
|
|
534
|
+
commonPrefix: longestCommonPrefix(endpoints.map((e) => e.path))
|
|
535
|
+
}));
|
|
536
|
+
groups.sort((a, b) => {
|
|
537
|
+
if (a.category === "Other") return 1;
|
|
538
|
+
if (b.category === "Other") return -1;
|
|
539
|
+
return a.category.localeCompare(b.category);
|
|
540
|
+
});
|
|
541
|
+
return groups;
|
|
542
|
+
}
|
|
543
|
+
chunkWGEGR3DF_cjs.__name(groupEndpoints, "groupEndpoints");
|
|
544
|
+
function DocsSidebar({
|
|
545
|
+
info,
|
|
546
|
+
endpoints,
|
|
547
|
+
schemas,
|
|
548
|
+
currentSchemaId,
|
|
549
|
+
onSchemaChange,
|
|
550
|
+
activeEndpointId,
|
|
551
|
+
selectedVersion,
|
|
552
|
+
onNavigate
|
|
553
|
+
}) {
|
|
554
|
+
const [search, setSearch] = React6.useState("");
|
|
555
|
+
const [debounced, setDebounced] = React6.useState("");
|
|
556
|
+
React6.useEffect(() => {
|
|
557
|
+
const id = setTimeout(() => setDebounced(search), 120);
|
|
558
|
+
return () => clearTimeout(id);
|
|
559
|
+
}, [search]);
|
|
560
|
+
const filteredGroups = React6.useMemo(() => {
|
|
561
|
+
let list = chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion);
|
|
562
|
+
if (debounced) {
|
|
563
|
+
const q = debounced.toLowerCase();
|
|
564
|
+
list = list.filter(
|
|
565
|
+
(e) => e.summary.toLowerCase().includes(q) || e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q) || e.path.toLowerCase().includes(q)
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
return groupEndpoints(list);
|
|
569
|
+
}, [endpoints, debounced, selectedVersion]);
|
|
570
|
+
const schemaOptions = React6.useMemo(
|
|
571
|
+
() => schemas.map((s) => ({ value: s.id, label: s.name })),
|
|
572
|
+
[schemas]
|
|
573
|
+
);
|
|
574
|
+
const hasMultipleSchemas = schemas.length > 1;
|
|
575
|
+
const apiTitle = info?.title ?? "API Reference";
|
|
576
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "flex flex-col min-h-0 border-r bg-muted/10", children: [
|
|
577
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-4 h-12 flex items-center gap-2", children: [
|
|
578
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-foreground truncate", children: apiTitle }),
|
|
579
|
+
info?.version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-[10px] text-muted-foreground/70 shrink-0", children: [
|
|
580
|
+
"v",
|
|
581
|
+
info.version
|
|
582
|
+
] })
|
|
583
|
+
] }),
|
|
584
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 py-3 space-y-2", children: [
|
|
585
|
+
hasMultipleSchemas && /* @__PURE__ */ jsxRuntime.jsx(
|
|
586
|
+
components.Combobox,
|
|
587
|
+
{
|
|
588
|
+
options: schemaOptions,
|
|
589
|
+
value: currentSchemaId ?? "",
|
|
590
|
+
onValueChange: (id) => id && onSchemaChange(id),
|
|
591
|
+
placeholder: "Select API",
|
|
592
|
+
searchPlaceholder: "Search APIs\u2026",
|
|
593
|
+
emptyText: "No APIs found",
|
|
594
|
+
className: "w-full h-8 text-xs"
|
|
595
|
+
}
|
|
596
|
+
),
|
|
597
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
598
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" }),
|
|
599
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
600
|
+
components.Input,
|
|
601
|
+
{
|
|
602
|
+
placeholder: "Search endpoints\u2026",
|
|
603
|
+
value: search,
|
|
604
|
+
onChange: (e) => setSearch(e.target.value),
|
|
605
|
+
className: "pl-8 h-8 text-xs"
|
|
606
|
+
}
|
|
607
|
+
)
|
|
608
|
+
] })
|
|
609
|
+
] }),
|
|
610
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { children: filteredGroups.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: debounced ? `No endpoints match "${debounced}"` : "No endpoints in this schema" }) : /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "py-2", children: filteredGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 last:mb-2", children: [
|
|
611
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/50 select-none", children: group.category }),
|
|
612
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: group.endpoints.map((ep) => {
|
|
613
|
+
const anchor = endpointAnchor(ep);
|
|
614
|
+
const isActive = activeEndpointId === anchor;
|
|
615
|
+
const label = sidebarLabel(ep, group.commonPrefix);
|
|
616
|
+
const tooltip = sidebarTooltip(ep);
|
|
617
|
+
const useMono = !ep.summary;
|
|
618
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(components.Tooltip, { delayDuration: 350, children: [
|
|
619
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
620
|
+
"button",
|
|
621
|
+
{
|
|
622
|
+
onClick: () => onNavigate(anchor),
|
|
623
|
+
"aria-current": isActive ? "location" : void 0,
|
|
624
|
+
className: lib.cn(
|
|
625
|
+
"relative group w-full text-left flex items-center gap-2 pl-4 pr-3 py-1.5 transition-colors",
|
|
626
|
+
isActive ? "bg-primary/10 text-foreground" : "hover:bg-muted/40 text-foreground/75 hover:text-foreground"
|
|
627
|
+
),
|
|
628
|
+
children: [
|
|
629
|
+
isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-0 top-1 bottom-1 w-0.5 rounded-r bg-primary" }),
|
|
630
|
+
/* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: ep.method }),
|
|
631
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
632
|
+
"span",
|
|
633
|
+
{
|
|
634
|
+
className: lib.cn(
|
|
635
|
+
"truncate leading-tight flex-1 min-w-0",
|
|
636
|
+
useMono ? "font-mono text-[11px]" : "text-[12px]",
|
|
637
|
+
isActive && "text-foreground font-medium"
|
|
638
|
+
),
|
|
639
|
+
children: label
|
|
640
|
+
}
|
|
641
|
+
)
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
) }),
|
|
645
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.TooltipContent, { side: "right", align: "center", className: "font-mono text-[11px]", children: tooltip })
|
|
646
|
+
] }, `${ep.method}-${ep.path}`);
|
|
647
|
+
}) })
|
|
648
|
+
] }, group.category)) }) })
|
|
649
|
+
] });
|
|
650
|
+
}
|
|
651
|
+
chunkWGEGR3DF_cjs.__name(DocsSidebar, "DocsSidebar");
|
|
652
|
+
var FLAVOUR_LABELS = {
|
|
653
|
+
markdown: {
|
|
654
|
+
title: "Markdown for LLM",
|
|
655
|
+
hint: "Endpoints + params as prose. Smallest."
|
|
656
|
+
},
|
|
657
|
+
compact: {
|
|
658
|
+
title: "Compact JSON",
|
|
659
|
+
hint: "Dereferenced, no examples, minified."
|
|
660
|
+
},
|
|
661
|
+
raw: {
|
|
662
|
+
title: "Raw JSON",
|
|
663
|
+
hint: "Full OpenAPI document with $refs."
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
function SchemaCopyMenu({ schema, endpoints, baseUrl }) {
|
|
667
|
+
const [sizeCache, setSizeCache] = React6.useState({});
|
|
668
|
+
const [justCopied, setJustCopied] = React6.useState(null);
|
|
669
|
+
const [open, setOpen] = React6.useState(false);
|
|
670
|
+
const isReady = schema !== null && endpoints.length > 0;
|
|
671
|
+
const build = React6.useCallback(
|
|
672
|
+
(flavour) => {
|
|
673
|
+
if (!schema) return "";
|
|
674
|
+
if (flavour === "markdown") return chunkIULI4XII_cjs.toMarkdown(schema, endpoints, baseUrl);
|
|
675
|
+
if (flavour === "compact") return chunkIULI4XII_cjs.toCompactJson(schema, baseUrl);
|
|
676
|
+
return chunkIULI4XII_cjs.toRawJson(schema, baseUrl);
|
|
677
|
+
},
|
|
678
|
+
[schema, endpoints, baseUrl]
|
|
679
|
+
);
|
|
680
|
+
const handleCopy = React6.useCallback(
|
|
681
|
+
async (flavour) => {
|
|
682
|
+
if (!isReady) return;
|
|
683
|
+
const text = build(flavour);
|
|
684
|
+
try {
|
|
685
|
+
await navigator.clipboard.writeText(text);
|
|
686
|
+
setSizeCache((prev) => ({ ...prev, [flavour]: chunkIULI4XII_cjs.formatBytes(text) }));
|
|
687
|
+
setJustCopied(flavour);
|
|
688
|
+
setTimeout(() => setJustCopied(null), 1500);
|
|
689
|
+
setOpen(false);
|
|
690
|
+
} catch {
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
[build, isReady]
|
|
694
|
+
);
|
|
695
|
+
const flavours = React6.useMemo(() => ["markdown", "compact", "raw"], []);
|
|
696
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(components.DropdownMenu, { open, onOpenChange: setOpen, children: [
|
|
697
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(components.Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
|
|
698
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" }),
|
|
699
|
+
"Copy for AI",
|
|
700
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 opacity-60" })
|
|
701
|
+
] }) }),
|
|
702
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.DropdownMenuContent, { align: "end", className: "w-72", children: [
|
|
703
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuLabel, { className: "text-[10px] uppercase tracking-wider text-muted-foreground/70", children: "Copy schema" }),
|
|
704
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuSeparator, {}),
|
|
705
|
+
flavours.map((f) => {
|
|
706
|
+
const label = FLAVOUR_LABELS[f];
|
|
707
|
+
const size = sizeCache[f];
|
|
708
|
+
const isDone = justCopied === f;
|
|
709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
710
|
+
components.DropdownMenuItem,
|
|
711
|
+
{
|
|
712
|
+
onClick: (e) => {
|
|
713
|
+
e.preventDefault();
|
|
714
|
+
void handleCopy(f);
|
|
715
|
+
},
|
|
716
|
+
className: "flex flex-col items-start gap-0.5 py-2 cursor-pointer",
|
|
717
|
+
children: [
|
|
718
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2", children: [
|
|
719
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium flex-1", children: label.title }),
|
|
720
|
+
isDone ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-emerald-500", children: [
|
|
721
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }),
|
|
722
|
+
" Copied"
|
|
723
|
+
] }) : size ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono text-muted-foreground/70 tabular-nums", children: size }) : null
|
|
724
|
+
] }),
|
|
725
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/70 leading-snug", children: label.hint })
|
|
726
|
+
]
|
|
727
|
+
},
|
|
728
|
+
f
|
|
729
|
+
);
|
|
730
|
+
})
|
|
731
|
+
] })
|
|
732
|
+
] });
|
|
733
|
+
}
|
|
734
|
+
chunkWGEGR3DF_cjs.__name(SchemaCopyMenu, "SchemaCopyMenu");
|
|
735
|
+
function ApiIntroSection({ info, schema, endpoints, resolvedBaseUrl }) {
|
|
736
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pb-10 mb-10 border-b", children: [
|
|
737
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 flex-wrap", children: [
|
|
738
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap min-w-0", children: [
|
|
739
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold tracking-tight text-foreground leading-tight", children: info.title }),
|
|
740
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 font-mono text-[11px] text-muted-foreground", children: [
|
|
741
|
+
"v",
|
|
742
|
+
info.version
|
|
743
|
+
] })
|
|
744
|
+
] }),
|
|
745
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
746
|
+
SchemaCopyMenu,
|
|
747
|
+
{
|
|
748
|
+
schema,
|
|
749
|
+
endpoints,
|
|
750
|
+
baseUrl: resolvedBaseUrl
|
|
751
|
+
}
|
|
752
|
+
)
|
|
753
|
+
] }),
|
|
754
|
+
info.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(chunkIULI4XII_cjs.MarkdownMessage, { content: info.description }) }),
|
|
755
|
+
info.servers && info.servers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 space-y-2", children: [
|
|
756
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60", children: "Base URL" }),
|
|
757
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: info.servers.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
|
|
758
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs px-2 py-1 rounded bg-muted border", children: s.url }),
|
|
759
|
+
s.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: s.description })
|
|
760
|
+
] }, `${s.url}-${i}`)) })
|
|
761
|
+
] })
|
|
762
|
+
] });
|
|
763
|
+
}
|
|
764
|
+
chunkWGEGR3DF_cjs.__name(ApiIntroSection, "ApiIntroSection");
|
|
765
|
+
|
|
766
|
+
// src/tools/OpenapiViewer/components/DocsLayout/schemaFields.ts
|
|
767
|
+
var MAX_DEPTH = 2;
|
|
768
|
+
function describeType(node) {
|
|
769
|
+
if (!node.type && node.properties) return "object";
|
|
770
|
+
const base = node.type || "any";
|
|
771
|
+
if (base === "array") {
|
|
772
|
+
const itemType = node.items ? describeType(node.items) : "any";
|
|
773
|
+
return `array<${itemType}>`;
|
|
774
|
+
}
|
|
775
|
+
if (Array.isArray(node.enum) && node.enum.length > 0) {
|
|
776
|
+
return `${base} enum`;
|
|
777
|
+
}
|
|
778
|
+
if (node.format) return `${base} (${node.format})`;
|
|
779
|
+
return base;
|
|
780
|
+
}
|
|
781
|
+
chunkWGEGR3DF_cjs.__name(describeType, "describeType");
|
|
782
|
+
function schemaToFields(schema, prefix = "", depth = 0) {
|
|
783
|
+
if (!schema || depth > MAX_DEPTH) return [];
|
|
784
|
+
if (schema.type === "array") {
|
|
785
|
+
if (!schema.items) {
|
|
786
|
+
return [{ name: prefix || "[]", type: "array", required: false }];
|
|
787
|
+
}
|
|
788
|
+
const inner = schemaToFields(schema.items, prefix ? `${prefix}[]` : "[]", depth);
|
|
789
|
+
if (inner.length === 0) {
|
|
790
|
+
return [
|
|
791
|
+
{
|
|
792
|
+
name: prefix || "[]",
|
|
793
|
+
type: describeType(schema),
|
|
794
|
+
required: false,
|
|
795
|
+
description: schema.description
|
|
796
|
+
}
|
|
797
|
+
];
|
|
798
|
+
}
|
|
799
|
+
return inner;
|
|
800
|
+
}
|
|
801
|
+
if (schema.type !== "object" && !schema.properties) {
|
|
802
|
+
return [
|
|
803
|
+
{
|
|
804
|
+
name: prefix || "(body)",
|
|
805
|
+
type: describeType(schema),
|
|
806
|
+
required: false,
|
|
807
|
+
description: schema.description
|
|
808
|
+
}
|
|
809
|
+
];
|
|
810
|
+
}
|
|
811
|
+
const required = new Set(schema.required ?? []);
|
|
812
|
+
const rows = [];
|
|
813
|
+
const props = schema.properties ?? {};
|
|
814
|
+
for (const [key, node] of Object.entries(props)) {
|
|
815
|
+
const fullName = prefix ? `${prefix}.${key}` : key;
|
|
816
|
+
const isRequired = required.has(key);
|
|
817
|
+
const isNestedExpandable = node.type === "object" && node.properties || node.type === "array" && node.items;
|
|
818
|
+
if (isNestedExpandable && depth < MAX_DEPTH) {
|
|
819
|
+
rows.push({
|
|
820
|
+
name: fullName,
|
|
821
|
+
type: describeType(node),
|
|
822
|
+
required: isRequired,
|
|
823
|
+
description: node.description
|
|
824
|
+
});
|
|
825
|
+
rows.push(...schemaToFields(node, fullName, depth + 1));
|
|
826
|
+
} else {
|
|
827
|
+
rows.push({
|
|
828
|
+
name: fullName,
|
|
829
|
+
type: describeType(node),
|
|
830
|
+
required: isRequired,
|
|
831
|
+
description: node.description
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return rows;
|
|
836
|
+
}
|
|
837
|
+
chunkWGEGR3DF_cjs.__name(schemaToFields, "schemaToFields");
|
|
838
|
+
function EndpointDoc({ endpoint, isLoadedInPlayground, onTryIt }) {
|
|
839
|
+
const anchor = endpointAnchor(endpoint);
|
|
840
|
+
const pathParams = endpoint.parameters?.filter((p) => endpoint.path.includes(`{${p.name}}`)) ?? [];
|
|
841
|
+
const queryParams = endpoint.parameters?.filter((p) => !endpoint.path.includes(`{${p.name}}`)) ?? [];
|
|
842
|
+
const [copied, setCopied] = React6.useState(false);
|
|
843
|
+
const copyAnchor = React6.useCallback(() => {
|
|
844
|
+
if (typeof window === "undefined") return;
|
|
845
|
+
const url = `${window.location.origin}${window.location.pathname}#${anchor}`;
|
|
846
|
+
void navigator.clipboard?.writeText(url).then(() => {
|
|
847
|
+
setCopied(true);
|
|
848
|
+
setTimeout(() => setCopied(false), 1200);
|
|
849
|
+
});
|
|
850
|
+
}, [anchor]);
|
|
851
|
+
const endpointMd = React6.useMemo(() => chunkIULI4XII_cjs.endpointToMarkdown(endpoint), [endpoint]);
|
|
852
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
853
|
+
"section",
|
|
854
|
+
{
|
|
855
|
+
id: anchor,
|
|
856
|
+
"data-endpoint-anchor": anchor,
|
|
857
|
+
className: "scroll-mt-24 py-10 first:pt-0",
|
|
858
|
+
children: [
|
|
859
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-4", children: [
|
|
860
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 flex-wrap", children: [
|
|
861
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2.5 min-w-0 flex-1 group/header", children: [
|
|
862
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 translate-y-[2px]", children: /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: endpoint.method }) }),
|
|
863
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
864
|
+
"code",
|
|
865
|
+
{
|
|
866
|
+
className: "font-mono text-sm md:text-[15px] font-medium text-foreground leading-snug min-w-0",
|
|
867
|
+
style: { overflowWrap: "anywhere", wordBreak: "break-word" },
|
|
868
|
+
children: chunkIULI4XII_cjs.relativePath(endpoint.path)
|
|
869
|
+
}
|
|
870
|
+
),
|
|
871
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
872
|
+
"button",
|
|
873
|
+
{
|
|
874
|
+
type: "button",
|
|
875
|
+
onClick: copyAnchor,
|
|
876
|
+
title: "Copy link to this section",
|
|
877
|
+
className: lib.cn(
|
|
878
|
+
"shrink-0 p-1 rounded text-muted-foreground/40 hover:text-foreground hover:bg-muted transition-all",
|
|
879
|
+
"opacity-0 group-hover/header:opacity-100",
|
|
880
|
+
copied && "opacity-100 text-emerald-500"
|
|
881
|
+
),
|
|
882
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3.5 w-3.5" })
|
|
883
|
+
}
|
|
884
|
+
),
|
|
885
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
886
|
+
components.CopyButton,
|
|
887
|
+
{
|
|
888
|
+
value: endpointMd,
|
|
889
|
+
title: "Copy endpoint as markdown (for AI)",
|
|
890
|
+
variant: "ghost",
|
|
891
|
+
size: "icon",
|
|
892
|
+
iconClassName: "h-3.5 w-3.5",
|
|
893
|
+
className: lib.cn(
|
|
894
|
+
"shrink-0 h-6 w-6 text-muted-foreground/40 hover:text-foreground",
|
|
895
|
+
"opacity-0 group-hover/header:opacity-100 focus-visible:opacity-100"
|
|
896
|
+
)
|
|
897
|
+
}
|
|
898
|
+
)
|
|
899
|
+
] }),
|
|
900
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
901
|
+
components.Button,
|
|
902
|
+
{
|
|
903
|
+
size: "sm",
|
|
904
|
+
variant: isLoadedInPlayground ? "secondary" : "default",
|
|
905
|
+
onClick: onTryIt,
|
|
906
|
+
className: "shrink-0 h-8 text-xs gap-1.5 lg:flex hidden",
|
|
907
|
+
children: [
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-3 w-3" }),
|
|
909
|
+
isLoadedInPlayground ? "Loaded" : "Try it"
|
|
910
|
+
]
|
|
911
|
+
}
|
|
912
|
+
)
|
|
913
|
+
] }),
|
|
914
|
+
endpoint.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(chunkIULI4XII_cjs.MarkdownMessage, { content: endpoint.description }) }),
|
|
915
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
916
|
+
components.Button,
|
|
917
|
+
{
|
|
918
|
+
size: "sm",
|
|
919
|
+
variant: isLoadedInPlayground ? "secondary" : "default",
|
|
920
|
+
onClick: onTryIt,
|
|
921
|
+
className: "lg:hidden h-8 text-xs gap-1.5",
|
|
922
|
+
children: [
|
|
923
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-3 w-3" }),
|
|
924
|
+
isLoadedInPlayground ? "Loaded in playground" : "Try it"
|
|
925
|
+
]
|
|
926
|
+
}
|
|
927
|
+
)
|
|
928
|
+
] }),
|
|
929
|
+
(pathParams.length > 0 || queryParams.length > 0 || endpoint.requestBody || endpoint.responses?.length) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 space-y-8", children: [
|
|
930
|
+
pathParams.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ParamTable, { title: "Path parameters", params: pathParams }),
|
|
931
|
+
queryParams.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ParamTable, { title: "Query parameters", params: queryParams }),
|
|
932
|
+
endpoint.requestBody && /* @__PURE__ */ jsxRuntime.jsx(RequestBodySection, { body: endpoint.requestBody }),
|
|
933
|
+
endpoint.responses && endpoint.responses.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Subsection, { title: "Responses", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: endpoint.responses.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
934
|
+
"div",
|
|
935
|
+
{
|
|
936
|
+
className: "grid grid-cols-[72px_minmax(0,1fr)] items-center gap-3 px-3 py-2.5 bg-background",
|
|
937
|
+
children: [
|
|
938
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { code: r.code }) }),
|
|
939
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground leading-relaxed break-words", children: r.description })
|
|
940
|
+
]
|
|
941
|
+
},
|
|
942
|
+
r.code
|
|
943
|
+
)) }) })
|
|
944
|
+
] })
|
|
945
|
+
]
|
|
946
|
+
}
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
chunkWGEGR3DF_cjs.__name(EndpointDoc, "EndpointDoc");
|
|
950
|
+
function RequestBodySection({ body }) {
|
|
951
|
+
const fields = React6.useMemo(() => schemaToFields(body.schema), [body.schema]);
|
|
952
|
+
const typeLabel = body.schema ? body.type === "array" ? `array<${body.schema.items?.type ?? "object"}>` : body.type : body.type;
|
|
953
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Subsection, { title: "Request body", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
954
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
|
|
955
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/80", children: typeLabel }),
|
|
956
|
+
body.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: body.description })
|
|
957
|
+
] }),
|
|
958
|
+
fields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(FieldsTable, { fields })
|
|
959
|
+
] }) });
|
|
960
|
+
}
|
|
961
|
+
chunkWGEGR3DF_cjs.__name(RequestBodySection, "RequestBodySection");
|
|
962
|
+
function FieldsTable({ fields }) {
|
|
963
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: fields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2.5 bg-background space-y-1", children: [
|
|
964
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
|
|
965
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs font-medium text-foreground", children: f.name }),
|
|
966
|
+
f.required && /* @__PURE__ */ jsxRuntime.jsx(
|
|
967
|
+
"span",
|
|
968
|
+
{
|
|
969
|
+
title: "Required",
|
|
970
|
+
className: "text-[9px] text-destructive font-bold leading-none",
|
|
971
|
+
children: "*"
|
|
972
|
+
}
|
|
973
|
+
),
|
|
974
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/70", children: f.type })
|
|
975
|
+
] }),
|
|
976
|
+
f.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed break-words", children: f.description })
|
|
977
|
+
] }, f.name)) });
|
|
978
|
+
}
|
|
979
|
+
chunkWGEGR3DF_cjs.__name(FieldsTable, "FieldsTable");
|
|
980
|
+
function Subsection({ title, children }) {
|
|
981
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2.5", children: [
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground/70", children: title }),
|
|
983
|
+
children
|
|
984
|
+
] });
|
|
985
|
+
}
|
|
986
|
+
chunkWGEGR3DF_cjs.__name(Subsection, "Subsection");
|
|
987
|
+
function ParamTable({
|
|
988
|
+
title,
|
|
989
|
+
params
|
|
990
|
+
}) {
|
|
991
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Subsection, { title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: params.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2.5 bg-background space-y-1", children: [
|
|
992
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
|
|
993
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs font-medium text-foreground", children: p.name }),
|
|
994
|
+
p.required && /* @__PURE__ */ jsxRuntime.jsx(
|
|
995
|
+
"span",
|
|
996
|
+
{
|
|
997
|
+
title: "Required",
|
|
998
|
+
className: "text-[9px] text-destructive font-bold leading-none",
|
|
999
|
+
children: "*"
|
|
1000
|
+
}
|
|
1001
|
+
),
|
|
1002
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/70", children: p.type })
|
|
1003
|
+
] }),
|
|
1004
|
+
p.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed break-words", children: p.description }) : null
|
|
1005
|
+
] }, p.name)) }) });
|
|
1006
|
+
}
|
|
1007
|
+
chunkWGEGR3DF_cjs.__name(ParamTable, "ParamTable");
|
|
1008
|
+
function StatusTag({ code }) {
|
|
1009
|
+
const numeric = Number.parseInt(code, 10);
|
|
1010
|
+
const cls = !Number.isFinite(numeric) ? "bg-muted text-muted-foreground border-border" : numeric >= 500 ? "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/25" : numeric >= 400 ? "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/25" : numeric >= 300 ? "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25" : "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25";
|
|
1011
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
|
|
1012
|
+
"inline-flex items-center justify-center rounded border px-2 py-0.5 font-mono text-[11px] font-bold leading-none shrink-0 tabular-nums",
|
|
1013
|
+
cls
|
|
1014
|
+
), children: code });
|
|
1015
|
+
}
|
|
1016
|
+
chunkWGEGR3DF_cjs.__name(StatusTag, "StatusTag");
|
|
1017
|
+
var DocsView = React6__default.default.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function DocsView2({
|
|
1018
|
+
info,
|
|
1019
|
+
rawSchema,
|
|
1020
|
+
resolvedBaseUrl,
|
|
1021
|
+
endpoints,
|
|
1022
|
+
selectedVersion,
|
|
1023
|
+
loadedEndpoint,
|
|
1024
|
+
onTryEndpoint,
|
|
1025
|
+
onActiveChange
|
|
1026
|
+
}, ref) {
|
|
1027
|
+
const scrollRef = React6.useRef(null);
|
|
1028
|
+
const visibleEndpoints = React6.useMemo(
|
|
1029
|
+
() => chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion),
|
|
1030
|
+
[endpoints, selectedVersion]
|
|
1031
|
+
);
|
|
1032
|
+
const scrollToAnchor = React6.useCallback((anchor) => {
|
|
1033
|
+
const root = scrollRef.current;
|
|
1034
|
+
if (!root) return;
|
|
1035
|
+
const el = root.querySelector(`[data-endpoint-anchor="${anchor}"]`);
|
|
1036
|
+
if (!el) return;
|
|
1037
|
+
el.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
1038
|
+
}, []);
|
|
1039
|
+
React6__default.default.useImperativeHandle(ref, () => ({ scrollToAnchor }), [scrollToAnchor]);
|
|
1040
|
+
React6.useEffect(() => {
|
|
1041
|
+
const root = scrollRef.current;
|
|
1042
|
+
if (!root) return;
|
|
1043
|
+
let rafId = 0;
|
|
1044
|
+
let lastActive = null;
|
|
1045
|
+
const compute = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
|
|
1046
|
+
rafId = 0;
|
|
1047
|
+
const sections = root.querySelectorAll("[data-endpoint-anchor]");
|
|
1048
|
+
if (sections.length === 0) return;
|
|
1049
|
+
const rootTop = root.getBoundingClientRect().top;
|
|
1050
|
+
const threshold = rootTop + root.clientHeight * 0.25;
|
|
1051
|
+
let active = null;
|
|
1052
|
+
for (const s of Array.from(sections)) {
|
|
1053
|
+
const top = s.getBoundingClientRect().top;
|
|
1054
|
+
if (top <= threshold) {
|
|
1055
|
+
active = s.dataset.endpointAnchor ?? null;
|
|
1056
|
+
} else {
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (active !== lastActive) {
|
|
1061
|
+
lastActive = active;
|
|
1062
|
+
onActiveChange(active);
|
|
1063
|
+
}
|
|
1064
|
+
}, "compute");
|
|
1065
|
+
const onScroll = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
|
|
1066
|
+
if (rafId) return;
|
|
1067
|
+
rafId = requestAnimationFrame(compute);
|
|
1068
|
+
}, "onScroll");
|
|
1069
|
+
compute();
|
|
1070
|
+
root.addEventListener("scroll", onScroll, { passive: true });
|
|
1071
|
+
return () => {
|
|
1072
|
+
root.removeEventListener("scroll", onScroll);
|
|
1073
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
1074
|
+
};
|
|
1075
|
+
}, [visibleEndpoints, onActiveChange]);
|
|
1076
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12", children: [
|
|
1077
|
+
info && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1078
|
+
ApiIntroSection,
|
|
1079
|
+
{
|
|
1080
|
+
info,
|
|
1081
|
+
schema: rawSchema,
|
|
1082
|
+
endpoints: visibleEndpoints,
|
|
1083
|
+
resolvedBaseUrl
|
|
1084
|
+
}
|
|
1085
|
+
),
|
|
1086
|
+
visibleEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-16 text-center text-sm text-muted-foreground", children: "No endpoints to display." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/60", children: visibleEndpoints.map((ep) => {
|
|
1087
|
+
const isLoaded = loadedEndpoint?.method === ep.method && loadedEndpoint?.path === ep.path;
|
|
1088
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1089
|
+
EndpointDoc,
|
|
1090
|
+
{
|
|
1091
|
+
endpoint: ep,
|
|
1092
|
+
isLoadedInPlayground: isLoaded,
|
|
1093
|
+
onTryIt: () => onTryEndpoint(ep)
|
|
1094
|
+
},
|
|
1095
|
+
`${ep.method}-${ep.path}`
|
|
1096
|
+
);
|
|
1097
|
+
}) })
|
|
1098
|
+
] }) });
|
|
1099
|
+
}, "DocsView"));
|
|
1100
|
+
var MAX_DEPTH2 = 6;
|
|
1101
|
+
function defaultForSchema(schema) {
|
|
1102
|
+
if (!schema) return null;
|
|
1103
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
|
|
1104
|
+
switch (schema.type) {
|
|
1105
|
+
case "object": {
|
|
1106
|
+
const out = {};
|
|
1107
|
+
for (const [k, v] of Object.entries(schema.properties ?? {})) {
|
|
1108
|
+
out[k] = defaultForSchema(v);
|
|
1109
|
+
}
|
|
1110
|
+
return out;
|
|
1111
|
+
}
|
|
1112
|
+
case "array":
|
|
1113
|
+
return [];
|
|
1114
|
+
case "integer":
|
|
1115
|
+
case "number":
|
|
1116
|
+
return 0;
|
|
1117
|
+
case "boolean":
|
|
1118
|
+
return false;
|
|
1119
|
+
case "string":
|
|
1120
|
+
return "";
|
|
1121
|
+
default:
|
|
1122
|
+
if (schema.properties) {
|
|
1123
|
+
const out = {};
|
|
1124
|
+
for (const [k, v] of Object.entries(schema.properties)) {
|
|
1125
|
+
out[k] = defaultForSchema(v);
|
|
1126
|
+
}
|
|
1127
|
+
return out;
|
|
1128
|
+
}
|
|
1129
|
+
return "";
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
chunkWGEGR3DF_cjs.__name(defaultForSchema, "defaultForSchema");
|
|
1133
|
+
function BodyFormEditor({ schema, value, onChange }) {
|
|
1134
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1135
|
+
SchemaField,
|
|
1136
|
+
{
|
|
1137
|
+
schema,
|
|
1138
|
+
value,
|
|
1139
|
+
onChange,
|
|
1140
|
+
depth: 0,
|
|
1141
|
+
required: false
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
chunkWGEGR3DF_cjs.__name(BodyFormEditor, "BodyFormEditor");
|
|
1146
|
+
function SchemaField({ schema, value, onChange, depth, required, label }) {
|
|
1147
|
+
if (depth > MAX_DEPTH2) {
|
|
1148
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RawJsonField, { label, value, onChange });
|
|
1149
|
+
}
|
|
1150
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) {
|
|
1151
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnumField, { schema, value, onChange, label, required });
|
|
1152
|
+
}
|
|
1153
|
+
switch (schema.type) {
|
|
1154
|
+
case "object":
|
|
1155
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ObjectField, { schema, value, onChange, depth, label });
|
|
1156
|
+
case "array":
|
|
1157
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ArrayField, { schema, value, onChange, depth, label, required });
|
|
1158
|
+
case "boolean":
|
|
1159
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BooleanField, { value, onChange, label, schema, required });
|
|
1160
|
+
case "integer":
|
|
1161
|
+
case "number":
|
|
1162
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NumberField, { value, onChange, label, schema, required });
|
|
1163
|
+
case "string":
|
|
1164
|
+
default:
|
|
1165
|
+
if (!schema.type && schema.properties) {
|
|
1166
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ObjectField, { schema, value, onChange, depth, label });
|
|
1167
|
+
}
|
|
1168
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StringField, { value, onChange, label, schema, required });
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
chunkWGEGR3DF_cjs.__name(SchemaField, "SchemaField");
|
|
1172
|
+
function FieldHeader({
|
|
1173
|
+
label,
|
|
1174
|
+
type,
|
|
1175
|
+
required,
|
|
1176
|
+
description
|
|
1177
|
+
}) {
|
|
1178
|
+
if (!label) return null;
|
|
1179
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
1180
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1181
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
|
|
1182
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
|
|
1183
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: type })
|
|
1184
|
+
] }),
|
|
1185
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground/70 leading-snug", children: description })
|
|
1186
|
+
] });
|
|
1187
|
+
}
|
|
1188
|
+
chunkWGEGR3DF_cjs.__name(FieldHeader, "FieldHeader");
|
|
1189
|
+
function StringField({
|
|
1190
|
+
value,
|
|
1191
|
+
onChange,
|
|
1192
|
+
label,
|
|
1193
|
+
schema,
|
|
1194
|
+
required
|
|
1195
|
+
}) {
|
|
1196
|
+
const stringValue = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
1197
|
+
const placeholder = schema.format ? `${schema.type ?? "string"} (${schema.format})` : schema.description || schema.type || "string";
|
|
1198
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1199
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: schema.format ? `string (${schema.format})` : "string", required, description: schema.description }),
|
|
1200
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1201
|
+
components.Input,
|
|
1202
|
+
{
|
|
1203
|
+
value: stringValue,
|
|
1204
|
+
onChange: (e) => onChange(e.target.value),
|
|
1205
|
+
placeholder,
|
|
1206
|
+
className: "h-8 text-xs font-mono"
|
|
1207
|
+
}
|
|
1208
|
+
)
|
|
1209
|
+
] });
|
|
1210
|
+
}
|
|
1211
|
+
chunkWGEGR3DF_cjs.__name(StringField, "StringField");
|
|
1212
|
+
function NumberField({
|
|
1213
|
+
value,
|
|
1214
|
+
onChange,
|
|
1215
|
+
label,
|
|
1216
|
+
schema,
|
|
1217
|
+
required
|
|
1218
|
+
}) {
|
|
1219
|
+
const raw = value == null ? "" : String(value);
|
|
1220
|
+
const type = schema.type === "integer" ? "integer" : "number";
|
|
1221
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1222
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: schema.format ? `${type} (${schema.format})` : type, required, description: schema.description }),
|
|
1223
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1224
|
+
components.Input,
|
|
1225
|
+
{
|
|
1226
|
+
type: "number",
|
|
1227
|
+
value: raw,
|
|
1228
|
+
onChange: (e) => {
|
|
1229
|
+
const v = e.target.value;
|
|
1230
|
+
if (v === "") return onChange(null);
|
|
1231
|
+
const n = schema.type === "integer" ? parseInt(v, 10) : parseFloat(v);
|
|
1232
|
+
onChange(Number.isNaN(n) ? null : n);
|
|
1233
|
+
},
|
|
1234
|
+
placeholder: type,
|
|
1235
|
+
className: "h-8 text-xs font-mono"
|
|
1236
|
+
}
|
|
1237
|
+
)
|
|
1238
|
+
] });
|
|
1239
|
+
}
|
|
1240
|
+
chunkWGEGR3DF_cjs.__name(NumberField, "NumberField");
|
|
1241
|
+
function BooleanField({
|
|
1242
|
+
value,
|
|
1243
|
+
onChange,
|
|
1244
|
+
label,
|
|
1245
|
+
schema,
|
|
1246
|
+
required
|
|
1247
|
+
}) {
|
|
1248
|
+
const bool = value === true;
|
|
1249
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1250
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: "boolean", required, description: schema.description }),
|
|
1251
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Switch, { checked: bool, onCheckedChange: onChange, className: "mt-0.5 shrink-0" })
|
|
1252
|
+
] });
|
|
1253
|
+
}
|
|
1254
|
+
chunkWGEGR3DF_cjs.__name(BooleanField, "BooleanField");
|
|
1255
|
+
function EnumField({
|
|
1256
|
+
schema,
|
|
1257
|
+
value,
|
|
1258
|
+
onChange,
|
|
1259
|
+
label,
|
|
1260
|
+
required
|
|
1261
|
+
}) {
|
|
1262
|
+
const options = (schema.enum ?? []).map((v) => ({
|
|
1263
|
+
value: String(v),
|
|
1264
|
+
label: String(v)
|
|
1265
|
+
}));
|
|
1266
|
+
const strValue = value == null ? "" : String(value);
|
|
1267
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1268
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: `${schema.type ?? "enum"} enum`, required, description: schema.description }),
|
|
1269
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1270
|
+
components.Combobox,
|
|
1271
|
+
{
|
|
1272
|
+
options,
|
|
1273
|
+
value: strValue,
|
|
1274
|
+
onValueChange: (v) => {
|
|
1275
|
+
if (schema.type === "integer") onChange(parseInt(v, 10));
|
|
1276
|
+
else if (schema.type === "number") onChange(parseFloat(v));
|
|
1277
|
+
else onChange(v);
|
|
1278
|
+
},
|
|
1279
|
+
placeholder: "Select\u2026",
|
|
1280
|
+
searchPlaceholder: "Search\u2026",
|
|
1281
|
+
className: "h-8 text-xs"
|
|
1282
|
+
}
|
|
1283
|
+
)
|
|
1284
|
+
] });
|
|
1285
|
+
}
|
|
1286
|
+
chunkWGEGR3DF_cjs.__name(EnumField, "EnumField");
|
|
1287
|
+
function RawJsonField({
|
|
1288
|
+
label,
|
|
1289
|
+
value,
|
|
1290
|
+
onChange
|
|
1291
|
+
}) {
|
|
1292
|
+
const [text, setText] = React6__default.default.useState(() => JSON.stringify(value ?? null, null, 2));
|
|
1293
|
+
React6__default.default.useEffect(() => {
|
|
1294
|
+
setText(JSON.stringify(value ?? null, null, 2));
|
|
1295
|
+
}, [value]);
|
|
1296
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1297
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(SectionLabel, { children: [
|
|
1298
|
+
label,
|
|
1299
|
+
" (raw)"
|
|
1300
|
+
] }),
|
|
1301
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1302
|
+
components.Textarea,
|
|
1303
|
+
{
|
|
1304
|
+
value: text,
|
|
1305
|
+
onChange: (e) => {
|
|
1306
|
+
setText(e.target.value);
|
|
1307
|
+
try {
|
|
1308
|
+
onChange(JSON.parse(e.target.value));
|
|
1309
|
+
} catch {
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
className: "font-mono text-[11px] min-h-[80px]",
|
|
1313
|
+
rows: 4
|
|
1314
|
+
}
|
|
1315
|
+
)
|
|
1316
|
+
] });
|
|
1317
|
+
}
|
|
1318
|
+
chunkWGEGR3DF_cjs.__name(RawJsonField, "RawJsonField");
|
|
1319
|
+
function ObjectField({
|
|
1320
|
+
schema,
|
|
1321
|
+
value,
|
|
1322
|
+
onChange,
|
|
1323
|
+
depth,
|
|
1324
|
+
label
|
|
1325
|
+
}) {
|
|
1326
|
+
const obj = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1327
|
+
const required = new Set(schema.required ?? []);
|
|
1328
|
+
const entries = Object.entries(schema.properties ?? {});
|
|
1329
|
+
const setKey = React6.useCallback(
|
|
1330
|
+
(key) => (next) => {
|
|
1331
|
+
onChange({ ...obj, [key]: next });
|
|
1332
|
+
},
|
|
1333
|
+
[obj, onChange]
|
|
1334
|
+
);
|
|
1335
|
+
if (entries.length === 0) {
|
|
1336
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RawJsonField, { label, value: obj, onChange });
|
|
1337
|
+
}
|
|
1338
|
+
const wrapperClass = depth === 0 ? "space-y-3" : "space-y-2 border-l-2 border-border/60 pl-3 ml-px";
|
|
1339
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1340
|
+
label && depth > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1341
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
|
|
1342
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: "object" })
|
|
1343
|
+
] }),
|
|
1344
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn(wrapperClass), children: entries.map(([key, subSchema]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1345
|
+
SchemaField,
|
|
1346
|
+
{
|
|
1347
|
+
schema: subSchema,
|
|
1348
|
+
value: obj[key],
|
|
1349
|
+
onChange: setKey(key),
|
|
1350
|
+
depth: depth + 1,
|
|
1351
|
+
required: required.has(key),
|
|
1352
|
+
label: key
|
|
1353
|
+
},
|
|
1354
|
+
key
|
|
1355
|
+
)) })
|
|
1356
|
+
] });
|
|
1357
|
+
}
|
|
1358
|
+
chunkWGEGR3DF_cjs.__name(ObjectField, "ObjectField");
|
|
1359
|
+
function ArrayField({
|
|
1360
|
+
schema,
|
|
1361
|
+
value,
|
|
1362
|
+
onChange,
|
|
1363
|
+
depth,
|
|
1364
|
+
label,
|
|
1365
|
+
required
|
|
1366
|
+
}) {
|
|
1367
|
+
const arr = Array.isArray(value) ? value : [];
|
|
1368
|
+
const items = schema.items ?? { type: "string" };
|
|
1369
|
+
const addItem = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => onChange([...arr, defaultForSchema(items)]), "addItem");
|
|
1370
|
+
const removeAt = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((i) => onChange(arr.filter((_, idx) => idx !== i)), "removeAt");
|
|
1371
|
+
const setAt = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((i) => (next) => onChange(arr.map((v, idx) => idx === i ? next : v)), "setAt");
|
|
1372
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1373
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1374
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
|
|
1375
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
|
|
1376
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: `array<${items.type ?? "any"}>` })
|
|
1377
|
+
] }),
|
|
1378
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 border-l-2 border-border/60 pl-3 ml-px", children: [
|
|
1379
|
+
arr.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground/50 italic", children: "Empty array" }),
|
|
1380
|
+
arr.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
1381
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1382
|
+
SchemaField,
|
|
1383
|
+
{
|
|
1384
|
+
schema: items,
|
|
1385
|
+
value: v,
|
|
1386
|
+
onChange: setAt(i),
|
|
1387
|
+
depth: depth + 1,
|
|
1388
|
+
required: false,
|
|
1389
|
+
label: `${label ?? ""}[${i}]`
|
|
1390
|
+
}
|
|
1391
|
+
) }),
|
|
1392
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1393
|
+
"button",
|
|
1394
|
+
{
|
|
1395
|
+
type: "button",
|
|
1396
|
+
onClick: () => removeAt(i),
|
|
1397
|
+
title: "Remove item",
|
|
1398
|
+
className: "shrink-0 h-7 w-7 inline-flex items-center justify-center rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors",
|
|
1399
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-3.5 w-3.5" })
|
|
1400
|
+
}
|
|
1401
|
+
)
|
|
1402
|
+
] }, i)),
|
|
1403
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1404
|
+
"button",
|
|
1405
|
+
{
|
|
1406
|
+
type: "button",
|
|
1407
|
+
onClick: addItem,
|
|
1408
|
+
className: "inline-flex items-center gap-1.5 text-[10px] text-muted-foreground hover:text-foreground transition-colors py-1",
|
|
1409
|
+
children: [
|
|
1410
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3" }),
|
|
1411
|
+
"Add item"
|
|
1412
|
+
]
|
|
1413
|
+
}
|
|
1414
|
+
)
|
|
1415
|
+
] })
|
|
1416
|
+
] });
|
|
1417
|
+
}
|
|
1418
|
+
chunkWGEGR3DF_cjs.__name(ArrayField, "ArrayField");
|
|
1419
|
+
function EndpointResetButton() {
|
|
1420
|
+
const { state, setParameters, setRequestBody } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1421
|
+
const ep = state.selectedEndpoint;
|
|
1422
|
+
const { reset } = useEndpointDraft(state.activeSchemaId, ep);
|
|
1423
|
+
const hasDraft = Object.keys(state.parameters).length > 0 || state.requestBody.length > 0;
|
|
1424
|
+
const onClick = React6.useCallback(() => {
|
|
1425
|
+
setParameters({});
|
|
1426
|
+
setRequestBody("");
|
|
1427
|
+
reset();
|
|
1428
|
+
}, [setParameters, setRequestBody, reset]);
|
|
1429
|
+
if (!ep || !hasDraft) return null;
|
|
1430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1431
|
+
"button",
|
|
1432
|
+
{
|
|
1433
|
+
type: "button",
|
|
1434
|
+
onClick,
|
|
1435
|
+
title: "Reset parameters & body (keeps auth)",
|
|
1436
|
+
className: lib.cn(
|
|
1437
|
+
"inline-flex items-center gap-1 text-[10px] text-muted-foreground",
|
|
1438
|
+
"hover:text-foreground transition-colors"
|
|
1439
|
+
),
|
|
1440
|
+
children: [
|
|
1441
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "h-2.5 w-2.5" }),
|
|
1442
|
+
"Reset"
|
|
1443
|
+
]
|
|
1444
|
+
}
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
chunkWGEGR3DF_cjs.__name(EndpointResetButton, "EndpointResetButton");
|
|
1448
|
+
function ParamFields({ label, params }) {
|
|
1449
|
+
const { state, setParameters } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1450
|
+
function handleChange(name, value) {
|
|
1451
|
+
setParameters({ ...state.parameters, [name]: value });
|
|
1452
|
+
}
|
|
1453
|
+
chunkWGEGR3DF_cjs.__name(handleChange, "handleChange");
|
|
1454
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1455
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: label }),
|
|
1456
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: params.map((p) => {
|
|
1457
|
+
const value = state.parameters[p.name] ?? "";
|
|
1458
|
+
const placeholder = p.description || p.name;
|
|
1459
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: p.name }),
|
|
1462
|
+
p.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
|
|
1463
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: p.type })
|
|
1464
|
+
] }),
|
|
1465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1466
|
+
components.Input,
|
|
1467
|
+
{
|
|
1468
|
+
value,
|
|
1469
|
+
onChange: (e) => handleChange(p.name, e.target.value),
|
|
1470
|
+
placeholder,
|
|
1471
|
+
className: "h-8 text-xs font-mono"
|
|
1472
|
+
}
|
|
1473
|
+
)
|
|
1474
|
+
] }, p.name);
|
|
1475
|
+
}) })
|
|
1476
|
+
] });
|
|
1477
|
+
}
|
|
1478
|
+
chunkWGEGR3DF_cjs.__name(ParamFields, "ParamFields");
|
|
1479
|
+
function RequestPanel() {
|
|
1480
|
+
const {
|
|
1481
|
+
state,
|
|
1482
|
+
apiKeys,
|
|
1483
|
+
apiKeysLoading,
|
|
1484
|
+
setRequestBody,
|
|
1485
|
+
setRequestHeaders,
|
|
1486
|
+
setSelectedApiKey,
|
|
1487
|
+
setManualApiToken,
|
|
1488
|
+
sendRequest
|
|
1489
|
+
} = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1490
|
+
const apiKeyOptions = React6.useMemo(
|
|
1491
|
+
() => apiKeys.map((k) => ({
|
|
1492
|
+
value: k.id,
|
|
1493
|
+
label: k.name || "Unnamed key",
|
|
1494
|
+
// Surface the first 8 chars of the secret so the user
|
|
1495
|
+
// can tell two similarly-named keys apart at a glance.
|
|
1496
|
+
description: k.secret ? `${k.secret.slice(0, 8)}\u2026` : void 0
|
|
1497
|
+
})),
|
|
1498
|
+
[apiKeys]
|
|
1499
|
+
);
|
|
1500
|
+
const hasApiKeys = apiKeyOptions.length > 0;
|
|
1501
|
+
const ep = state.selectedEndpoint;
|
|
1502
|
+
const isJsonValid = state.requestBody ? chunkIULI4XII_cjs.isValidJson(state.requestBody) : true;
|
|
1503
|
+
const curlCommand = React6.useMemo(() => {
|
|
1504
|
+
if (!state.requestUrl) return "";
|
|
1505
|
+
const absoluteUrl = chunkIULI4XII_cjs.resolveAbsolute(state.requestUrl);
|
|
1506
|
+
const apiKey = state.selectedApiKey ? chunkIULI4XII_cjs.findApiKeyById(apiKeys, state.selectedApiKey) : null;
|
|
1507
|
+
const hdrs = chunkIULI4XII_cjs.parseRequestHeaders(state.requestHeaders);
|
|
1508
|
+
if (apiKey) hdrs["X-API-Key"] = apiKey.secret || apiKey.id;
|
|
1509
|
+
let cmd = `curl -X ${state.requestMethod} "${absoluteUrl}"`;
|
|
1510
|
+
Object.entries(hdrs).forEach(([k, v]) => {
|
|
1511
|
+
cmd += ` \\
|
|
1512
|
+
-H "${k}: ${v}"`;
|
|
1513
|
+
});
|
|
1514
|
+
if (state.requestBody && state.requestMethod !== "GET" && isJsonValid) {
|
|
1515
|
+
cmd += ` \\
|
|
1516
|
+
-d '${state.requestBody}'`;
|
|
1517
|
+
}
|
|
1518
|
+
return cmd;
|
|
1519
|
+
}, [state, apiKeys, isJsonValid]);
|
|
1520
|
+
const pathParams = React6.useMemo(
|
|
1521
|
+
() => ep?.parameters?.filter((p) => ep.path.includes(`{${p.name}}`)) ?? [],
|
|
1522
|
+
[ep]
|
|
1523
|
+
);
|
|
1524
|
+
const queryParams = React6.useMemo(
|
|
1525
|
+
() => ep?.parameters?.filter((p) => !ep.path.includes(`{${p.name}}`)) ?? [],
|
|
1526
|
+
[ep]
|
|
1527
|
+
);
|
|
1528
|
+
state.loading || !state.requestUrl || !isJsonValid;
|
|
1529
|
+
const displayUrl = chunkIULI4XII_cjs.resolveAbsolute(state.requestUrl || ep?.path || "");
|
|
1530
|
+
const hasBody = ep?.method !== "GET";
|
|
1531
|
+
const bodyType = ep?.requestBody?.type ?? "";
|
|
1532
|
+
const hasPathParams = pathParams.length > 0;
|
|
1533
|
+
const hasQueryParams = queryParams.length > 0;
|
|
1534
|
+
const hasCurl = Boolean(curlCommand);
|
|
1535
|
+
const epPath = ep ? chunkIULI4XII_cjs.relativePath(ep.path) : "";
|
|
1536
|
+
const urlChanged = displayUrl !== "" && displayUrl !== epPath;
|
|
1537
|
+
if (!ep) {
|
|
1538
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Send, text: "Select an endpoint to build a request" });
|
|
1539
|
+
}
|
|
1540
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1541
|
+
(urlChanged || ep) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-4 py-2 bg-muted/10 flex items-center gap-2 min-h-[28px]", children: [
|
|
1542
|
+
urlChanged ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/60 break-all leading-snug truncate min-w-0 flex-1", children: displayUrl }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
1543
|
+
/* @__PURE__ */ jsxRuntime.jsx(EndpointResetButton, {})
|
|
1544
|
+
] }),
|
|
1545
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "px-4 py-3 space-y-3", children: [
|
|
1546
|
+
hasPathParams && /* @__PURE__ */ jsxRuntime.jsx(ParamFields, { label: "Path Parameters", params: pathParams }),
|
|
1547
|
+
hasQueryParams && /* @__PURE__ */ jsxRuntime.jsx(ParamFields, { label: "Query Parameters", params: queryParams }),
|
|
1548
|
+
hasBody && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1549
|
+
BodySection,
|
|
1550
|
+
{
|
|
1551
|
+
schema: ep.requestBody?.schema,
|
|
1552
|
+
bodyType,
|
|
1553
|
+
bodyDescription: ep.requestBody?.description,
|
|
1554
|
+
value: state.requestBody,
|
|
1555
|
+
onChange: setRequestBody,
|
|
1556
|
+
isJsonValid
|
|
1557
|
+
}
|
|
1558
|
+
),
|
|
1559
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1560
|
+
CollapsibleSection,
|
|
1561
|
+
{
|
|
1562
|
+
label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1563
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Key, { className: "h-2.5 w-2.5" }),
|
|
1564
|
+
"Auth & Headers"
|
|
1565
|
+
] }),
|
|
1566
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 pt-2", children: [
|
|
1567
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1568
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "API Key" }),
|
|
1569
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1570
|
+
components.Combobox,
|
|
1571
|
+
{
|
|
1572
|
+
options: apiKeyOptions,
|
|
1573
|
+
value: state.selectedApiKey ?? "",
|
|
1574
|
+
onValueChange: (v) => setSelectedApiKey(v || null),
|
|
1575
|
+
placeholder: apiKeysLoading ? "Loading keys\u2026" : hasApiKeys ? "Select an API key" : "No API keys yet",
|
|
1576
|
+
searchPlaceholder: "Search keys\u2026",
|
|
1577
|
+
emptyText: "No matching key",
|
|
1578
|
+
disabled: apiKeysLoading || !hasApiKeys,
|
|
1579
|
+
className: "h-8"
|
|
1580
|
+
}
|
|
1581
|
+
),
|
|
1582
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[10px] text-muted-foreground", children: [
|
|
1583
|
+
"Picks are sent via the",
|
|
1584
|
+
" ",
|
|
1585
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: "X-API-Key" }),
|
|
1586
|
+
" header."
|
|
1587
|
+
] })
|
|
1588
|
+
] }),
|
|
1589
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1590
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Bearer Token" }),
|
|
1591
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1592
|
+
components.Input,
|
|
1593
|
+
{
|
|
1594
|
+
type: "password",
|
|
1595
|
+
placeholder: "Leave empty to use JWT from localStorage",
|
|
1596
|
+
value: state.manualApiToken,
|
|
1597
|
+
onChange: (e) => setManualApiToken(e.target.value),
|
|
1598
|
+
className: "font-mono text-xs h-8"
|
|
1599
|
+
}
|
|
1600
|
+
)
|
|
1601
|
+
] }),
|
|
1602
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1603
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Headers" }),
|
|
1604
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1605
|
+
components.Textarea,
|
|
1606
|
+
{
|
|
1607
|
+
value: state.requestHeaders,
|
|
1608
|
+
onChange: (e) => setRequestHeaders(e.target.value),
|
|
1609
|
+
className: "font-mono text-[11px] min-h-[60px] resize-y",
|
|
1610
|
+
rows: 3
|
|
1611
|
+
}
|
|
1612
|
+
)
|
|
1613
|
+
] })
|
|
1614
|
+
] })
|
|
1615
|
+
}
|
|
1616
|
+
),
|
|
1617
|
+
hasCurl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1618
|
+
CollapsibleSection,
|
|
1619
|
+
{
|
|
1620
|
+
label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1621
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Terminal, { className: "h-2.5 w-2.5" }),
|
|
1622
|
+
"cURL"
|
|
1623
|
+
] }),
|
|
1624
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1625
|
+
chunkIULI4XII_cjs.PrettyCode_default,
|
|
1626
|
+
{
|
|
1627
|
+
data: curlCommand,
|
|
1628
|
+
language: "bash",
|
|
1629
|
+
isCompact: true,
|
|
1630
|
+
maxLines: 50
|
|
1631
|
+
}
|
|
1632
|
+
) })
|
|
1633
|
+
}
|
|
1634
|
+
),
|
|
1635
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4" })
|
|
1636
|
+
] })
|
|
1637
|
+
] });
|
|
1638
|
+
}
|
|
1639
|
+
chunkWGEGR3DF_cjs.__name(RequestPanel, "RequestPanel");
|
|
1640
|
+
function BodySection({ schema, bodyType, bodyDescription, value, onChange, isJsonValid }) {
|
|
1641
|
+
const hasSchema = !!schema;
|
|
1642
|
+
const [mode, setMode] = React6__default.default.useState(hasSchema ? "form" : "json");
|
|
1643
|
+
const parsed = React6__default.default.useMemo(() => {
|
|
1644
|
+
if (!value) return null;
|
|
1645
|
+
try {
|
|
1646
|
+
return JSON.parse(value);
|
|
1647
|
+
} catch {
|
|
1648
|
+
return null;
|
|
1649
|
+
}
|
|
1650
|
+
}, [value]);
|
|
1651
|
+
const handleFormChange = React6.useCallback(
|
|
1652
|
+
(next) => {
|
|
1653
|
+
onChange(JSON.stringify(next, null, 2));
|
|
1654
|
+
},
|
|
1655
|
+
[onChange]
|
|
1656
|
+
);
|
|
1657
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1658
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
1659
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 min-w-0", children: [
|
|
1660
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Body" }),
|
|
1661
|
+
bodyType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/40 font-mono", children: bodyType }),
|
|
1662
|
+
bodyDescription && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/60 truncate", children: bodyDescription })
|
|
1663
|
+
] }),
|
|
1664
|
+
hasSchema && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex rounded-md border overflow-hidden text-[10px]", children: [
|
|
1665
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModeButton, { active: mode === "form", onClick: () => setMode("form"), children: "Form" }),
|
|
1666
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModeButton, { active: mode === "json", onClick: () => setMode("json"), children: "JSON" })
|
|
1667
|
+
] }),
|
|
1668
|
+
mode === "json" && isJsonValid && value && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1669
|
+
"button",
|
|
1670
|
+
{
|
|
1671
|
+
type: "button",
|
|
1672
|
+
onClick: () => {
|
|
1673
|
+
try {
|
|
1674
|
+
onChange(JSON.stringify(JSON.parse(value), null, 2));
|
|
1675
|
+
} catch {
|
|
1676
|
+
}
|
|
1677
|
+
},
|
|
1678
|
+
className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors",
|
|
1679
|
+
children: [
|
|
1680
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-2.5 w-2.5" }),
|
|
1681
|
+
"Format"
|
|
1682
|
+
]
|
|
1683
|
+
}
|
|
1684
|
+
)
|
|
1685
|
+
] }),
|
|
1686
|
+
mode === "form" && hasSchema ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1687
|
+
BodyFormEditor,
|
|
1688
|
+
{
|
|
1689
|
+
schema,
|
|
1690
|
+
value: parsed,
|
|
1691
|
+
onChange: handleFormChange
|
|
1692
|
+
}
|
|
1693
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1694
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1695
|
+
components.Textarea,
|
|
1696
|
+
{
|
|
1697
|
+
placeholder: '{\n "key": "value"\n}',
|
|
1698
|
+
value,
|
|
1699
|
+
onChange: (e) => onChange(e.target.value),
|
|
1700
|
+
className: lib.cn(
|
|
1701
|
+
"font-mono text-[11px] min-h-[90px] resize-y",
|
|
1702
|
+
!isJsonValid && "border-destructive focus-visible:ring-destructive/30"
|
|
1703
|
+
),
|
|
1704
|
+
rows: 4
|
|
1705
|
+
}
|
|
1706
|
+
),
|
|
1707
|
+
!isJsonValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-destructive", children: "Invalid JSON" })
|
|
1708
|
+
] })
|
|
1709
|
+
] });
|
|
1710
|
+
}
|
|
1711
|
+
chunkWGEGR3DF_cjs.__name(BodySection, "BodySection");
|
|
1712
|
+
function ModeButton({
|
|
1713
|
+
active,
|
|
1714
|
+
onClick,
|
|
1715
|
+
children
|
|
1716
|
+
}) {
|
|
1717
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1718
|
+
"button",
|
|
1719
|
+
{
|
|
1720
|
+
type: "button",
|
|
1721
|
+
onClick,
|
|
1722
|
+
className: lib.cn(
|
|
1723
|
+
"px-2 py-0.5 font-medium transition-colors",
|
|
1724
|
+
active ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:text-foreground"
|
|
1725
|
+
),
|
|
1726
|
+
children
|
|
1727
|
+
}
|
|
1728
|
+
);
|
|
1729
|
+
}
|
|
1730
|
+
chunkWGEGR3DF_cjs.__name(ModeButton, "ModeButton");
|
|
1731
|
+
var JSON_TREE_CONFIG = {
|
|
1732
|
+
maxAutoExpandDepth: 2,
|
|
1733
|
+
maxAutoExpandArrayItems: 10,
|
|
1734
|
+
maxAutoExpandObjectKeys: 5,
|
|
1735
|
+
maxStringLength: 200,
|
|
1736
|
+
collectionLimit: 50,
|
|
1737
|
+
showCollectionInfo: true,
|
|
1738
|
+
showExpandControls: true,
|
|
1739
|
+
showActionButtons: false,
|
|
1740
|
+
preserveKeyOrder: true,
|
|
1741
|
+
className: "border-0 rounded-none"
|
|
1742
|
+
};
|
|
1743
|
+
function ResponsePanel() {
|
|
1744
|
+
const { state } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1745
|
+
const { response, loading, selectedEndpoint } = state;
|
|
1746
|
+
const { treeData, rawText } = React6.useMemo(() => {
|
|
1747
|
+
const d = response?.data;
|
|
1748
|
+
if (d == null) return { treeData: null, rawText: "" };
|
|
1749
|
+
if (typeof d === "string") {
|
|
1750
|
+
try {
|
|
1751
|
+
return { treeData: JSON.parse(d), rawText: d };
|
|
1752
|
+
} catch {
|
|
1753
|
+
return { treeData: null, rawText: d };
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
return { treeData: d, rawText: JSON.stringify(d, null, 2) };
|
|
1757
|
+
}, [response?.data]);
|
|
1758
|
+
const sizeKb = rawText ? `${(rawText.length / 1024).toFixed(1)} KB` : "";
|
|
1759
|
+
const duration = response?.duration != null ? `${response.duration}ms` : "";
|
|
1760
|
+
const hasError = Boolean(response?.error);
|
|
1761
|
+
const hasStatus = response?.status != null;
|
|
1762
|
+
const hasCopy = Boolean(rawText);
|
|
1763
|
+
if (loading) {
|
|
1764
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center h-full gap-2", children: [
|
|
1765
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
|
|
1766
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Sending\u2026" })
|
|
1767
|
+
] });
|
|
1768
|
+
}
|
|
1769
|
+
if (!selectedEndpoint) return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Terminal, text: "Response will appear here" });
|
|
1770
|
+
if (!response) return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Send, text: 'Press "Send Request" to see the response' });
|
|
1771
|
+
if (hasError && !hasStatus) {
|
|
1772
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1773
|
+
EmptyState,
|
|
1774
|
+
{
|
|
1775
|
+
icon: lucideReact.WifiOff,
|
|
1776
|
+
text: response.error,
|
|
1777
|
+
className: "text-destructive [&_svg]:text-destructive"
|
|
1778
|
+
}
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1782
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-4 py-2 flex items-center justify-between gap-3 bg-muted/20", children: [
|
|
1783
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
1784
|
+
hasStatus && /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: response.status }),
|
|
1785
|
+
response.statusText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground truncate", children: response.statusText }),
|
|
1786
|
+
sizeKb && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/50 tabular-nums shrink-0", children: sizeKb }),
|
|
1787
|
+
duration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/50 tabular-nums shrink-0", children: duration })
|
|
1788
|
+
] }),
|
|
1789
|
+
hasCopy && /* @__PURE__ */ jsxRuntime.jsx(components.CopyButton, { value: rawText, variant: "ghost", size: "sm", className: "h-6 px-2 text-[10px] text-muted-foreground shrink-0", children: "Copy" })
|
|
1790
|
+
] }),
|
|
1791
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 mx-4 mt-3 rounded border border-destructive/20 bg-destructive/5 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: response.error }) }),
|
|
1792
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { children: treeData != null ? /* @__PURE__ */ jsxRuntime.jsx(chunk33AMWFBZ_cjs.JsonTree_default, { title: "Response Body", data: treeData, config: JSON_TREE_CONFIG }) : rawText ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-4 text-[11px] font-mono text-foreground/70 whitespace-pre-wrap break-all leading-relaxed", children: rawText }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 text-center text-xs text-muted-foreground", children: "Empty response body" }) })
|
|
1793
|
+
] });
|
|
1794
|
+
}
|
|
1795
|
+
chunkWGEGR3DF_cjs.__name(ResponsePanel, "ResponsePanel");
|
|
1796
|
+
function SendButton({ className }) {
|
|
1797
|
+
const { state, sendRequest } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1798
|
+
const ep = state.selectedEndpoint;
|
|
1799
|
+
const builder = React6.useMemo(
|
|
1800
|
+
() => ep ? new chunkIULI4XII_cjs.UrlBuilder(ep, state.parameters) : null,
|
|
1801
|
+
[ep, state.parameters]
|
|
1802
|
+
);
|
|
1803
|
+
const missingRequired = builder?.missingRequired() ?? [];
|
|
1804
|
+
const unsubstituted = builder?.unfilledPlaceholders() ?? [];
|
|
1805
|
+
const isJsonValid = state.requestBody ? chunkIULI4XII_cjs.isValidJson(state.requestBody) : true;
|
|
1806
|
+
const blockers = [];
|
|
1807
|
+
if (missingRequired.length > 0) {
|
|
1808
|
+
blockers.push(
|
|
1809
|
+
`Fill required parameter${missingRequired.length > 1 ? "s" : ""}: ${missingRequired.join(", ")}`
|
|
1810
|
+
);
|
|
1811
|
+
} else if (unsubstituted.length > 0) {
|
|
1812
|
+
blockers.push(`URL still has unfilled placeholder${unsubstituted.length > 1 ? "s" : ""}: ${unsubstituted.map((n) => `{${n}}`).join(", ")}`);
|
|
1813
|
+
}
|
|
1814
|
+
if (!isJsonValid) blockers.push("Request body is not valid JSON");
|
|
1815
|
+
const disabled = state.loading || !state.requestUrl || blockers.length > 0;
|
|
1816
|
+
const tooltip = blockers.length > 0 ? blockers.join("\n") : void 0;
|
|
1817
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("space-y-2", className), children: [
|
|
1818
|
+
blockers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 rounded-md border border-amber-500/25 bg-amber-500/[0.06] px-3 py-2 text-[11px] text-amber-600 dark:text-amber-400", children: [
|
|
1819
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-3.5 w-3.5 shrink-0 mt-px" }),
|
|
1820
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "leading-snug", children: blockers[0] })
|
|
1821
|
+
] }),
|
|
1822
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1823
|
+
components.Button,
|
|
1824
|
+
{
|
|
1825
|
+
onClick: sendRequest,
|
|
1826
|
+
disabled,
|
|
1827
|
+
size: "sm",
|
|
1828
|
+
title: tooltip,
|
|
1829
|
+
className: "w-full gap-2 h-9",
|
|
1830
|
+
children: state.loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1831
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
1832
|
+
"Sending\u2026"
|
|
1833
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1834
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3.5 w-3.5" }),
|
|
1835
|
+
"Send Request"
|
|
1836
|
+
] })
|
|
1837
|
+
}
|
|
1838
|
+
)
|
|
1839
|
+
] });
|
|
1840
|
+
}
|
|
1841
|
+
chunkWGEGR3DF_cjs.__name(SendButton, "SendButton");
|
|
1842
|
+
var WIDTH_NARROW = "clamp(380px, 30vw, 480px)";
|
|
1843
|
+
var WIDTH_WIDE = "clamp(720px, 60vw, 1280px)";
|
|
1844
|
+
function SlideInPlayground({ open, onClose }) {
|
|
1845
|
+
const { state } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1846
|
+
const ep = state.selectedEndpoint;
|
|
1847
|
+
const showResponse = state.response !== null || state.loading;
|
|
1848
|
+
const width = showResponse ? WIDTH_WIDE : WIDTH_NARROW;
|
|
1849
|
+
return /* @__PURE__ */ jsxRuntime.jsx(components.SidePanel, { open, onOpenChange: (v) => !v && onClose(), side: "right", children: /* @__PURE__ */ jsxRuntime.jsxs(components.SidePanel.Content, { width, className: "max-w-[95vw]", children: [
|
|
1850
|
+
/* @__PURE__ */ jsxRuntime.jsxs(components.SidePanel.Header, { children: [
|
|
1851
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.SidePanel.Title, { children: "Playground" }),
|
|
1852
|
+
ep && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
|
|
1853
|
+
/* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: ep.method }),
|
|
1854
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground truncate", children: chunkIULI4XII_cjs.relativePath(ep.path) })
|
|
1855
|
+
] }),
|
|
1856
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.SidePanel.Close, { className: "ml-auto" })
|
|
1857
|
+
] }),
|
|
1858
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1859
|
+
components.SidePanel.Body,
|
|
1860
|
+
{
|
|
1861
|
+
className: lib.cn(
|
|
1862
|
+
"overflow-hidden grid divide-x transition-[grid-template-columns] duration-250",
|
|
1863
|
+
showResponse ? "grid-cols-[minmax(0,1fr)_minmax(0,1fr)]" : "grid-cols-1"
|
|
1864
|
+
),
|
|
1865
|
+
children: [
|
|
1866
|
+
/* @__PURE__ */ jsxRuntime.jsx(Panel, { children: /* @__PURE__ */ jsxRuntime.jsx(RequestPanel, {}) }),
|
|
1867
|
+
showResponse && /* @__PURE__ */ jsxRuntime.jsx(Panel, { children: /* @__PURE__ */ jsxRuntime.jsx(ResponsePanel, {}) })
|
|
1868
|
+
]
|
|
1869
|
+
}
|
|
1870
|
+
),
|
|
1871
|
+
ep && /* @__PURE__ */ jsxRuntime.jsx(components.SidePanel.Footer, { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(SendButton, {}) })
|
|
1872
|
+
] }) });
|
|
1873
|
+
}
|
|
1874
|
+
chunkWGEGR3DF_cjs.__name(SlideInPlayground, "SlideInPlayground");
|
|
1875
|
+
function TryItSheet({ open, onOpenChange }) {
|
|
1876
|
+
const { state } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1877
|
+
const showResponse = state.response !== null || state.loading;
|
|
1878
|
+
return /* @__PURE__ */ jsxRuntime.jsx(components.ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(components.ResponsiveSheetContent, { className: "sm:max-w-xl flex flex-col h-full p-0", children: [
|
|
1879
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.ResponsiveSheetHeader, { className: "px-4 py-3 border-b shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(components.ResponsiveSheetTitle, { className: "text-sm", children: "Playground" }) }),
|
|
1880
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-h-0 flex flex-col divide-y", children: [
|
|
1881
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: showResponse ? "flex-1 min-h-0 flex flex-col" : "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(RequestPanel, {}) }),
|
|
1882
|
+
showResponse && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(ResponsePanel, {}) })
|
|
1883
|
+
] }),
|
|
1884
|
+
state.selectedEndpoint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t px-4 py-3 bg-background/95 backdrop-blur-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SendButton, {}) })
|
|
1885
|
+
] }) });
|
|
1886
|
+
}
|
|
1887
|
+
chunkWGEGR3DF_cjs.__name(TryItSheet, "TryItSheet");
|
|
1888
|
+
var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
|
|
1889
|
+
const { state, config, setSelectedEndpoint } = chunkIULI4XII_cjs.usePlaygroundContext();
|
|
1890
|
+
const isDesktop = hooks.useMediaQuery("(min-width: 1024px)");
|
|
1891
|
+
const isMobile = !isDesktop;
|
|
1892
|
+
const {
|
|
1893
|
+
endpoints,
|
|
1894
|
+
schemaInfo,
|
|
1895
|
+
rawSchema,
|
|
1896
|
+
resolvedBaseUrl,
|
|
1897
|
+
loading,
|
|
1898
|
+
error,
|
|
1899
|
+
schemas,
|
|
1900
|
+
currentSchema,
|
|
1901
|
+
setCurrentSchema
|
|
1902
|
+
} = useOpenApiSchema({
|
|
1903
|
+
schemas: config.schemas,
|
|
1904
|
+
defaultSchemaId: config.defaultSchemaId,
|
|
1905
|
+
baseUrl: config.baseUrl
|
|
1906
|
+
});
|
|
1907
|
+
const [activeAnchor, setActiveAnchor] = React6.useState(null);
|
|
1908
|
+
const [sheetOpen, setSheetOpen] = React6.useState(false);
|
|
1909
|
+
const docsRef = React6.useRef(null);
|
|
1910
|
+
const slideOpen = !isMobile && state.selectedEndpoint !== null;
|
|
1911
|
+
const handleTry = React6.useCallback(
|
|
1912
|
+
(ep) => {
|
|
1913
|
+
setSelectedEndpoint(ep);
|
|
1914
|
+
if (isMobile) setSheetOpen(true);
|
|
1915
|
+
},
|
|
1916
|
+
[isMobile, setSelectedEndpoint]
|
|
1917
|
+
);
|
|
1918
|
+
const handleCloseSlide = React6.useCallback(() => {
|
|
1919
|
+
setSelectedEndpoint(null);
|
|
1920
|
+
}, [setSelectedEndpoint]);
|
|
1921
|
+
const handleNavigate = React6.useCallback((anchor) => {
|
|
1922
|
+
docsRef.current?.scrollToAnchor(anchor);
|
|
1923
|
+
}, []);
|
|
1924
|
+
if (loading) {
|
|
1925
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1926
|
+
"div",
|
|
1927
|
+
{
|
|
1928
|
+
className: "grid grid-cols-[260px_1fr] min-h-0 overflow-hidden",
|
|
1929
|
+
style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
|
|
1930
|
+
children: [
|
|
1931
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-r p-3 space-y-1.5", children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-full rounded" }, i)) }),
|
|
1932
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 space-y-4", children: [
|
|
1933
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-1/2" }),
|
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-full" }),
|
|
1935
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-3/4" }),
|
|
1936
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 space-y-6", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1937
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-6 w-1/3" }),
|
|
1938
|
+
/* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-20 w-full" })
|
|
1939
|
+
] }, i)) })
|
|
1940
|
+
] })
|
|
1941
|
+
]
|
|
1942
|
+
}
|
|
1943
|
+
);
|
|
1944
|
+
}
|
|
1945
|
+
if (error) {
|
|
1946
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1947
|
+
"div",
|
|
1948
|
+
{
|
|
1949
|
+
className: "flex items-center justify-center p-8",
|
|
1950
|
+
style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
|
|
1951
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-destructive", children: [
|
|
1952
|
+
"Failed to load schema: ",
|
|
1953
|
+
error
|
|
1954
|
+
] })
|
|
1955
|
+
}
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
if (isMobile) {
|
|
1959
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1960
|
+
"div",
|
|
1961
|
+
{
|
|
1962
|
+
className: "flex flex-col overflow-hidden",
|
|
1963
|
+
style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
|
|
1964
|
+
children: [
|
|
1965
|
+
/* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
|
|
1966
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1967
|
+
DocsView,
|
|
1968
|
+
{
|
|
1969
|
+
ref: docsRef,
|
|
1970
|
+
info: schemaInfo,
|
|
1971
|
+
rawSchema,
|
|
1972
|
+
resolvedBaseUrl,
|
|
1973
|
+
endpoints,
|
|
1974
|
+
selectedVersion: state.selectedVersion,
|
|
1975
|
+
loadedEndpoint: state.selectedEndpoint,
|
|
1976
|
+
onTryEndpoint: handleTry,
|
|
1977
|
+
onActiveChange: setActiveAnchor
|
|
1978
|
+
}
|
|
1979
|
+
),
|
|
1980
|
+
/* @__PURE__ */ jsxRuntime.jsx(TryItSheet, { open: sheetOpen, onOpenChange: setSheetOpen })
|
|
1981
|
+
]
|
|
1982
|
+
}
|
|
1983
|
+
);
|
|
1984
|
+
}
|
|
1985
|
+
return /* @__PURE__ */ jsxRuntime.jsx(components.TooltipProvider, { delayDuration: 350, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1986
|
+
"div",
|
|
1987
|
+
{
|
|
1988
|
+
className: "grid grid-cols-[260px_minmax(0,1fr)] min-h-0 overflow-hidden",
|
|
1989
|
+
style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
|
|
1990
|
+
children: [
|
|
1991
|
+
/* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
|
|
1992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1993
|
+
DocsSidebar,
|
|
1994
|
+
{
|
|
1995
|
+
info: schemaInfo,
|
|
1996
|
+
endpoints,
|
|
1997
|
+
schemas,
|
|
1998
|
+
currentSchemaId: currentSchema?.id ?? null,
|
|
1999
|
+
onSchemaChange: setCurrentSchema,
|
|
2000
|
+
activeEndpointId: activeAnchor,
|
|
2001
|
+
selectedVersion: state.selectedVersion,
|
|
2002
|
+
onNavigate: handleNavigate
|
|
2003
|
+
}
|
|
2004
|
+
),
|
|
2005
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2006
|
+
DocsView,
|
|
2007
|
+
{
|
|
2008
|
+
ref: docsRef,
|
|
2009
|
+
info: schemaInfo,
|
|
2010
|
+
rawSchema,
|
|
2011
|
+
resolvedBaseUrl,
|
|
2012
|
+
endpoints,
|
|
2013
|
+
selectedVersion: state.selectedVersion,
|
|
2014
|
+
loadedEndpoint: state.selectedEndpoint,
|
|
2015
|
+
onTryEndpoint: handleTry,
|
|
2016
|
+
onActiveChange: setActiveAnchor
|
|
2017
|
+
}
|
|
2018
|
+
),
|
|
2019
|
+
/* @__PURE__ */ jsxRuntime.jsx(SlideInPlayground, { open: slideOpen, onClose: handleCloseSlide })
|
|
2020
|
+
]
|
|
2021
|
+
}
|
|
2022
|
+
) });
|
|
2023
|
+
}, "DocsLayout");
|
|
2024
|
+
|
|
2025
|
+
exports.DocsLayout = DocsLayout;
|
|
2026
|
+
//# sourceMappingURL=DocsLayout-BCVU6TTX.cjs.map
|
|
2027
|
+
//# sourceMappingURL=DocsLayout-BCVU6TTX.cjs.map
|