@djangocfg/ui-tools 2.1.196 → 2.1.197

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGX62WYEV_cjs = require('./chunk-GX62WYEV.cjs');
3
+ var chunkQP6QAK3F_cjs = require('./chunk-QP6QAK3F.cjs');
4
4
  var chunkDFWXRCIC_cjs = require('./chunk-DFWXRCIC.cjs');
5
5
  var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
6
6
  var lucideReact = require('lucide-react');
@@ -22,19 +22,21 @@ var useMobile = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
22
22
  isDesktop: !isMobile
23
23
  };
24
24
  }, "useMobile");
25
+ var HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
25
26
  var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema) => {
26
- const endpointMap = /* @__PURE__ */ new Map();
27
+ const endpoints = [];
27
28
  if (!schema.paths) return [];
28
29
  const baseUrl = schema.servers && schema.servers.length > 0 ? schema.servers[0].url : "";
29
30
  for (const [path, methods] of Object.entries(schema.paths)) {
30
- const getOperation = methods.get;
31
- if (!getOperation) continue;
32
- const op = getOperation;
33
- const description = op.description || op.summary || `GET ${path}`;
34
- const category = op.tags?.[0] || "Other";
35
- const parameters = [];
36
- if (op.parameters) {
37
- for (const param of op.parameters) {
31
+ for (const method of HTTP_METHODS) {
32
+ const op = methods[method];
33
+ if (!op) continue;
34
+ const methodUpper = method.toUpperCase();
35
+ const description = op.description || op.summary || `${methodUpper} ${path}`;
36
+ const category = op.tags?.[0] || "Other";
37
+ const parameters = [];
38
+ const allParams = [...methods.parameters || [], ...op.parameters || []];
39
+ for (const param of allParams) {
38
40
  parameters.push({
39
41
  name: param.name,
40
42
  type: param.schema?.type || "string",
@@ -42,31 +44,38 @@ var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema) => {
42
44
  description: param.description
43
45
  });
44
46
  }
45
- }
46
- const responses = [];
47
- if (op.responses) {
48
- for (const [code, response] of Object.entries(op.responses)) {
49
- responses.push({
50
- code,
51
- description: response.description || `Response ${code}`
52
- });
47
+ const responses = [];
48
+ if (op.responses) {
49
+ for (const [code, response] of Object.entries(op.responses)) {
50
+ responses.push({
51
+ code,
52
+ description: response.description || `Response ${code}`
53
+ });
54
+ }
53
55
  }
56
+ let requestBody;
57
+ if (op.requestBody) {
58
+ const content = op.requestBody.content;
59
+ const mediaType = content?.["application/json"] || content?.[Object.keys(content || {})[0]];
60
+ requestBody = {
61
+ type: mediaType?.schema?.type || "object",
62
+ description: op.requestBody.description
63
+ };
64
+ }
65
+ const endpoint = {
66
+ name: path.split("/").pop() || path,
67
+ method: methodUpper,
68
+ path: baseUrl + path,
69
+ description,
70
+ category,
71
+ parameters: parameters.length > 0 ? parameters : void 0,
72
+ requestBody,
73
+ responses: responses.length > 0 ? responses : void 0
74
+ };
75
+ endpoints.push(endpoint);
54
76
  }
55
- const endpoint = {
56
- name: path.split("/").pop() || path,
57
- method: "GET",
58
- path: baseUrl + path,
59
- // Combine baseUrl with path
60
- description,
61
- category,
62
- parameters: parameters.length > 0 ? parameters : void 0,
63
- requestBody: void 0,
64
- // GET requests don't have request body
65
- responses: responses.length > 0 ? responses : void 0
66
- };
67
- endpointMap.set(path, endpoint);
68
77
  }
69
- return Array.from(endpointMap.values());
78
+ return endpoints;
70
79
  }, "extractEndpoints");
71
80
  var getCategories = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((endpoints) => {
72
81
  const categories = /* @__PURE__ */ new Set();
@@ -161,53 +170,16 @@ function useOpenApiSchema({
161
170
  };
162
171
  }
163
172
  chunkWGEGR3DF_cjs.__name(useOpenApiSchema, "useOpenApiSchema");
164
- var VersionSelector = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
165
- const { state, config, setSelectedVersion } = chunkGX62WYEV_cjs.usePlaygroundContext();
166
- const { endpoints } = useOpenApiSchema({
167
- schemas: config.schemas,
168
- defaultSchemaId: config.defaultSchemaId
169
- });
170
- const currentVersion = chunkGX62WYEV_cjs.getVersionById(state.selectedVersion);
171
- const versionStats = chunkGX62WYEV_cjs.getVersionStats(endpoints);
172
- const handleVersionChange = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((versionId) => {
173
- setSelectedVersion(versionId);
174
- }, "handleVersionChange");
175
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3", children: [
176
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
177
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranch, { className: "h-4 w-4 text-muted-foreground" }),
178
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground", children: "API Version:" })
179
- ] }),
180
- /* @__PURE__ */ jsxRuntime.jsxs(components.Select, { value: state.selectedVersion, onValueChange: handleVersionChange, children: [
181
- /* @__PURE__ */ jsxRuntime.jsx(components.SelectTrigger, { className: "w-48", children: /* @__PURE__ */ jsxRuntime.jsx(components.SelectValue, {}) }),
182
- /* @__PURE__ */ jsxRuntime.jsx(components.SelectContent, { children: chunkGX62WYEV_cjs.API_VERSIONS.map((version) => /* @__PURE__ */ jsxRuntime.jsx(components.SelectItem, { value: version.id, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full", children: [
183
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
184
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: version.name }),
185
- version.isDefault && /* @__PURE__ */ jsxRuntime.jsx(components.Badge, { variant: "secondary", className: "text-xs", children: "Default" })
186
- ] }),
187
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-2", children: [
188
- versionStats[version.id] || 0,
189
- " endpoints"
190
- ] })
191
- ] }) }, version.id)) })
192
- ] }),
193
- currentVersion && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1 text-xs text-muted-foreground", children: [
194
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "h-3 w-3" }),
195
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: currentVersion.description })
196
- ] })
197
- ] });
198
- }, "VersionSelector");
199
- var categoryIcons = {
200
- "Authentication": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Shield, { className: "h-4 w-4" }),
201
- "Users": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Users, { className: "h-4 w-4" }),
202
- "Data": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Database, { className: "h-4 w-4" }),
203
- "Analytics": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "h-4 w-4" }),
204
- "Files": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "h-4 w-4" }),
205
- "Settings": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "h-4 w-4" }),
206
- "Other": /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { className: "h-4 w-4" })
173
+ var METHOD_BADGE_VARIANTS = {
174
+ GET: "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/20",
175
+ POST: "bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/20",
176
+ PUT: "bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/20",
177
+ PATCH: "bg-orange-500/15 text-orange-600 dark:text-orange-400 border-orange-500/20",
178
+ DELETE: "bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/20"
207
179
  };
208
180
  var EndpointsLibrary = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
209
- const { state, config, setSelectedEndpoint, setSelectedCategory, setSearchTerm } = chunkGX62WYEV_cjs.usePlaygroundContext();
210
- const { endpoints, categories, loading, error } = useOpenApiSchema({
181
+ const { state, config, setSelectedEndpoint, setSelectedCategory, setSearchTerm } = chunkQP6QAK3F_cjs.usePlaygroundContext();
182
+ const { endpoints, categories, loading, error, schemas, currentSchema, setCurrentSchema } = useOpenApiSchema({
211
183
  schemas: config.schemas,
212
184
  defaultSchemaId: config.defaultSchemaId
213
185
  });
@@ -221,7 +193,7 @@ var EndpointsLibrary = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
221
193
  }
222
194
  }, "getRelativePath");
223
195
  const filteredEndpoints = React.useMemo(() => {
224
- let filtered = chunkGX62WYEV_cjs.deduplicateEndpoints(endpoints, state.selectedVersion);
196
+ let filtered = chunkQP6QAK3F_cjs.deduplicateEndpoints(endpoints, state.selectedVersion);
225
197
  if (state.selectedCategory && state.selectedCategory !== "All") {
226
198
  filtered = filtered.filter((endpoint) => endpoint.category === state.selectedCategory);
227
199
  }
@@ -233,122 +205,142 @@ var EndpointsLibrary = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
233
205
  }
234
206
  return filtered;
235
207
  }, [endpoints, state.selectedCategory, state.searchTerm, state.selectedVersion]);
236
- const handleEndpointSelect = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((endpoint) => {
237
- setSelectedEndpoint(endpoint);
238
- }, "handleEndpointSelect");
239
- const getMethodBadges = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((methods) => {
240
- return methods.split(", ").map((method) => /* @__PURE__ */ jsxRuntime.jsx(components.Badge, { variant: chunkGX62WYEV_cjs.getMethodColor(method) === "success" ? "default" : "secondary", className: "text-xs", children: method }, method));
241
- }, "getMethodBadges");
208
+ const schemaOptions = React.useMemo(
209
+ () => schemas.map((s) => ({ value: s.id, label: s.name })),
210
+ [schemas]
211
+ );
212
+ const getMethodBadge = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((method) => /* @__PURE__ */ jsxRuntime.jsx(
213
+ components.Badge,
214
+ {
215
+ variant: "outline",
216
+ className: `text-xs font-mono font-semibold ${METHOD_BADGE_VARIANTS[method.toUpperCase()] || ""}`,
217
+ children: method
218
+ },
219
+ method
220
+ ), "getMethodBadge");
242
221
  if (loading) {
243
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
244
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
245
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: "API Endpoints" }),
246
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
247
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-32" }),
248
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-48" })
249
- ] })
222
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
223
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
224
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-9 w-44" }),
225
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-9 flex-1 max-w-xs" }),
226
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
227
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-9 w-24" })
250
228
  ] }),
251
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-20 w-full" }, i)) })
229
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-12 w-full" }, i)) })
252
230
  ] });
253
231
  }
254
232
  if (error) {
255
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
256
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: "API Endpoints" }) }),
257
- /* @__PURE__ */ jsxRuntime.jsx(components.Card, { className: "bg-destructive/10 border-destructive/20", children: /* @__PURE__ */ jsxRuntime.jsx(components.CardContent, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-destructive", children: [
258
- "Error loading endpoints: ",
259
- error
260
- ] }) }) })
261
- ] });
233
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntime.jsx(components.Card, { className: "bg-destructive/10 border-destructive/20", children: /* @__PURE__ */ jsxRuntime.jsx(components.CardContent, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-destructive", children: [
234
+ "Failed to load schema: ",
235
+ error
236
+ ] }) }) }) });
262
237
  }
263
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
264
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
265
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-4", children: [
266
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: "API Endpoints" }),
267
- /* @__PURE__ */ jsxRuntime.jsx(VersionSelector, {})
238
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
239
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
240
+ schemas.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
241
+ components.Combobox,
242
+ {
243
+ options: schemaOptions,
244
+ value: currentSchema?.id || "",
245
+ onValueChange: (id) => id && setCurrentSchema(id),
246
+ placeholder: "Select API",
247
+ searchPlaceholder: "Search APIs...",
248
+ emptyText: "No APIs found",
249
+ className: "w-44"
250
+ }
251
+ ),
252
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-xs", children: [
253
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
254
+ /* @__PURE__ */ jsxRuntime.jsx(
255
+ components.Input,
256
+ {
257
+ placeholder: "Search...",
258
+ value: state.searchTerm,
259
+ onChange: (e) => setSearchTerm(e.target.value),
260
+ className: "h-9 pl-8 text-sm"
261
+ }
262
+ )
268
263
  ] }),
269
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
270
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border rounded-md", children: [
271
- /* @__PURE__ */ jsxRuntime.jsx(
272
- components.Button,
273
- {
274
- variant: viewMode === "table" ? "default" : "ghost",
275
- size: "sm",
276
- onClick: () => setViewMode("table"),
277
- className: "rounded-r-none",
278
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "h-4 w-4" })
279
- }
280
- ),
281
- /* @__PURE__ */ jsxRuntime.jsx(
282
- components.Button,
283
- {
284
- variant: viewMode === "grid" ? "default" : "ghost",
285
- size: "sm",
286
- onClick: () => setViewMode("grid"),
287
- className: "rounded-l-none",
288
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: "h-4 w-4" })
289
- }
290
- )
264
+ /* @__PURE__ */ jsxRuntime.jsxs(components.Select, { value: state.selectedCategory, onValueChange: setSelectedCategory, children: [
265
+ /* @__PURE__ */ jsxRuntime.jsxs(components.SelectTrigger, { className: "w-auto h-9 gap-1.5", children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-3.5 w-3.5" }),
267
+ /* @__PURE__ */ jsxRuntime.jsx(components.SelectValue, {})
291
268
  ] }),
292
- /* @__PURE__ */ jsxRuntime.jsxs(components.Select, { value: state.selectedCategory, onValueChange: setSelectedCategory, children: [
293
- /* @__PURE__ */ jsxRuntime.jsxs(components.SelectTrigger, { className: "w-32", children: [
294
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-4 w-4 mr-2" }),
295
- /* @__PURE__ */ jsxRuntime.jsx(components.SelectValue, {})
296
- ] }),
297
- /* @__PURE__ */ jsxRuntime.jsxs(components.SelectContent, { children: [
298
- /* @__PURE__ */ jsxRuntime.jsx(components.SelectItem, { value: "All", children: "All" }),
299
- categories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(components.SelectItem, { value: category, children: category }, category))
300
- ] })
301
- ] }),
302
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
303
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
304
- /* @__PURE__ */ jsxRuntime.jsx(
305
- components.Input,
306
- {
307
- placeholder: "Search endpoints...",
308
- value: state.searchTerm,
309
- onChange: (e) => setSearchTerm(e.target.value),
310
- className: "w-48 pl-8"
311
- }
312
- )
269
+ /* @__PURE__ */ jsxRuntime.jsxs(components.SelectContent, { children: [
270
+ /* @__PURE__ */ jsxRuntime.jsx(components.SelectItem, { value: "All", children: "All" }),
271
+ categories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(components.SelectItem, { value: category, children: category }, category))
313
272
  ] })
314
- ] }) })
273
+ ] }),
274
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
275
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground tabular-nums hidden sm:inline", children: [
276
+ filteredEndpoints.length,
277
+ " endpoint",
278
+ filteredEndpoints.length !== 1 ? "s" : ""
279
+ ] }),
280
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border rounded-md", children: [
281
+ /* @__PURE__ */ jsxRuntime.jsx(
282
+ components.Button,
283
+ {
284
+ variant: viewMode === "table" ? "default" : "ghost",
285
+ size: "icon",
286
+ className: "h-8 w-8 rounded-r-none",
287
+ onClick: () => setViewMode("table"),
288
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "h-3.5 w-3.5" })
289
+ }
290
+ ),
291
+ /* @__PURE__ */ jsxRuntime.jsx(
292
+ components.Button,
293
+ {
294
+ variant: viewMode === "grid" ? "default" : "ghost",
295
+ size: "icon",
296
+ className: "h-8 w-8 rounded-l-none",
297
+ onClick: () => setViewMode("grid"),
298
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: "h-3.5 w-3.5" })
299
+ }
300
+ )
301
+ ] }),
302
+ currentSchema && /* @__PURE__ */ jsxRuntime.jsx(
303
+ components.DownloadButton,
304
+ {
305
+ url: currentSchema.url,
306
+ filename: `${currentSchema.id}-openapi.json`,
307
+ variant: "outline",
308
+ size: "sm",
309
+ className: "h-8",
310
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Schema" })
311
+ }
312
+ )
315
313
  ] }),
316
314
  viewMode === "table" ? /* @__PURE__ */ jsxRuntime.jsx(components.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(components.Table, { children: [
317
315
  /* @__PURE__ */ jsxRuntime.jsx(components.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(components.TableRow, { children: [
318
- /* @__PURE__ */ jsxRuntime.jsx(components.TableHead, { className: "text-foreground", children: "Methods" }),
316
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableHead, { className: "w-20 text-foreground", children: "Method" }),
319
317
  /* @__PURE__ */ jsxRuntime.jsx(components.TableHead, { className: "text-foreground", children: "Path" }),
320
- /* @__PURE__ */ jsxRuntime.jsx(components.TableHead, { className: "text-foreground", children: "Description" })
318
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableHead, { className: "text-foreground hidden lg:table-cell", children: "Description" })
321
319
  ] }) }),
322
- /* @__PURE__ */ jsxRuntime.jsx(components.TableBody, { children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(components.TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { colSpan: 3, className: "text-center py-8 text-muted-foreground", children: "No endpoints found" }) }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxRuntime.jsxs(
320
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableBody, { children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(components.TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { colSpan: 3, className: "text-center py-12 text-muted-foreground", children: "No endpoints found" }) }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxRuntime.jsxs(
323
321
  components.TableRow,
324
322
  {
325
- className: `cursor-pointer transition-colors hover:bg-muted/50 ${state.selectedEndpoint?.path === endpoint.path ? "bg-primary/10" : ""}`,
326
- onClick: () => handleEndpointSelect(endpoint),
323
+ className: `cursor-pointer transition-colors hover:bg-muted/50 ${state.selectedEndpoint?.path === endpoint.path && state.selectedEndpoint?.method === endpoint.method ? "bg-primary/5" : ""}`,
324
+ onClick: () => setSelectedEndpoint(endpoint),
327
325
  children: [
328
- /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex space-x-1", children: getMethodBadges(endpoint.method) }) }),
329
- /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { className: "font-mono text-sm text-muted-foreground", children: getRelativePath(endpoint.path) }),
330
- /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { className: "text-sm text-muted-foreground max-w-xs truncate", children: endpoint.description })
326
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { className: "py-2.5", children: getMethodBadge(endpoint.method) }),
327
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { className: "font-mono text-sm text-muted-foreground py-2.5", children: getRelativePath(endpoint.path) }),
328
+ /* @__PURE__ */ jsxRuntime.jsx(components.TableCell, { className: "text-sm text-muted-foreground max-w-sm truncate py-2.5 hidden lg:table-cell", children: endpoint.description })
331
329
  ]
332
330
  },
333
331
  `${endpoint.method}-${endpoint.path}`
334
332
  )) })
335
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-full text-center py-8 text-muted-foreground", children: "No endpoints found" }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxRuntime.jsxs(
333
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3", children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-full text-center py-12 text-muted-foreground", children: "No endpoints found" }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxRuntime.jsxs(
336
334
  components.Card,
337
335
  {
338
- className: `cursor-pointer transition-all hover:shadow-md ${state.selectedEndpoint?.path === endpoint.path ? "ring-2 ring-primary" : ""}`,
339
- onClick: () => handleEndpointSelect(endpoint),
336
+ className: `cursor-pointer transition-all hover:shadow-md ${state.selectedEndpoint?.path === endpoint.path && state.selectedEndpoint?.method === endpoint.method ? "ring-2 ring-primary" : ""}`,
337
+ onClick: () => setSelectedEndpoint(endpoint),
340
338
  children: [
341
- /* @__PURE__ */ jsxRuntime.jsx(components.CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(components.CardTitle, { className: "flex items-center justify-between text-sm", children: [
342
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
343
- categoryIcons[endpoint.category] || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { className: "h-4 w-4" }),
344
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: endpoint.name })
345
- ] }),
346
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex space-x-1", children: getMethodBadges(endpoint.method) })
339
+ /* @__PURE__ */ jsxRuntime.jsx(components.CardHeader, { className: "pb-2 pt-3 px-4", children: /* @__PURE__ */ jsxRuntime.jsxs(components.CardTitle, { className: "flex items-center justify-between text-sm", children: [
340
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-xs text-muted-foreground truncate", children: getRelativePath(endpoint.path) }),
341
+ getMethodBadge(endpoint.method)
347
342
  ] }) }),
348
- /* @__PURE__ */ jsxRuntime.jsxs(components.CardContent, { className: "space-y-2", children: [
349
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-mono text-muted-foreground break-all", children: getRelativePath(endpoint.path) }),
350
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: endpoint.description })
351
- ] })
343
+ /* @__PURE__ */ jsxRuntime.jsx(components.CardContent, { className: "px-4 pb-3 pt-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: endpoint.description }) })
352
344
  ]
353
345
  },
354
346
  `${endpoint.method}-${endpoint.path}`
@@ -373,12 +365,12 @@ var stepConfig = {
373
365
  }
374
366
  };
375
367
  var PlaygroundStepper = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
376
- const { state, setCurrentStep, goToNextStep, goToPreviousStep } = chunkGX62WYEV_cjs.usePlaygroundContext();
368
+ const { state, setCurrentStep, goToNextStep, goToPreviousStep } = chunkQP6QAK3F_cjs.usePlaygroundContext();
377
369
  const { currentStep, steps } = state;
378
370
  const currentIndex = steps.indexOf(currentStep);
379
371
  const canGoNext = currentIndex < steps.length - 1;
380
372
  const canGoPrevious = currentIndex > 0;
381
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full", children: [
382
374
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-4", children: steps.map((step, index) => {
383
375
  const config = stepConfig[step];
384
376
  const Icon = config.icon;
@@ -436,7 +428,7 @@ var PlaygroundStepper = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
436
428
  ] });
437
429
  }, "PlaygroundStepper");
438
430
  var EndpointInfo = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
439
- const { state } = chunkGX62WYEV_cjs.usePlaygroundContext();
431
+ const { state } = chunkQP6QAK3F_cjs.usePlaygroundContext();
440
432
  const { selectedEndpoint } = state;
441
433
  const endpointJson = React.useMemo(() => {
442
434
  if (!selectedEndpoint) return "";
@@ -454,7 +446,7 @@ var EndpointInfo = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
454
446
  return null;
455
447
  }
456
448
  const getMethodBadges = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((methods) => {
457
- return methods.split(", ").map((method) => /* @__PURE__ */ jsxRuntime.jsx(components.Badge, { variant: chunkGX62WYEV_cjs.getMethodColor(method) === "success" ? "default" : "secondary", className: "text-xs", children: method }, method));
449
+ return methods.split(", ").map((method) => /* @__PURE__ */ jsxRuntime.jsx(components.Badge, { variant: chunkQP6QAK3F_cjs.getMethodColor(method) === "success" ? "default" : "secondary", className: "text-xs", children: method }, method));
458
450
  }, "getMethodBadges");
459
451
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
460
452
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
@@ -522,7 +514,7 @@ var EndpointInfo = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
522
514
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4" })
523
515
  ] }),
524
516
  /* @__PURE__ */ jsxRuntime.jsx(components.CollapsibleContent, { className: "mt-2 space-y-2", children: selectedEndpoint.responses.map((response, index) => {
525
- const statusColor = chunkGX62WYEV_cjs.getStatusColor(parseInt(response.code));
517
+ const statusColor = chunkQP6QAK3F_cjs.getStatusColor(parseInt(response.code));
526
518
  const badgeVariant = statusColor === "success" ? "default" : statusColor === "error" ? "destructive" : "secondary";
527
519
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2 text-xs", children: [
528
520
  /* @__PURE__ */ jsxRuntime.jsx(components.Badge, { variant: badgeVariant, className: "text-xs", children: response.code }),
@@ -535,7 +527,7 @@ var EndpointInfo = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
535
527
  ] });
536
528
  }, "EndpointInfo");
537
529
  var RequestParametersForm = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
538
- const { state, setParameters } = chunkGX62WYEV_cjs.usePlaygroundContext();
530
+ const { state, setParameters } = chunkQP6QAK3F_cjs.usePlaygroundContext();
539
531
  const [formData, setFormData] = React.useState({});
540
532
  const [activeTab, setActiveTab] = React.useState("required");
541
533
  React.useEffect(() => {
@@ -716,12 +708,12 @@ var RequestBuilder = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
716
708
  setRequestBody,
717
709
  setManualApiToken,
718
710
  sendRequest
719
- } = chunkGX62WYEV_cjs.usePlaygroundContext();
720
- const isJsonValid = state.requestBody ? chunkGX62WYEV_cjs.isValidJson(state.requestBody) : true;
711
+ } = chunkQP6QAK3F_cjs.usePlaygroundContext();
712
+ const isJsonValid = state.requestBody ? chunkQP6QAK3F_cjs.isValidJson(state.requestBody) : true;
721
713
  const generateCurlCommand = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
722
714
  if (!state.requestUrl) return "";
723
- const apiKey = state.selectedApiKey ? chunkGX62WYEV_cjs.findApiKeyById(apiKeys, state.selectedApiKey) : null;
724
- const headers = chunkGX62WYEV_cjs.parseRequestHeaders(state.requestHeaders);
715
+ const apiKey = state.selectedApiKey ? chunkQP6QAK3F_cjs.findApiKeyById(apiKeys, state.selectedApiKey) : null;
716
+ const headers = chunkQP6QAK3F_cjs.parseRequestHeaders(state.requestHeaders);
725
717
  if (apiKey) {
726
718
  headers["X-API-Key"] = apiKey.id || "";
727
719
  }
@@ -808,12 +800,12 @@ var RequestBuilder = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
808
800
  }
809
801
  )
810
802
  ] }) }),
811
- /* @__PURE__ */ jsxRuntime.jsx(components.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkGX62WYEV_cjs.PrettyCode_default, { data: curlCommand, language: "bash" }) })
803
+ /* @__PURE__ */ jsxRuntime.jsx(components.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkQP6QAK3F_cjs.PrettyCode_default, { data: curlCommand, language: "bash" }) })
812
804
  ] })
813
805
  ] });
814
806
  }, "RequestBuilder");
815
807
  var ResponseViewer = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
816
- const { state } = chunkGX62WYEV_cjs.usePlaygroundContext();
808
+ const { state } = chunkQP6QAK3F_cjs.usePlaygroundContext();
817
809
  const { response } = state;
818
810
  const responseText = React.useMemo(() => {
819
811
  if (!response?.data) return "";
@@ -858,7 +850,7 @@ var ResponseViewer = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
858
850
  /* @__PURE__ */ jsxRuntime.jsx(
859
851
  components.Badge,
860
852
  {
861
- variant: chunkGX62WYEV_cjs.getStatusColor(response.status || 0) === "success" ? "default" : chunkGX62WYEV_cjs.getStatusColor(response.status || 0) === "error" ? "destructive" : "secondary",
853
+ variant: chunkQP6QAK3F_cjs.getStatusColor(response.status || 0) === "success" ? "default" : chunkQP6QAK3F_cjs.getStatusColor(response.status || 0) === "error" ? "destructive" : "secondary",
862
854
  className: "text-xs",
863
855
  children: response.status
864
856
  }
@@ -923,7 +915,7 @@ var ResponseViewer = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
923
915
  ] });
924
916
  }, "ResponseViewer");
925
917
  var PlaygroundLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
926
- const { state, setSidebarOpen } = chunkGX62WYEV_cjs.usePlaygroundContext();
918
+ const { state, setSidebarOpen } = chunkQP6QAK3F_cjs.usePlaygroundContext();
927
919
  const { isMobile } = useMobile();
928
920
  const renderStepContent = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
929
921
  switch (state.currentStep) {
@@ -937,26 +929,10 @@ var PlaygroundLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
937
929
  return /* @__PURE__ */ jsxRuntime.jsx(EndpointsLibrary, {});
938
930
  }
939
931
  }, "renderStepContent");
940
- const getStepTitle = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
941
- switch (state.currentStep) {
942
- case "endpoints":
943
- return "API Endpoints";
944
- case "request":
945
- return "Request Builder";
946
- case "response":
947
- return "Response Viewer";
948
- default:
949
- return "API Playground";
950
- }
951
- }, "getStepTitle");
952
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen", children: [
953
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
954
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-4", children: [
955
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold text-foreground", children: "API Playground" }),
956
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground hidden sm:block", children: "Test and explore API endpoints" })
957
- ] }),
958
- isMobile && /* @__PURE__ */ jsxRuntime.jsxs(components.Sheet, { open: state.sidebarOpen, onOpenChange: setSidebarOpen, children: [
959
- /* @__PURE__ */ jsxRuntime.jsx(components.SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(components.Button, { variant: "outline", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "h-4 w-4" }) }) }),
932
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
933
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-6 py-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: isMobile ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
934
+ /* @__PURE__ */ jsxRuntime.jsxs(components.Sheet, { open: state.sidebarOpen, onOpenChange: setSidebarOpen, children: [
935
+ /* @__PURE__ */ jsxRuntime.jsx(components.SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(components.Button, { variant: "ghost", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "h-4 w-4" }) }) }),
960
936
  /* @__PURE__ */ jsxRuntime.jsx(components.SheetContent, { side: "left", className: "w-80", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
961
937
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
962
938
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Navigation" }),
@@ -972,27 +948,17 @@ var PlaygroundLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
972
948
  ] }),
973
949
  /* @__PURE__ */ jsxRuntime.jsx(PlaygroundStepper, {})
974
950
  ] }) })
975
- ] })
976
- ] }) }) }),
977
- !isMobile && /* @__PURE__ */ jsxRuntime.jsx(PlaygroundStepper, {}),
978
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "container mx-auto px-6 py-6", children: [
979
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
980
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-foreground", children: getStepTitle() }),
981
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground mt-1", children: [
982
- state.currentStep === "endpoints" && "Browse and select API endpoints",
983
- state.currentStep === "request" && "Configure your API request",
984
- state.currentStep === "response" && "View API response and details"
985
- ] })
986
951
  ] }),
987
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: renderStepContent() })
988
- ] }),
952
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground capitalize", children: state.currentStep }),
953
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8" }),
954
+ " "
955
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(PlaygroundStepper, {}) }) }) }),
956
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-6 py-6", children: renderStepContent() }),
989
957
  isMobile && state.currentStep === "request" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-4 right-4 z-50", children: /* @__PURE__ */ jsxRuntime.jsx(
990
958
  components.Button,
991
959
  {
992
960
  size: "lg",
993
961
  className: "rounded-full shadow-lg",
994
- onClick: () => {
995
- },
996
962
  children: "Send Request"
997
963
  }
998
964
  ) })
@@ -1000,5 +966,5 @@ var PlaygroundLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1000
966
  }, "PlaygroundLayout");
1001
967
 
1002
968
  exports.PlaygroundLayout = PlaygroundLayout;
1003
- //# sourceMappingURL=PlaygroundLayout-LICYATAF.cjs.map
1004
- //# sourceMappingURL=PlaygroundLayout-LICYATAF.cjs.map
969
+ //# sourceMappingURL=PlaygroundLayout-XYMJBNT4.cjs.map
970
+ //# sourceMappingURL=PlaygroundLayout-XYMJBNT4.cjs.map