@djangocfg/ui-tools 2.1.389 → 2.1.393

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.
Files changed (183) hide show
  1. package/README.md +7 -10
  2. package/dist/chunk-PAWJFY3S.mjs +6 -0
  3. package/dist/{chunk-N2XQF2OL.mjs.map → chunk-PAWJFY3S.mjs.map} +1 -1
  4. package/dist/chunk-PK6SKIKE.cjs +8 -0
  5. package/dist/{chunk-OLISEQHS.cjs.map → chunk-PK6SKIKE.cjs.map} +1 -1
  6. package/dist/file-icon/index.cjs +6 -6
  7. package/dist/file-icon/index.d.cts +1 -1
  8. package/dist/file-icon/index.d.ts +1 -1
  9. package/dist/file-icon/index.mjs +1 -1
  10. package/dist/tree/index.cjs +1372 -143
  11. package/dist/tree/index.cjs.map +1 -1
  12. package/dist/tree/index.d.cts +2 -2
  13. package/dist/tree/index.d.ts +2 -2
  14. package/dist/tree/index.mjs +1322 -3
  15. package/dist/tree/index.mjs.map +1 -1
  16. package/dist/{types-CevSbyfD.d.cts → types-B_zhyAqR.d.cts} +1 -1
  17. package/dist/{types-CevSbyfD.d.ts → types-B_zhyAqR.d.ts} +1 -1
  18. package/package.json +9 -17
  19. package/src/tools/AudioPlayer/README.md +4 -4
  20. package/src/tools/Chat/README.md +6 -6
  21. package/src/tools/CronScheduler/index.tsx +1 -1
  22. package/src/tools/CronScheduler/lazy.tsx +1 -1
  23. package/src/tools/ImageViewer/README.md +1 -1
  24. package/src/tools/JsonForm/README.md +2 -2
  25. package/src/tools/MarkdownEditor/README.md +3 -3
  26. package/src/tools/MarkdownMessage/README.md +2 -2
  27. package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +5 -1
  28. package/src/tools/SpeechRecognition/README.md +1 -1
  29. package/dist/ChatRoot-EFNXQXXN.cjs +0 -15
  30. package/dist/ChatRoot-EFNXQXXN.cjs.map +0 -1
  31. package/dist/ChatRoot-FITF5RVP.mjs +0 -6
  32. package/dist/ChatRoot-FITF5RVP.mjs.map +0 -1
  33. package/dist/ChatRoot-PNNGQCYF.css +0 -7
  34. package/dist/ChatRoot-PNNGQCYF.css.map +0 -1
  35. package/dist/CronScheduler.client-DLMXCPAJ.mjs +0 -67
  36. package/dist/CronScheduler.client-DLMXCPAJ.mjs.map +0 -1
  37. package/dist/CronScheduler.client-WEJF4PWQ.cjs +0 -72
  38. package/dist/CronScheduler.client-WEJF4PWQ.cjs.map +0 -1
  39. package/dist/DictationField-AS2F33WI.cjs +0 -13
  40. package/dist/DictationField-AS2F33WI.cjs.map +0 -1
  41. package/dist/DictationField-WPONUCYE.mjs +0 -4
  42. package/dist/DictationField-WPONUCYE.mjs.map +0 -1
  43. package/dist/DocsLayout-EKASBSP7.mjs +0 -3448
  44. package/dist/DocsLayout-EKASBSP7.mjs.map +0 -1
  45. package/dist/DocsLayout-MBFIB4NO.css +0 -7
  46. package/dist/DocsLayout-MBFIB4NO.css.map +0 -1
  47. package/dist/DocsLayout-OURFYWQE.cjs +0 -3455
  48. package/dist/DocsLayout-OURFYWQE.cjs.map +0 -1
  49. package/dist/JsonSchemaForm-DD7CLRIG.cjs +0 -13
  50. package/dist/JsonSchemaForm-DD7CLRIG.cjs.map +0 -1
  51. package/dist/JsonSchemaForm-XKUIVELK.mjs +0 -4
  52. package/dist/JsonSchemaForm-XKUIVELK.mjs.map +0 -1
  53. package/dist/JsonTree-43PQAJKY.mjs +0 -5
  54. package/dist/JsonTree-43PQAJKY.mjs.map +0 -1
  55. package/dist/JsonTree-MLET23ZA.css +0 -7
  56. package/dist/JsonTree-MLET23ZA.css.map +0 -1
  57. package/dist/JsonTree-X6W5YEVY.cjs +0 -11
  58. package/dist/JsonTree-X6W5YEVY.cjs.map +0 -1
  59. package/dist/LottiePlayer.client-2S7ISJ2S.cjs +0 -168
  60. package/dist/LottiePlayer.client-2S7ISJ2S.cjs.map +0 -1
  61. package/dist/LottiePlayer.client-5LDSSJWS.mjs +0 -161
  62. package/dist/LottiePlayer.client-5LDSSJWS.mjs.map +0 -1
  63. package/dist/MapContainer-AKIPABJK.mjs +0 -4
  64. package/dist/MapContainer-AKIPABJK.mjs.map +0 -1
  65. package/dist/MapContainer-STVDMC36.cjs +0 -17
  66. package/dist/MapContainer-STVDMC36.cjs.map +0 -1
  67. package/dist/Mermaid.client-DDXWXZXY.css +0 -7
  68. package/dist/Mermaid.client-DDXWXZXY.css.map +0 -1
  69. package/dist/Mermaid.client-NL4SVR7F.mjs +0 -481
  70. package/dist/Mermaid.client-NL4SVR7F.mjs.map +0 -1
  71. package/dist/Mermaid.client-NNTI6DFX.cjs +0 -487
  72. package/dist/Mermaid.client-NNTI6DFX.cjs.map +0 -1
  73. package/dist/Player-BRV7XTWR.mjs +0 -4
  74. package/dist/Player-BRV7XTWR.mjs.map +0 -1
  75. package/dist/Player-PM7F7DD7.cjs +0 -13
  76. package/dist/Player-PM7F7DD7.cjs.map +0 -1
  77. package/dist/Player-ZGQKKOWI.css +0 -66
  78. package/dist/Player-ZGQKKOWI.css.map +0 -1
  79. package/dist/PrettyCode.client-GWFAIVFN.css +0 -7
  80. package/dist/PrettyCode.client-GWFAIVFN.css.map +0 -1
  81. package/dist/PrettyCode.client-KOHDVPPN.cjs +0 -285
  82. package/dist/PrettyCode.client-KOHDVPPN.cjs.map +0 -1
  83. package/dist/PrettyCode.client-ZGYGKE7G.mjs +0 -283
  84. package/dist/PrettyCode.client-ZGYGKE7G.mjs.map +0 -1
  85. package/dist/TreeRoot-5COOOSWG.mjs +0 -4
  86. package/dist/TreeRoot-5COOOSWG.mjs.map +0 -1
  87. package/dist/TreeRoot-AABP2J6Y.cjs +0 -19
  88. package/dist/TreeRoot-AABP2J6Y.cjs.map +0 -1
  89. package/dist/chunk-2NG4SXEP.mjs +0 -743
  90. package/dist/chunk-2NG4SXEP.mjs.map +0 -1
  91. package/dist/chunk-4LFB7I5K.cjs +0 -1387
  92. package/dist/chunk-4LFB7I5K.cjs.map +0 -1
  93. package/dist/chunk-5D2OCOPQ.cjs +0 -222
  94. package/dist/chunk-5D2OCOPQ.cjs.map +0 -1
  95. package/dist/chunk-5I5QNGUG.cjs +0 -611
  96. package/dist/chunk-5I5QNGUG.cjs.map +0 -1
  97. package/dist/chunk-6ZX2G25W.mjs +0 -1361
  98. package/dist/chunk-6ZX2G25W.mjs.map +0 -1
  99. package/dist/chunk-76NNDZH6.cjs +0 -1061
  100. package/dist/chunk-76NNDZH6.cjs.map +0 -1
  101. package/dist/chunk-7CWGZPO3.mjs +0 -214
  102. package/dist/chunk-7CWGZPO3.mjs.map +0 -1
  103. package/dist/chunk-7EYHNP3E.cjs +0 -965
  104. package/dist/chunk-7EYHNP3E.cjs.map +0 -1
  105. package/dist/chunk-7IYXZUJO.cjs +0 -769
  106. package/dist/chunk-7IYXZUJO.cjs.map +0 -1
  107. package/dist/chunk-ADEN3UA4.cjs +0 -892
  108. package/dist/chunk-ADEN3UA4.cjs.map +0 -1
  109. package/dist/chunk-B6IR5KSC.mjs +0 -59
  110. package/dist/chunk-B6IR5KSC.mjs.map +0 -1
  111. package/dist/chunk-C6GXVH5J.mjs +0 -338
  112. package/dist/chunk-C6GXVH5J.mjs.map +0 -1
  113. package/dist/chunk-DMX7W4XZ.mjs +0 -1113
  114. package/dist/chunk-DMX7W4XZ.mjs.map +0 -1
  115. package/dist/chunk-ECONRHIG.mjs +0 -212
  116. package/dist/chunk-ECONRHIG.mjs.map +0 -1
  117. package/dist/chunk-FEN5S772.cjs +0 -1227
  118. package/dist/chunk-FEN5S772.cjs.map +0 -1
  119. package/dist/chunk-FP2RLYQZ.cjs +0 -187
  120. package/dist/chunk-FP2RLYQZ.cjs.map +0 -1
  121. package/dist/chunk-FVVF7VCD.cjs +0 -1325
  122. package/dist/chunk-FVVF7VCD.cjs.map +0 -1
  123. package/dist/chunk-GYIO7W7M.mjs +0 -1197
  124. package/dist/chunk-GYIO7W7M.mjs.map +0 -1
  125. package/dist/chunk-KNDLV4PI.cjs +0 -1356
  126. package/dist/chunk-KNDLV4PI.cjs.map +0 -1
  127. package/dist/chunk-KNEQRUBA.mjs +0 -181
  128. package/dist/chunk-KNEQRUBA.mjs.map +0 -1
  129. package/dist/chunk-N2XQF2OL.mjs +0 -14
  130. package/dist/chunk-N4MZYNR4.mjs +0 -1342
  131. package/dist/chunk-N4MZYNR4.mjs.map +0 -1
  132. package/dist/chunk-NTVBIIUD.mjs +0 -1439
  133. package/dist/chunk-NTVBIIUD.mjs.map +0 -1
  134. package/dist/chunk-OBRSGM64.mjs +0 -607
  135. package/dist/chunk-OBRSGM64.mjs.map +0 -1
  136. package/dist/chunk-ODO4GMW7.mjs +0 -79
  137. package/dist/chunk-ODO4GMW7.mjs.map +0 -1
  138. package/dist/chunk-OLISEQHS.cjs +0 -18
  139. package/dist/chunk-PVAX67JG.mjs +0 -1041
  140. package/dist/chunk-PVAX67JG.mjs.map +0 -1
  141. package/dist/chunk-QJ6GTUCO.cjs +0 -81
  142. package/dist/chunk-QJ6GTUCO.cjs.map +0 -1
  143. package/dist/chunk-T3MWM23F.cjs +0 -214
  144. package/dist/chunk-T3MWM23F.cjs.map +0 -1
  145. package/dist/chunk-TBSHZO5R.cjs +0 -1134
  146. package/dist/chunk-TBSHZO5R.cjs.map +0 -1
  147. package/dist/chunk-UNCS5V5F.mjs +0 -887
  148. package/dist/chunk-UNCS5V5F.mjs.map +0 -1
  149. package/dist/chunk-VWQ5WOIL.mjs +0 -2059
  150. package/dist/chunk-VWQ5WOIL.mjs.map +0 -1
  151. package/dist/chunk-W75B7Y6C.cjs +0 -1478
  152. package/dist/chunk-W75B7Y6C.cjs.map +0 -1
  153. package/dist/chunk-Y6UTOBF6.mjs +0 -938
  154. package/dist/chunk-Y6UTOBF6.mjs.map +0 -1
  155. package/dist/chunk-YDPDTOSP.cjs +0 -2061
  156. package/dist/chunk-YDPDTOSP.cjs.map +0 -1
  157. package/dist/chunk-YW5IVWHQ.cjs +0 -346
  158. package/dist/chunk-YW5IVWHQ.cjs.map +0 -1
  159. package/dist/chunk-YXZ6GU7H.cjs +0 -63
  160. package/dist/chunk-YXZ6GU7H.cjs.map +0 -1
  161. package/dist/chunk-ZL7FH4NW.mjs +0 -1274
  162. package/dist/chunk-ZL7FH4NW.mjs.map +0 -1
  163. package/dist/components-EHOGXATG.cjs +0 -22
  164. package/dist/components-EHOGXATG.cjs.map +0 -1
  165. package/dist/components-MQ6DR7TX.cjs +0 -26
  166. package/dist/components-MQ6DR7TX.cjs.map +0 -1
  167. package/dist/components-XRX7QGLB.mjs +0 -5
  168. package/dist/components-XRX7QGLB.mjs.map +0 -1
  169. package/dist/components-YATKRWLH.mjs +0 -5
  170. package/dist/components-YATKRWLH.mjs.map +0 -1
  171. package/dist/index.cjs +0 -3674
  172. package/dist/index.cjs.map +0 -1
  173. package/dist/index.css +0 -234
  174. package/dist/index.css.map +0 -1
  175. package/dist/index.d.cts +0 -4929
  176. package/dist/index.d.ts +0 -4929
  177. package/dist/index.mjs +0 -2912
  178. package/dist/index.mjs.map +0 -1
  179. package/dist/launcher-5Y42OBSN.mjs +0 -6
  180. package/dist/launcher-5Y42OBSN.mjs.map +0 -1
  181. package/dist/launcher-PMW2YB24.cjs +0 -59
  182. package/dist/launcher-PMW2YB24.cjs.map +0 -1
  183. package/src/index.ts +0 -157
@@ -1,3455 +0,0 @@
1
- 'use strict';
2
-
3
- var chunk7EYHNP3E_cjs = require('./chunk-7EYHNP3E.cjs');
4
- var chunk7IYXZUJO_cjs = require('./chunk-7IYXZUJO.cjs');
5
- var chunkT3MWM23F_cjs = require('./chunk-T3MWM23F.cjs');
6
- require('./chunk-FP2RLYQZ.cjs');
7
- var chunkOLISEQHS_cjs = require('./chunk-OLISEQHS.cjs');
8
- var React12 = require('react');
9
- var lodashEs = require('lodash-es');
10
- var components = require('@djangocfg/ui-core/components');
11
- var hooks = require('@djangocfg/ui-core/hooks');
12
- var consola = require('consola');
13
- var lucideReact = require('lucide-react');
14
- var lib = require('@djangocfg/ui-core/lib');
15
- var jsxRuntime = require('react/jsx-runtime');
16
- var zustand = require('zustand');
17
- var middleware = require('zustand/middleware');
18
-
19
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
-
21
- var React12__default = /*#__PURE__*/_interopDefault(React12);
22
- var consola__default = /*#__PURE__*/_interopDefault(consola);
23
-
24
- var HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
25
- var extractEndpoints = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((schema, baseUrl, schemaId, specRoot) => {
26
- const endpoints = [];
27
- if (!schema.paths) return [];
28
- for (const [path, methods] of Object.entries(schema.paths)) {
29
- for (const method of HTTP_METHODS) {
30
- const op = methods[method];
31
- if (!op) continue;
32
- const methodUpper = method.toUpperCase();
33
- const summary = (op.summary || "").trim();
34
- const description = op.description || summary || `${methodUpper} ${path}`;
35
- const category = op.tags?.[0] || "Other";
36
- const parameters = [];
37
- const allParams = [...methods.parameters || [], ...op.parameters || []];
38
- for (const param of allParams) {
39
- parameters.push({
40
- name: param.name,
41
- type: param.schema?.type || "string",
42
- required: param.required || false,
43
- description: param.description
44
- });
45
- }
46
- const responses = [];
47
- if (op.responses) {
48
- for (const [code, response] of Object.entries(op.responses)) {
49
- const respContent = response.content;
50
- const contentKeys = respContent ? Object.keys(respContent) : [];
51
- const chosenContentType = respContent?.["application/json"] ? "application/json" : contentKeys[0];
52
- const chosen = chosenContentType ? respContent?.[chosenContentType] : void 0;
53
- const respSchema = chosen?.schema;
54
- responses.push({
55
- code,
56
- description: response.description || `Response ${code}`,
57
- contentType: chosenContentType,
58
- schema: respSchema,
59
- example: respSchema ? chunk7EYHNP3E_cjs.sampleSchemaJson(respSchema, { skipWriteOnly: true }, specRoot) : void 0
60
- });
61
- }
62
- }
63
- let requestBody;
64
- if (op.requestBody) {
65
- const content = op.requestBody.content;
66
- const mediaType = content?.["application/json"] || content?.[Object.keys(content || {})[0]];
67
- const rawSchema = mediaType?.schema;
68
- requestBody = {
69
- type: rawSchema?.type || "object",
70
- description: op.requestBody.description,
71
- schema: rawSchema,
72
- example: rawSchema ? chunk7EYHNP3E_cjs.sampleSchemaJson(rawSchema, { skipReadOnly: true }, specRoot) : void 0
73
- };
74
- }
75
- const endpoint = {
76
- name: path.split("/").pop() || path,
77
- method: methodUpper,
78
- path: baseUrl ? chunk7EYHNP3E_cjs.joinUrl(baseUrl, path) : path,
79
- summary,
80
- description,
81
- category,
82
- parameters: parameters.length > 0 ? parameters : void 0,
83
- requestBody,
84
- responses: responses.length > 0 ? responses : void 0,
85
- schemaId
86
- };
87
- endpoints.push(endpoint);
88
- }
89
- }
90
- return endpoints;
91
- }, "extractEndpoints");
92
- var getCategories = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpoints) => {
93
- const categories = /* @__PURE__ */ new Set();
94
- endpoints.forEach((endpoint) => categories.add(endpoint.category));
95
- return Array.from(categories).sort();
96
- }, "getCategories");
97
- var fetchSchema = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(async (url) => {
98
- const response = await fetch(url, {
99
- headers: {
100
- "Accept": "application/json"
101
- }
102
- });
103
- if (!response.ok) {
104
- throw new Error(`Failed to fetch schema: ${response.statusText}`);
105
- }
106
- return response.json();
107
- }, "fetchSchema");
108
- function useOpenApiSchema({
109
- schemas,
110
- defaultSchemaId,
111
- baseUrl: configBaseUrl,
112
- preloadAll = false
113
- }) {
114
- const [loading, setLoading] = React12.useState(true);
115
- const [error, setError] = React12.useState(null);
116
- const [currentSchemaId, setCurrentSchemaId] = React12.useState(
117
- defaultSchemaId || schemas[0]?.id
118
- );
119
- const [loadedSchemas, setLoadedSchemas] = React12.useState(
120
- /* @__PURE__ */ new Map()
121
- );
122
- const [loadStates, setLoadStates] = React12.useState(/* @__PURE__ */ new Map());
123
- const currentSchema = React12.useMemo(
124
- () => schemas.find((s) => s.id === currentSchemaId) || null,
125
- [schemas, currentSchemaId]
126
- );
127
- const currentOpenApiSchema = React12.useMemo(
128
- () => currentSchemaId ? loadedSchemas.get(currentSchemaId) : null,
129
- [loadedSchemas, currentSchemaId]
130
- );
131
- const dereferencedSchema = React12.useMemo(
132
- () => currentOpenApiSchema ? chunk7EYHNP3E_cjs.dereferenceSchema(currentOpenApiSchema) : null,
133
- [currentOpenApiSchema]
134
- );
135
- const resolvedBaseUrl = React12.useMemo(
136
- () => chunk7EYHNP3E_cjs.resolveBaseUrl({
137
- schemaSource: currentSchema?.baseUrl,
138
- config: configBaseUrl,
139
- fromServers: currentOpenApiSchema?.servers?.[0]?.url
140
- }),
141
- [currentSchema?.baseUrl, configBaseUrl, currentOpenApiSchema]
142
- );
143
- const endpoints = React12.useMemo(
144
- () => dereferencedSchema ? extractEndpoints(dereferencedSchema, resolvedBaseUrl, currentSchemaId, currentOpenApiSchema ?? void 0) : [],
145
- [dereferencedSchema, resolvedBaseUrl, currentSchemaId, currentOpenApiSchema]
146
- );
147
- const categories = React12.useMemo(() => getCategories(endpoints), [endpoints]);
148
- const schemaInfo = React12.useMemo(() => {
149
- if (!currentOpenApiSchema?.info) return null;
150
- const { title, version, description } = currentOpenApiSchema.info;
151
- return {
152
- title,
153
- version,
154
- description,
155
- servers: currentOpenApiSchema.servers
156
- };
157
- }, [currentOpenApiSchema]);
158
- React12.useEffect(() => {
159
- if (preloadAll) return;
160
- if (!currentSchema) return;
161
- if (loadedSchemas.has(currentSchema.id)) {
162
- setLoading(false);
163
- return;
164
- }
165
- setLoading(true);
166
- setError(null);
167
- if (currentSchema.data) {
168
- setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, currentSchema.data));
169
- consola__default.default.success(`Schema loaded (static): ${currentSchema.name}`);
170
- setLoading(false);
171
- return;
172
- }
173
- if (!currentSchema.url) {
174
- setError("SchemaSource requires either url or data");
175
- setLoading(false);
176
- return;
177
- }
178
- fetchSchema(currentSchema.url).then((schema) => {
179
- setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, schema));
180
- consola__default.default.success(`Schema loaded: ${currentSchema.name}`);
181
- setLoading(false);
182
- }).catch((err) => {
183
- consola__default.default.error(`Error loading schema from ${currentSchema.url}:`, err);
184
- setError(err instanceof Error ? err.message : "Failed to load schema");
185
- setLoading(false);
186
- });
187
- }, [currentSchema, loadedSchemas, preloadAll]);
188
- React12.useEffect(() => {
189
- if (!preloadAll) return;
190
- if (schemas.length === 0) {
191
- setLoading(false);
192
- return;
193
- }
194
- let cancelled = false;
195
- const pending = schemas.filter((s) => !loadedSchemas.has(s.id));
196
- if (pending.length === 0) {
197
- setLoading(false);
198
- return;
199
- }
200
- setLoading(true);
201
- setLoadStates((prev) => {
202
- const next = new Map(prev);
203
- for (const s of pending) next.set(s.id, { loading: true, error: null });
204
- return next;
205
- });
206
- Promise.allSettled(
207
- pending.map(
208
- (s) => s.data ? Promise.resolve({ id: s.id, name: s.name, schema: s.data }) : s.url ? fetchSchema(s.url).then((schema) => ({ id: s.id, name: s.name, schema })) : Promise.reject(new Error("SchemaSource requires either url or data"))
209
- )
210
- ).then((results) => {
211
- if (cancelled) return;
212
- setLoadedSchemas((prev) => {
213
- const next = new Map(prev);
214
- for (const r of results) {
215
- if (r.status === "fulfilled") {
216
- next.set(r.value.id, r.value.schema);
217
- consola__default.default.success(`Schema loaded: ${r.value.name}`);
218
- }
219
- }
220
- return next;
221
- });
222
- setLoadStates((prev) => {
223
- const next = new Map(prev);
224
- results.forEach((r, i) => {
225
- const src = pending[i];
226
- if (r.status === "fulfilled") {
227
- next.set(src.id, { loading: false, error: null });
228
- } else {
229
- const msg = r.reason instanceof Error ? r.reason.message : "Failed to load schema";
230
- consola__default.default.error(`Error loading schema from ${src.url}:`, r.reason);
231
- next.set(src.id, { loading: false, error: msg });
232
- }
233
- });
234
- return next;
235
- });
236
- setLoading(false);
237
- });
238
- return () => {
239
- cancelled = true;
240
- };
241
- }, [preloadAll, schemas, loadedSchemas]);
242
- const schemasData = React12.useMemo(() => {
243
- if (!preloadAll) return [];
244
- return schemas.map((src) => {
245
- const raw = loadedSchemas.get(src.id) ?? null;
246
- const deref = raw ? chunk7EYHNP3E_cjs.dereferenceSchema(raw) : null;
247
- const resolved = chunk7EYHNP3E_cjs.resolveBaseUrl({
248
- schemaSource: src.baseUrl,
249
- config: configBaseUrl,
250
- fromServers: raw?.servers?.[0]?.url
251
- });
252
- const info = raw?.info ? {
253
- title: raw.info.title,
254
- version: raw.info.version,
255
- description: raw.info.description,
256
- servers: raw.servers
257
- } : null;
258
- const eps = deref ? extractEndpoints(deref, resolved, src.id, raw ?? void 0) : [];
259
- const state = loadStates.get(src.id) ?? { loading: !raw, error: null };
260
- return {
261
- source: src,
262
- info,
263
- rawSchema: raw,
264
- endpoints: eps,
265
- resolvedBaseUrl: resolved || void 0,
266
- loading: state.loading,
267
- error: state.error
268
- };
269
- });
270
- }, [preloadAll, schemas, loadedSchemas, loadStates, configBaseUrl]);
271
- const setCurrentSchema = React12.useCallback((schemaId) => {
272
- setCurrentSchemaId(schemaId);
273
- }, []);
274
- const refresh = React12.useCallback(() => {
275
- if (!currentSchema) return;
276
- if (currentSchema.data) {
277
- setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, currentSchema.data));
278
- return;
279
- }
280
- if (!currentSchema.url) return;
281
- setLoading(true);
282
- setError(null);
283
- setLoadedSchemas((prev) => {
284
- const next = new Map(prev);
285
- next.delete(currentSchema.id);
286
- return next;
287
- });
288
- fetchSchema(currentSchema.url).then((schema) => {
289
- setLoadedSchemas((prev) => new Map(prev).set(currentSchema.id, schema));
290
- consola__default.default.success(`Schema refreshed: ${currentSchema.name}`);
291
- setLoading(false);
292
- }).catch((err) => {
293
- consola__default.default.error(`Error refreshing schema from ${currentSchema.url}:`, err);
294
- setError(err instanceof Error ? err.message : "Failed to refresh schema");
295
- setLoading(false);
296
- });
297
- }, [currentSchema]);
298
- return {
299
- loading,
300
- error,
301
- endpoints,
302
- categories,
303
- schemas,
304
- currentSchema,
305
- schemaInfo,
306
- rawSchema: currentOpenApiSchema ?? null,
307
- // Consumers expect ``undefined`` when no base URL was resolved (for
308
- // conditional ``{ baseUrl?: … }`` plumbing). Turn the empty-string
309
- // convention from the resolver into undefined at the API boundary.
310
- resolvedBaseUrl: resolvedBaseUrl || void 0,
311
- setCurrentSchema,
312
- refresh,
313
- schemasData
314
- };
315
- }
316
- chunkOLISEQHS_cjs.__name(useOpenApiSchema, "useOpenApiSchema");
317
- function parseDocsHash(hash) {
318
- const raw = hash.startsWith("#") ? hash.slice(1) : hash;
319
- if (!raw) return { schemaId: null, anchor: null };
320
- const [schemaId = null, ...rest] = raw.split("/");
321
- const anchor = rest.length > 0 ? rest.join("/") : null;
322
- return {
323
- schemaId: schemaId || null,
324
- anchor: anchor || null
325
- };
326
- }
327
- chunkOLISEQHS_cjs.__name(parseDocsHash, "parseDocsHash");
328
- function buildDocsHash(schemaId, anchor) {
329
- if (!schemaId && !anchor) return "";
330
- if (schemaId && anchor) return `#${schemaId}/${anchor}`;
331
- if (schemaId) return `#${schemaId}`;
332
- return anchor ? `#${anchor}` : "";
333
- }
334
- chunkOLISEQHS_cjs.__name(buildDocsHash, "buildDocsHash");
335
- function useDocsUrlSync({
336
- enabled,
337
- currentSchemaId,
338
- activeAnchor,
339
- onHashTarget
340
- }) {
341
- const primedRef = React12.useRef(false);
342
- const onHashTargetRef = React12.useRef(onHashTarget);
343
- React12.useEffect(() => {
344
- onHashTargetRef.current = onHashTarget;
345
- }, [onHashTarget]);
346
- React12.useEffect(() => {
347
- if (!enabled || typeof window === "undefined") return;
348
- const apply = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
349
- onHashTargetRef.current(parseDocsHash(window.location.hash));
350
- }, "apply");
351
- apply();
352
- primedRef.current = true;
353
- window.addEventListener("hashchange", apply);
354
- window.addEventListener("popstate", apply);
355
- return () => {
356
- window.removeEventListener("hashchange", apply);
357
- window.removeEventListener("popstate", apply);
358
- };
359
- }, [enabled]);
360
- React12.useEffect(() => {
361
- if (!enabled || typeof window === "undefined") return;
362
- if (!primedRef.current) return;
363
- const next = buildDocsHash(currentSchemaId, activeAnchor);
364
- const current = window.location.hash;
365
- if (next === current) return;
366
- const url = next ? `${window.location.pathname}${window.location.search}${next}` : `${window.location.pathname}${window.location.search}`;
367
- window.history.replaceState(window.history.state, "", url);
368
- }, [enabled, currentSchemaId, activeAnchor]);
369
- const pushTarget = React12.useCallback(
370
- (schemaId, anchor) => {
371
- if (!enabled || typeof window === "undefined") return;
372
- const next = buildDocsHash(schemaId, anchor);
373
- const url = next ? `${window.location.pathname}${window.location.search}${next}` : `${window.location.pathname}${window.location.search}`;
374
- window.history.pushState(window.history.state, "", url);
375
- },
376
- [enabled]
377
- );
378
- return { pushTarget };
379
- }
380
- chunkOLISEQHS_cjs.__name(useDocsUrlSync, "useDocsUrlSync");
381
- var EMPTY_DRAFT = { parameters: {}, requestBody: "" };
382
- function storageKey(schemaId, ep) {
383
- if (!schemaId || !ep) return null;
384
- return `openapi-playground:draft:${schemaId}:${ep.method}:${ep.path}`;
385
- }
386
- chunkOLISEQHS_cjs.__name(storageKey, "storageKey");
387
- function readDraft(key) {
388
- if (!key || typeof window === "undefined") return EMPTY_DRAFT;
389
- try {
390
- const raw = window.localStorage.getItem(key);
391
- if (!raw) return EMPTY_DRAFT;
392
- const parsed = JSON.parse(raw);
393
- return {
394
- parameters: parsed?.parameters ?? {},
395
- requestBody: typeof parsed?.requestBody === "string" ? parsed.requestBody : ""
396
- };
397
- } catch {
398
- return EMPTY_DRAFT;
399
- }
400
- }
401
- chunkOLISEQHS_cjs.__name(readDraft, "readDraft");
402
- function writeDraft(key, value) {
403
- if (!key || typeof window === "undefined") return;
404
- try {
405
- if (Object.keys(value.parameters).length === 0 && !value.requestBody) {
406
- window.localStorage.removeItem(key);
407
- return;
408
- }
409
- window.localStorage.setItem(key, JSON.stringify(value));
410
- } catch {
411
- }
412
- }
413
- chunkOLISEQHS_cjs.__name(writeDraft, "writeDraft");
414
- function useEndpointDraft(schemaId, endpoint) {
415
- const key = storageKey(schemaId, endpoint);
416
- const [draft, setDraftSnapshot] = React12.useState(() => readDraft(key));
417
- const loadedKeyRef = React12.useRef(key);
418
- React12.useEffect(() => {
419
- if (loadedKeyRef.current === key) return;
420
- loadedKeyRef.current = key;
421
- setDraftSnapshot(readDraft(key));
422
- }, [key]);
423
- const keyRef = React12.useRef(key);
424
- React12.useEffect(() => {
425
- keyRef.current = key;
426
- }, [key]);
427
- const latestRef = React12.useRef(draft);
428
- React12.useEffect(() => {
429
- latestRef.current = draft;
430
- }, [draft]);
431
- const setParameters = React12.useCallback((params) => {
432
- const next = {
433
- parameters: params,
434
- requestBody: latestRef.current.requestBody
435
- };
436
- latestRef.current = next;
437
- writeDraft(keyRef.current, next);
438
- }, []);
439
- const setRequestBody = React12.useCallback((body) => {
440
- const next = {
441
- parameters: latestRef.current.parameters,
442
- requestBody: body
443
- };
444
- latestRef.current = next;
445
- writeDraft(keyRef.current, next);
446
- }, []);
447
- const reset = React12.useCallback(() => {
448
- latestRef.current = EMPTY_DRAFT;
449
- if (keyRef.current && typeof window !== "undefined") {
450
- try {
451
- window.localStorage.removeItem(keyRef.current);
452
- } catch {
453
- }
454
- }
455
- setDraftSnapshot(EMPTY_DRAFT);
456
- }, []);
457
- return { draft, setParameters, setRequestBody, reset };
458
- }
459
- chunkOLISEQHS_cjs.__name(useEndpointDraft, "useEndpointDraft");
460
-
461
- // src/tools/OpenapiViewer/components/shared/EndpointDraftSync.tsx
462
- function EndpointDraftSync({ schemaId }) {
463
- const { state, setParameters, setRequestBody, setActiveSchemaId } = chunk7EYHNP3E_cjs.usePlaygroundContext();
464
- const ep = state.selectedEndpoint;
465
- React12.useEffect(() => {
466
- setActiveSchemaId(schemaId);
467
- }, [schemaId, setActiveSchemaId]);
468
- const { draft, setParameters: persistParams, setRequestBody: persistBody } = useEndpointDraft(schemaId, ep);
469
- const lastLoadedKeyRef = React12.useRef(null);
470
- const lastPersistedParamsRef = React12.useRef("");
471
- const lastPersistedBodyRef = React12.useRef("");
472
- const currentKey = ep ? `${ep.method}|${ep.path}` : null;
473
- React12.useEffect(() => {
474
- if (!ep || !currentKey) {
475
- lastLoadedKeyRef.current = null;
476
- return;
477
- }
478
- if (lastLoadedKeyRef.current === currentKey) return;
479
- lastLoadedKeyRef.current = currentKey;
480
- const hasStoredParams = draft.parameters && Object.keys(draft.parameters).length > 0;
481
- const hasStoredBody = typeof draft.requestBody === "string" && draft.requestBody !== "";
482
- if (hasStoredParams) {
483
- setParameters(draft.parameters);
484
- lastPersistedParamsRef.current = JSON.stringify(draft.parameters);
485
- } else {
486
- lastPersistedParamsRef.current = JSON.stringify(state.parameters);
487
- }
488
- if (hasStoredBody) {
489
- setRequestBody(draft.requestBody);
490
- lastPersistedBodyRef.current = draft.requestBody;
491
- } else {
492
- lastPersistedBodyRef.current = state.requestBody;
493
- }
494
- }, [currentKey]);
495
- React12.useEffect(() => {
496
- if (!ep || lastLoadedKeyRef.current !== currentKey) return;
497
- const serialised = JSON.stringify(state.parameters);
498
- if (serialised === lastPersistedParamsRef.current) return;
499
- lastPersistedParamsRef.current = serialised;
500
- persistParams(state.parameters);
501
- }, [state.parameters, ep, currentKey, persistParams]);
502
- React12.useEffect(() => {
503
- if (!ep || lastLoadedKeyRef.current !== currentKey) return;
504
- if (state.requestBody === lastPersistedBodyRef.current) return;
505
- lastPersistedBodyRef.current = state.requestBody;
506
- persistBody(state.requestBody);
507
- }, [state.requestBody, ep, currentKey, persistBody]);
508
- return null;
509
- }
510
- chunkOLISEQHS_cjs.__name(EndpointDraftSync, "EndpointDraftSync");
511
-
512
- // src/tools/OpenapiViewer/components/DocsLayout/anchor.ts
513
- function endpointAnchor(ep, schemaId) {
514
- const slug = ep.path.replace(/^https?:\/\/[^/]+/, "").replace(/[{}]/g, "").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
515
- const schemaSlug = schemaId ? `${slugifySchemaId(schemaId)}-` : "";
516
- return `ep-${schemaSlug}${ep.method.toLowerCase()}-${slug}`;
517
- }
518
- chunkOLISEQHS_cjs.__name(endpointAnchor, "endpointAnchor");
519
- function slugifySchemaId(id) {
520
- return id.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
521
- }
522
- chunkOLISEQHS_cjs.__name(slugifySchemaId, "slugifySchemaId");
523
- var METHOD_STYLES = {
524
- GET: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25",
525
- POST: "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25",
526
- PUT: "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/25",
527
- PATCH: "bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/25",
528
- DELETE: "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/25"
529
- };
530
- var METHOD_FALLBACK = "bg-muted text-muted-foreground border-border";
531
- function getMethodStyle(method) {
532
- return METHOD_STYLES[method.toUpperCase()] ?? METHOD_FALLBACK;
533
- }
534
- chunkOLISEQHS_cjs.__name(getMethodStyle, "getMethodStyle");
535
- function getStatusStyle(status) {
536
- if (status >= 500) return "bg-red-500/10 text-red-500 dark:text-red-400 border-red-500/25";
537
- if (status >= 400) return "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/25";
538
- if (status >= 300) return "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25";
539
- return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25";
540
- }
541
- chunkOLISEQHS_cjs.__name(getStatusStyle, "getStatusStyle");
542
- function MethodBadge({ method }) {
543
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
544
- "inline-flex shrink-0 items-center rounded border px-1.5 py-px",
545
- "font-mono text-[10px] font-bold uppercase tracking-wider leading-none",
546
- getMethodStyle(method)
547
- ), children: method });
548
- }
549
- chunkOLISEQHS_cjs.__name(MethodBadge, "MethodBadge");
550
- function StatusBadge({ status }) {
551
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
552
- "inline-flex items-center rounded border px-1.5 py-px",
553
- "font-mono text-[11px] font-bold leading-none",
554
- getStatusStyle(status)
555
- ), children: status });
556
- }
557
- chunkOLISEQHS_cjs.__name(StatusBadge, "StatusBadge");
558
- function SectionLabel({ children }) {
559
- return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60 select-none", children });
560
- }
561
- chunkOLISEQHS_cjs.__name(SectionLabel, "SectionLabel");
562
- function Panel({ children, className }) {
563
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn("flex flex-col min-h-0 overflow-hidden", className), children });
564
- }
565
- chunkOLISEQHS_cjs.__name(Panel, "Panel");
566
- function ScrollArea({ children, className }) {
567
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn("flex-1 overflow-y-auto min-h-0", className), children });
568
- }
569
- chunkOLISEQHS_cjs.__name(ScrollArea, "ScrollArea");
570
- function EmptyState({
571
- icon: Icon,
572
- text,
573
- className
574
- }) {
575
- return /* @__PURE__ */ jsxRuntime.jsxs(
576
- "div",
577
- {
578
- className: lib.cn(
579
- "flex flex-col items-center justify-center h-full gap-3 px-6 text-center",
580
- className
581
- ),
582
- children: [
583
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-7 w-7 text-muted-foreground/25" }),
584
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: text })
585
- ]
586
- }
587
- );
588
- }
589
- chunkOLISEQHS_cjs.__name(EmptyState, "EmptyState");
590
- function CollapsibleSection({
591
- label,
592
- action,
593
- children,
594
- defaultOpen = false
595
- }) {
596
- const [open, setOpen] = React12__default.default.useState(defaultOpen);
597
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0", children: [
598
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
599
- /* @__PURE__ */ jsxRuntime.jsxs(
600
- "button",
601
- {
602
- type: "button",
603
- onClick: () => setOpen((v) => !v),
604
- 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",
605
- children: [
606
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: lib.cn("h-3 w-3 transition-transform", open && "rotate-90") }),
607
- label
608
- ]
609
- }
610
- ),
611
- action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action })
612
- ] }),
613
- open && /* @__PURE__ */ jsxRuntime.jsx("div", { children })
614
- ] });
615
- }
616
- chunkOLISEQHS_cjs.__name(CollapsibleSection, "CollapsibleSection");
617
- function BrandHeader({ info }) {
618
- const apiTitle = info?.title ?? "API Reference";
619
- const versionLabel = info?.version ? `v${info.version}` : null;
620
- const versionNode = versionLabel ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-[10px] text-muted-foreground/60 leading-tight mt-0.5", children: versionLabel }) : null;
621
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 py-2.5", children: [
622
- /* @__PURE__ */ jsxRuntime.jsx(
623
- "div",
624
- {
625
- className: "text-[13px] font-semibold text-foreground leading-tight truncate",
626
- title: apiTitle,
627
- children: apiTitle
628
- }
629
- ),
630
- versionNode
631
- ] });
632
- }
633
- chunkOLISEQHS_cjs.__name(BrandHeader, "BrandHeader");
634
-
635
- // src/tools/OpenapiViewer/components/DocsLayout/sidebarLabel.ts
636
- function longestCommonPrefix(paths) {
637
- if (paths.length === 0) return "";
638
- if (paths.length === 1) return "";
639
- const segments = paths.map((p) => p.split("/"));
640
- const minLen = Math.min(...segments.map((s) => s.length));
641
- const shared = [];
642
- for (let i = 0; i < minLen; i++) {
643
- const first = segments[0][i];
644
- if (segments.every((s) => s[i] === first)) {
645
- shared.push(first);
646
- } else {
647
- break;
648
- }
649
- }
650
- const joined = shared.join("/");
651
- return joined;
652
- }
653
- chunkOLISEQHS_cjs.__name(longestCommonPrefix, "longestCommonPrefix");
654
- function sidebarLabel(ep, groupCommonPrefix) {
655
- if (ep.summary) return ep.summary;
656
- if (groupCommonPrefix && ep.path.startsWith(groupCommonPrefix)) {
657
- const tail = ep.path.slice(groupCommonPrefix.length) || "/";
658
- return tail;
659
- }
660
- return chunk7EYHNP3E_cjs.relativePath(ep.path);
661
- }
662
- chunkOLISEQHS_cjs.__name(sidebarLabel, "sidebarLabel");
663
- function sidebarTooltip(ep) {
664
- return `${ep.method} ${chunk7EYHNP3E_cjs.relativePath(ep.path)}`;
665
- }
666
- chunkOLISEQHS_cjs.__name(sidebarTooltip, "sidebarTooltip");
667
-
668
- // src/tools/OpenapiViewer/components/DocsLayout/grouping.ts
669
- var METHOD_ORDER = {
670
- GET: 0,
671
- POST: 1,
672
- PUT: 2,
673
- PATCH: 3,
674
- DELETE: 4
675
- };
676
- var methodRank = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((ep) => METHOD_ORDER[ep.method] ?? 99, "methodRank");
677
- function groupEndpoints(list) {
678
- const byCategory = lodashEs.groupBy(list, "category");
679
- const all = Object.entries(byCategory).map(([category, endpoints]) => ({
680
- category,
681
- endpoints: lodashEs.orderBy(endpoints, ["path", methodRank], ["asc", "asc"]),
682
- commonPrefix: longestCommonPrefix(endpoints.map((e) => e.path))
683
- }));
684
- const [other, named] = lodashEs.partition(all, (g) => g.category === "Other");
685
- return [...lodashEs.sortBy(named, (g) => g.category.toLowerCase()), ...other];
686
- }
687
- chunkOLISEQHS_cjs.__name(groupEndpoints, "groupEndpoints");
688
- function buildSchemaSections(sources, endpointsBySchema) {
689
- return sources.map((source) => ({
690
- source,
691
- groups: groupEndpoints(endpointsBySchema[source.id] ?? [])
692
- }));
693
- }
694
- chunkOLISEQHS_cjs.__name(buildSchemaSections, "buildSchemaSections");
695
-
696
- // src/tools/OpenapiViewer/components/DocsLayout/Sidebar/buildVM.ts
697
- function filterEndpoints(list, query, method) {
698
- let out = list;
699
- if (method !== "ALL") {
700
- out = out.filter((e) => e.method === method);
701
- }
702
- if (query) {
703
- const q = query.toLowerCase();
704
- out = out.filter(
705
- (e) => e.summary.toLowerCase().includes(q) || e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q) || e.path.toLowerCase().includes(q)
706
- );
707
- }
708
- return out;
709
- }
710
- chunkOLISEQHS_cjs.__name(filterEndpoints, "filterEndpoints");
711
- function buildCategory(group, activeEndpointId, schemaId, keyPrefix) {
712
- const rows = group.endpoints.map((ep) => {
713
- const anchor = endpointAnchor(ep, schemaId ?? ep.schemaId ?? null);
714
- return {
715
- key: `${ep.method}-${ep.path}`,
716
- anchor,
717
- schemaId: schemaId ?? ep.schemaId ?? null,
718
- label: sidebarLabel(ep, group.commonPrefix),
719
- tooltip: sidebarTooltip(ep),
720
- method: ep.method,
721
- useMono: !ep.summary,
722
- isActive: activeEndpointId === anchor
723
- };
724
- });
725
- return {
726
- key: `${keyPrefix}${group.category}`,
727
- category: group.category,
728
- rows
729
- };
730
- }
731
- chunkOLISEQHS_cjs.__name(buildCategory, "buildCategory");
732
- function emptyTextFor(query, method, defaultText) {
733
- if (query && method !== "ALL") return `No ${method} endpoints match "${query}"`;
734
- if (query) return `No endpoints match "${query}"`;
735
- if (method !== "ALL") return `No ${method} endpoints`;
736
- return defaultText;
737
- }
738
- chunkOLISEQHS_cjs.__name(emptyTextFor, "emptyTextFor");
739
- function buildFlatVM(endpoints, selectedVersion, query, method, activeEndpointId) {
740
- const filtered = filterEndpoints(
741
- chunk7EYHNP3E_cjs.deduplicateEndpoints(endpoints, selectedVersion),
742
- query,
743
- method
744
- );
745
- const groups = groupEndpoints(filtered);
746
- return {
747
- kind: "flat",
748
- categories: groups.map((g) => buildCategory(g, activeEndpointId, null, "")),
749
- emptyText: emptyTextFor(query, method, "No endpoints in this schema")
750
- };
751
- }
752
- chunkOLISEQHS_cjs.__name(buildFlatVM, "buildFlatVM");
753
- function buildSectionsVM(schemas, endpointsBySchema, selectedVersion, query, method, activeEndpointId) {
754
- const filteredMap = {};
755
- for (const src of schemas) {
756
- const raw = endpointsBySchema[src.id] ?? [];
757
- filteredMap[src.id] = filterEndpoints(
758
- chunk7EYHNP3E_cjs.deduplicateEndpoints(raw, selectedVersion),
759
- query,
760
- method
761
- );
762
- }
763
- const rawSections = buildSchemaSections(schemas, filteredMap);
764
- const sections = rawSections.filter((s) => s.groups.length > 0).map((s) => ({
765
- sourceId: s.source.id,
766
- sourceName: s.source.name,
767
- categories: s.groups.map(
768
- (g) => buildCategory(g, activeEndpointId, s.source.id, `${s.source.id}-`)
769
- )
770
- }));
771
- return {
772
- kind: "sections",
773
- sections,
774
- emptyText: emptyTextFor(query, method, "No endpoints in any schema")
775
- };
776
- }
777
- chunkOLISEQHS_cjs.__name(buildSectionsVM, "buildSectionsVM");
778
- var EndpointRow = React12__default.default.memo(/* @__PURE__ */ chunkOLISEQHS_cjs.__name(function EndpointRow2({
779
- row,
780
- onNavigate
781
- }) {
782
- const displayLabel = row.label.replace(/\.$/, "");
783
- const buttonRef = React12.useRef(null);
784
- React12.useEffect(() => {
785
- if (!row.isActive || !buttonRef.current) return;
786
- buttonRef.current.scrollIntoView({ block: "nearest", inline: "nearest" });
787
- }, [row.isActive]);
788
- return /* @__PURE__ */ jsxRuntime.jsxs(components.Tooltip, { delayDuration: 350, children: [
789
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
790
- "button",
791
- {
792
- ref: buttonRef,
793
- onClick: () => onNavigate(row.anchor, row.schemaId),
794
- "aria-current": row.isActive ? "location" : void 0,
795
- className: lib.cn(
796
- "relative w-full text-left grid grid-cols-[52px_minmax(0,1fr)] items-baseline gap-2 pl-3 pr-3 py-1 transition-colors",
797
- row.isActive ? "bg-primary/10 text-foreground" : "hover:bg-muted/40 text-foreground/75 hover:text-foreground"
798
- ),
799
- children: [
800
- row.isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-0 top-1 bottom-1 w-0.5 rounded-r bg-primary" }),
801
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "justify-self-start", children: /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: row.method }) }),
802
- /* @__PURE__ */ jsxRuntime.jsx(
803
- "span",
804
- {
805
- className: lib.cn(
806
- "line-clamp-2 leading-snug min-w-0",
807
- row.useMono ? "font-mono text-[11px] break-all" : "text-[12px]",
808
- row.isActive && "text-foreground font-medium"
809
- ),
810
- children: displayLabel
811
- }
812
- )
813
- ]
814
- }
815
- ) }),
816
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipContent, { side: "right", align: "center", className: "font-mono text-[11px]", children: row.tooltip })
817
- ] });
818
- }, "EndpointRow"));
819
- var CategoryBlock = React12__default.default.memo(/* @__PURE__ */ chunkOLISEQHS_cjs.__name(function CategoryBlock2({
820
- category,
821
- onNavigate
822
- }) {
823
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2.5 last:mb-1", children: [
824
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-3 pb-1 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/50 select-none", children: category.category }),
825
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: category.rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(EndpointRow, { row, onNavigate }, row.key)) })
826
- ] });
827
- }, "CategoryBlock"));
828
- function SchemaSection({ section, onNavigate }) {
829
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 last:mb-2", children: [
830
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 sticky top-0 z-[1] bg-background/95 backdrop-blur-[2px] border-b border-border/40", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-bold uppercase tracking-[0.12em] text-foreground/80", children: section.sourceName }) }),
831
- section.categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(CategoryBlock, { category: cat, onNavigate }, cat.key))
832
- ] });
833
- }
834
- chunkOLISEQHS_cjs.__name(SchemaSection, "SchemaSection");
835
- function SidebarBody({ body, onNavigate }) {
836
- if (body.kind === "flat") {
837
- if (body.categories.length === 0) {
838
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: body.emptyText });
839
- }
840
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "pt-1.5 pb-[10vh]", children: body.categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(CategoryBlock, { category: cat, onNavigate }, cat.key)) });
841
- }
842
- if (body.sections.length === 0) {
843
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: body.emptyText });
844
- }
845
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "py-1.5", children: body.sections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(SchemaSection, { section, onNavigate }, section.sourceId)) });
846
- }
847
- chunkOLISEQHS_cjs.__name(SidebarBody, "SidebarBody");
848
- var FLAVOUR_LABELS = {
849
- markdown: {
850
- title: "Markdown for LLM",
851
- hint: "Endpoints + params as prose. Smallest."
852
- },
853
- compact: {
854
- title: "Compact JSON",
855
- hint: "Dereferenced, no examples, minified."
856
- },
857
- raw: {
858
- title: "Raw JSON",
859
- hint: "Full OpenAPI document with $refs."
860
- }
861
- };
862
- function SchemaCopyMenu({ schema, endpoints, baseUrl, variant = "button", side }) {
863
- const [sizeCache, setSizeCache] = React12.useState({});
864
- const [justCopied, setJustCopied] = React12.useState(null);
865
- const [open, setOpen] = React12.useState(false);
866
- const isReady = schema !== null && endpoints.length > 0;
867
- const build = React12.useCallback(
868
- (flavour) => {
869
- if (!schema) return "";
870
- if (flavour === "markdown") return chunk7EYHNP3E_cjs.toMarkdown(schema, endpoints, baseUrl);
871
- if (flavour === "compact") return chunk7EYHNP3E_cjs.toCompactJson(schema, baseUrl);
872
- return chunk7EYHNP3E_cjs.toRawJson(schema, baseUrl);
873
- },
874
- [schema, endpoints, baseUrl]
875
- );
876
- const handleCopy = React12.useCallback(
877
- async (flavour) => {
878
- if (!isReady) return;
879
- const text = build(flavour);
880
- const label = FLAVOUR_LABELS[flavour].title;
881
- try {
882
- await navigator.clipboard.writeText(text);
883
- const size = chunk7EYHNP3E_cjs.formatBytes(text);
884
- setSizeCache((prev) => ({ ...prev, [flavour]: size }));
885
- setJustCopied(flavour);
886
- setTimeout(() => setJustCopied(null), 1500);
887
- setOpen(false);
888
- hooks.toast.success(`Copied ${label}`, { description: size });
889
- } catch (err) {
890
- const message = err instanceof Error ? err.message : "Clipboard permission denied";
891
- hooks.toast.error("Copy failed", { description: message });
892
- }
893
- },
894
- [build, isReady]
895
- );
896
- const flavours = React12.useMemo(() => ["markdown", "compact", "raw"], []);
897
- const resolvedSide = side ?? (variant === "footer" ? "top" : "right");
898
- const resolvedAlign = variant === "footer" ? "center" : "start";
899
- return /* @__PURE__ */ jsxRuntime.jsxs(components.DropdownMenu, { open, onOpenChange: setOpen, children: [
900
- /* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuTrigger, { asChild: true, children: variant === "icon" ? /* @__PURE__ */ jsxRuntime.jsx(
901
- components.Button,
902
- {
903
- variant: "ghost",
904
- size: "icon",
905
- className: "h-7 w-7 shrink-0",
906
- disabled: !isReady,
907
- title: "Copy schema for AI",
908
- "aria-label": "Copy schema for AI",
909
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3.5 w-3.5" })
910
- }
911
- ) : variant === "footer" ? /* @__PURE__ */ jsxRuntime.jsxs(
912
- components.Button,
913
- {
914
- variant: "secondary",
915
- size: "sm",
916
- className: "w-full justify-center gap-1.5 text-xs",
917
- disabled: !isReady,
918
- children: [
919
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" }),
920
- "Copy schema for AI",
921
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 opacity-60" })
922
- ]
923
- }
924
- ) : /* @__PURE__ */ jsxRuntime.jsxs(components.Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
925
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" }),
926
- "Copy for AI",
927
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 opacity-60" })
928
- ] }) }),
929
- /* @__PURE__ */ jsxRuntime.jsxs(
930
- components.DropdownMenuContent,
931
- {
932
- side: resolvedSide,
933
- align: resolvedAlign,
934
- sideOffset: 6,
935
- collisionPadding: 8,
936
- className: "w-60 max-w-[calc(100vw-16px)]",
937
- children: [
938
- /* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuLabel, { className: "text-[10px] uppercase tracking-wider text-muted-foreground/70", children: "Copy schema" }),
939
- /* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuSeparator, {}),
940
- flavours.map((f) => {
941
- const label = FLAVOUR_LABELS[f];
942
- const size = sizeCache[f];
943
- const isDone = justCopied === f;
944
- return /* @__PURE__ */ jsxRuntime.jsxs(
945
- components.DropdownMenuItem,
946
- {
947
- onClick: (e) => {
948
- e.preventDefault();
949
- void handleCopy(f);
950
- },
951
- className: "flex flex-col items-start gap-0.5 py-2 cursor-pointer",
952
- children: [
953
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2", children: [
954
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium flex-1", children: label.title }),
955
- isDone ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-emerald-500", children: [
956
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }),
957
- " Copied"
958
- ] }) : size ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono text-muted-foreground/70 tabular-nums", children: size }) : null
959
- ] }),
960
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/70 leading-snug line-clamp-1", children: label.hint })
961
- ]
962
- },
963
- f
964
- );
965
- })
966
- ]
967
- }
968
- )
969
- ] });
970
- }
971
- chunkOLISEQHS_cjs.__name(SchemaCopyMenu, "SchemaCopyMenu");
972
- function SearchInput({ value, onChange, placeholder }) {
973
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
974
- /* @__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" }),
975
- /* @__PURE__ */ jsxRuntime.jsx(
976
- components.Input,
977
- {
978
- placeholder: placeholder ?? "Search endpoints\u2026",
979
- value,
980
- onChange: (e) => onChange(e.target.value),
981
- className: "pl-8 pr-7 h-8 text-xs"
982
- }
983
- ),
984
- value && /* @__PURE__ */ jsxRuntime.jsx(
985
- "button",
986
- {
987
- type: "button",
988
- onClick: () => onChange(""),
989
- "aria-label": "Clear search",
990
- className: lib.cn(
991
- "absolute right-1.5 top-1/2 -translate-y-1/2 h-5 w-5 rounded",
992
- "inline-flex items-center justify-center",
993
- "text-muted-foreground/50 hover:text-foreground hover:bg-muted transition-colors"
994
- ),
995
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" })
996
- }
997
- )
998
- ] });
999
- }
1000
- chunkOLISEQHS_cjs.__name(SearchInput, "SearchInput");
1001
- function Toolbar({
1002
- schemas,
1003
- currentSchemaId,
1004
- onSchemaChange,
1005
- showSchemaSelector,
1006
- search,
1007
- onSearchChange,
1008
- endpoints,
1009
- rawSchema,
1010
- resolvedBaseUrl
1011
- }) {
1012
- const schemaOptions = React12__default.default.useMemo(
1013
- () => schemas.map((s) => ({ value: s.id, label: s.name })),
1014
- [schemas]
1015
- );
1016
- const copyReady = rawSchema !== null && rawSchema !== void 0 && endpoints.length > 0;
1017
- const schemaSelectorNode = showSchemaSelector ? /* @__PURE__ */ jsxRuntime.jsx(
1018
- components.Combobox,
1019
- {
1020
- options: schemaOptions,
1021
- value: currentSchemaId ?? "",
1022
- onValueChange: (id) => id && onSchemaChange(id),
1023
- placeholder: "Select API",
1024
- searchPlaceholder: "Search APIs\u2026",
1025
- emptyText: "No APIs found",
1026
- className: "w-full h-8 text-xs"
1027
- }
1028
- ) : null;
1029
- const copyMenuNode = copyReady ? /* @__PURE__ */ jsxRuntime.jsx(
1030
- SchemaCopyMenu,
1031
- {
1032
- schema: rawSchema ?? null,
1033
- endpoints,
1034
- baseUrl: resolvedBaseUrl,
1035
- variant: "footer",
1036
- side: "bottom"
1037
- }
1038
- ) : null;
1039
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 py-2.5 space-y-2", children: [
1040
- schemaSelectorNode,
1041
- /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { value: search, onChange: onSearchChange }),
1042
- copyMenuNode
1043
- ] });
1044
- }
1045
- chunkOLISEQHS_cjs.__name(Toolbar, "Toolbar");
1046
- function useDebouncedValue(value, delayMs = 120) {
1047
- const [debounced, setDebounced] = React12.useState(value);
1048
- React12.useEffect(() => {
1049
- const id = setTimeout(() => setDebounced(value), delayMs);
1050
- return () => clearTimeout(id);
1051
- }, [value, delayMs]);
1052
- return debounced;
1053
- }
1054
- chunkOLISEQHS_cjs.__name(useDebouncedValue, "useDebouncedValue");
1055
- function DocsSidebar({
1056
- info,
1057
- endpoints,
1058
- schemas,
1059
- currentSchemaId,
1060
- onSchemaChange,
1061
- activeEndpointId,
1062
- selectedVersion,
1063
- onNavigate,
1064
- grouping = "selector",
1065
- endpointsBySchema,
1066
- rawSchema,
1067
- resolvedBaseUrl
1068
- }) {
1069
- const [search, setSearch] = React12.useState("");
1070
- const debouncedSearch = useDebouncedValue(search);
1071
- const body = React12.useMemo(() => {
1072
- if (grouping === "sections") {
1073
- return buildSectionsVM(
1074
- schemas,
1075
- endpointsBySchema ?? {},
1076
- selectedVersion,
1077
- debouncedSearch,
1078
- "ALL",
1079
- activeEndpointId
1080
- );
1081
- }
1082
- return buildFlatVM(
1083
- endpoints,
1084
- selectedVersion,
1085
- debouncedSearch,
1086
- "ALL",
1087
- activeEndpointId
1088
- );
1089
- }, [
1090
- grouping,
1091
- schemas,
1092
- endpointsBySchema,
1093
- endpoints,
1094
- selectedVersion,
1095
- debouncedSearch,
1096
- activeEndpointId
1097
- ]);
1098
- const hasMultipleSchemas = schemas.length > 1;
1099
- const showSchemaSelector = grouping === "selector" && hasMultipleSchemas;
1100
- return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "flex flex-col h-full min-h-0 border-r bg-muted/10", children: [
1101
- /* @__PURE__ */ jsxRuntime.jsx(BrandHeader, { info }),
1102
- /* @__PURE__ */ jsxRuntime.jsx(
1103
- Toolbar,
1104
- {
1105
- schemas,
1106
- currentSchemaId,
1107
- onSchemaChange,
1108
- showSchemaSelector,
1109
- search,
1110
- onSearchChange: setSearch,
1111
- endpoints,
1112
- rawSchema,
1113
- resolvedBaseUrl
1114
- }
1115
- ),
1116
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarBody, { body, onNavigate }) })
1117
- ] });
1118
- }
1119
- chunkOLISEQHS_cjs.__name(DocsSidebar, "DocsSidebar");
1120
-
1121
- // src/tools/OpenapiViewer/utils/scrollParent.ts
1122
- function getScrollParent(el) {
1123
- if (typeof window === "undefined") return null;
1124
- if (!el) return window;
1125
- let cur = el.parentElement;
1126
- while (cur && cur !== document.body && cur !== document.documentElement) {
1127
- const style = getComputedStyle(cur);
1128
- const overflowY = style.overflowY;
1129
- const canScroll = (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && cur.scrollHeight > cur.clientHeight;
1130
- if (canScroll) return cur;
1131
- cur = cur.parentElement;
1132
- }
1133
- return window;
1134
- }
1135
- chunkOLISEQHS_cjs.__name(getScrollParent, "getScrollParent");
1136
- function getScrollTop(target) {
1137
- return target === window ? window.scrollY : target.scrollTop;
1138
- }
1139
- chunkOLISEQHS_cjs.__name(getScrollTop, "getScrollTop");
1140
- function getViewportHeight(target) {
1141
- return target === window ? window.innerHeight : target.clientHeight;
1142
- }
1143
- chunkOLISEQHS_cjs.__name(getViewportHeight, "getViewportHeight");
1144
- function getTargetTop(target) {
1145
- return target === window ? 0 : target.getBoundingClientRect().top;
1146
- }
1147
- chunkOLISEQHS_cjs.__name(getTargetTop, "getTargetTop");
1148
- function scrollTargetTo(target, top) {
1149
- if (target === window) {
1150
- window.scrollTo({ top, behavior: "smooth" });
1151
- return;
1152
- }
1153
- target.scrollTop = top;
1154
- }
1155
- chunkOLISEQHS_cjs.__name(scrollTargetTo, "scrollTargetTo");
1156
- function ApiIntroSection({ info, schema, endpoints, resolvedBaseUrl }) {
1157
- const baseUrlRows = resolvedBaseUrl ? [{ url: resolvedBaseUrl, description: info.servers?.[0]?.description }] : (info.servers ?? []).map((s) => ({ url: s.url, description: s.description }));
1158
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pb-10 mb-10 border-b", children: [
1159
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 flex-wrap", children: [
1160
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap min-w-0", children: [
1161
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-semibold tracking-tight text-foreground leading-tight", children: info.title }),
1162
- /* @__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: [
1163
- "v",
1164
- info.version
1165
- ] })
1166
- ] }),
1167
- /* @__PURE__ */ jsxRuntime.jsx(
1168
- SchemaCopyMenu,
1169
- {
1170
- schema,
1171
- endpoints,
1172
- baseUrl: resolvedBaseUrl
1173
- }
1174
- )
1175
- ] }),
1176
- info.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(chunk7IYXZUJO_cjs.MarkdownMessage, { content: info.description }) }),
1177
- baseUrlRows.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 space-y-2", children: [
1178
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60", children: "Base URL" }),
1179
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: baseUrlRows.map((row, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
1180
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs px-2 py-1 rounded bg-muted border", children: row.url }),
1181
- row.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: row.description })
1182
- ] }, `${row.url}-${i}`)) })
1183
- ] })
1184
- ] });
1185
- }
1186
- chunkOLISEQHS_cjs.__name(ApiIntroSection, "ApiIntroSection");
1187
- var EndpointDocContext = React12.createContext(null);
1188
- function EndpointDocProvider({ endpointId, method, children }) {
1189
- const value = React12.useMemo(() => ({ endpointId, method }), [endpointId, method]);
1190
- return /* @__PURE__ */ jsxRuntime.jsx(EndpointDocContext.Provider, { value, children });
1191
- }
1192
- chunkOLISEQHS_cjs.__name(EndpointDocProvider, "EndpointDocProvider");
1193
- function useEndpointDocContext() {
1194
- const ctx = React12.useContext(EndpointDocContext);
1195
- if (!ctx) {
1196
- throw new Error(
1197
- "[OpenapiViewer] useEndpointDocContext must be used inside <EndpointDocProvider>."
1198
- );
1199
- }
1200
- return ctx;
1201
- }
1202
- chunkOLISEQHS_cjs.__name(useEndpointDocContext, "useEndpointDocContext");
1203
- var sectionKey = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, sectionId) => `${endpointId}:${sectionId}`, "sectionKey");
1204
- var initialState = {
1205
- openSections: {},
1206
- activeCodeTab: {}
1207
- };
1208
- var useEndpointDocStore = zustand.create()(
1209
- middleware.persist(
1210
- (set) => ({
1211
- ...initialState,
1212
- toggleSection: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, sectionId, defaultOpen) => set((state) => {
1213
- const key = sectionKey(endpointId, sectionId);
1214
- const current = state.openSections[key];
1215
- const visible = current === void 0 ? defaultOpen : current;
1216
- return {
1217
- openSections: {
1218
- ...state.openSections,
1219
- [key]: !visible
1220
- }
1221
- };
1222
- }), "toggleSection"),
1223
- setSectionOpen: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, sectionId, open) => set((state) => ({
1224
- openSections: {
1225
- ...state.openSections,
1226
- [sectionKey(endpointId, sectionId)]: open
1227
- }
1228
- })), "setSectionOpen"),
1229
- setCodeTab: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, tab) => set((state) => ({
1230
- activeCodeTab: {
1231
- ...state.activeCodeTab,
1232
- [endpointId]: tab
1233
- }
1234
- })), "setCodeTab"),
1235
- expandAll: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, sectionIds) => set((state) => {
1236
- const next = { ...state.openSections };
1237
- for (const sid of sectionIds) {
1238
- next[sectionKey(endpointId, sid)] = true;
1239
- }
1240
- return { openSections: next };
1241
- }), "expandAll"),
1242
- collapseAll: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((endpointId, sectionIds) => set((state) => {
1243
- const next = { ...state.openSections };
1244
- for (const sid of sectionIds) {
1245
- next[sectionKey(endpointId, sid)] = false;
1246
- }
1247
- return { openSections: next };
1248
- }), "collapseAll")
1249
- }),
1250
- {
1251
- name: "openapi-viewer:endpoint-doc",
1252
- storage: middleware.createJSONStorage(() => {
1253
- if (typeof window === "undefined") {
1254
- return {
1255
- getItem: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => null, "getItem"),
1256
- setItem: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
1257
- }, "setItem"),
1258
- removeItem: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
1259
- }, "removeItem")
1260
- };
1261
- }
1262
- return window.sessionStorage;
1263
- }),
1264
- // Only persist user overrides, not the functions. Zustand
1265
- // serialises everything by default and logs a warning on
1266
- // non-serialisable values; partialize keeps the payload lean.
1267
- partialize: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((state) => ({
1268
- openSections: state.openSections,
1269
- activeCodeTab: state.activeCodeTab
1270
- }), "partialize")
1271
- }
1272
- )
1273
- );
1274
-
1275
- // src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/store/selectors.ts
1276
- function useIsSectionOpen(endpointId, sectionId, defaultOpen) {
1277
- return useEndpointDocStore((s) => {
1278
- const explicit = s.openSections[sectionKey(endpointId, sectionId)];
1279
- return explicit === void 0 ? defaultOpen : explicit;
1280
- });
1281
- }
1282
- chunkOLISEQHS_cjs.__name(useIsSectionOpen, "useIsSectionOpen");
1283
- function useActiveCodeTab(endpointId, fallback = "curl") {
1284
- return useEndpointDocStore((s) => s.activeCodeTab[endpointId] ?? fallback);
1285
- }
1286
- chunkOLISEQHS_cjs.__name(useActiveCodeTab, "useActiveCodeTab");
1287
- function LanguageTabs({ activeId, onChange }) {
1288
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 overflow-x-auto -mx-1 px-1", children: chunk7EYHNP3E_cjs.CODE_SAMPLE_TARGETS.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
1289
- "button",
1290
- {
1291
- type: "button",
1292
- onClick: () => onChange(t.id),
1293
- className: lib.cn(
1294
- "shrink-0 h-7 px-2.5 rounded text-xs font-medium transition-colors",
1295
- activeId === t.id ? "bg-muted text-foreground" : "text-muted-foreground/70 hover:text-foreground hover:bg-muted/50"
1296
- ),
1297
- children: t.label
1298
- },
1299
- t.id
1300
- )) });
1301
- }
1302
- chunkOLISEQHS_cjs.__name(LanguageTabs, "LanguageTabs");
1303
- function useCodeSnippet({
1304
- endpoint,
1305
- body,
1306
- parameters,
1307
- headers,
1308
- baseUrl,
1309
- activeId
1310
- }) {
1311
- const effectiveBody = body ?? endpoint.requestBody?.example;
1312
- const har = React12.useMemo(() => {
1313
- const h = chunk7EYHNP3E_cjs.buildHarRequest({
1314
- endpoint,
1315
- body: effectiveBody,
1316
- parameters,
1317
- headers,
1318
- baseUrl
1319
- });
1320
- return baseUrl ? h : { ...h, url: chunk7EYHNP3E_cjs.resolveAbsolute(h.url) };
1321
- }, [endpoint, effectiveBody, parameters, headers, baseUrl]);
1322
- return React12.useMemo(() => {
1323
- const target = chunk7EYHNP3E_cjs.CODE_SAMPLE_TARGETS.find((t) => t.id === activeId);
1324
- const code = chunk7EYHNP3E_cjs.renderSnippet(har, activeId);
1325
- return {
1326
- snippet: code ?? `// Snippet for ${target.label} is unavailable for this request.`,
1327
- prism: target.prism
1328
- };
1329
- }, [har, activeId]);
1330
- }
1331
- chunkOLISEQHS_cjs.__name(useCodeSnippet, "useCodeSnippet");
1332
- function CodeSamples({ endpoint, body, parameters, headers, baseUrl }) {
1333
- const { endpointId } = useEndpointDocContext();
1334
- const activeId = useActiveCodeTab(endpointId);
1335
- const setCodeTab = useEndpointDocStore((s) => s.setCodeTab);
1336
- const { snippet, prism } = useCodeSnippet({
1337
- endpoint,
1338
- body,
1339
- parameters,
1340
- headers,
1341
- baseUrl,
1342
- activeId
1343
- });
1344
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2.5", children: [
1345
- /* @__PURE__ */ jsxRuntime.jsx(LanguageTabs, { activeId, onChange: (id) => setCodeTab(endpointId, id) }),
1346
- /* @__PURE__ */ jsxRuntime.jsx(
1347
- chunk7IYXZUJO_cjs.PrettyCode_default,
1348
- {
1349
- data: snippet,
1350
- language: prism,
1351
- isCompact: true,
1352
- maxLines: 20
1353
- }
1354
- )
1355
- ] });
1356
- }
1357
- chunkOLISEQHS_cjs.__name(CodeSamples, "CodeSamples");
1358
- function IconButton({ label, onClick, children, active }) {
1359
- return /* @__PURE__ */ jsxRuntime.jsxs(components.Tooltip, { children: [
1360
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1361
- "button",
1362
- {
1363
- type: "button",
1364
- onClick,
1365
- "aria-label": label,
1366
- className: lib.cn(
1367
- "shrink-0 h-6 w-6 inline-flex items-center justify-center rounded",
1368
- "text-muted-foreground/60 hover:text-foreground hover:bg-muted transition-colors",
1369
- active && "text-emerald-500 hover:text-emerald-500"
1370
- ),
1371
- children
1372
- }
1373
- ) }),
1374
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipContent, { side: "bottom", className: "text-[11px]", children: label })
1375
- ] });
1376
- }
1377
- chunkOLISEQHS_cjs.__name(IconButton, "IconButton");
1378
- function MetaActions({ anchor, presentSections }) {
1379
- const { endpointId } = useEndpointDocContext();
1380
- const expandAll = useEndpointDocStore((s) => s.expandAll);
1381
- const collapseAll = useEndpointDocStore((s) => s.collapseAll);
1382
- const openSections = useEndpointDocStore((s) => s.openSections);
1383
- const [linkCopied, setLinkCopied] = React12.useState(false);
1384
- const flashLink = React12.useCallback(() => {
1385
- setLinkCopied(true);
1386
- setTimeout(() => setLinkCopied(false), 1200);
1387
- }, []);
1388
- const mostlyOpen = React12.useMemo(() => {
1389
- if (presentSections.length === 0) return false;
1390
- let openCount = 0;
1391
- for (const sid of presentSections) {
1392
- if (openSections[sectionKey(endpointId, sid)]) openCount += 1;
1393
- }
1394
- return openCount > presentSections.length / 2;
1395
- }, [openSections, presentSections, endpointId]);
1396
- const copyLink = React12.useCallback(() => {
1397
- if (typeof window === "undefined") return;
1398
- const url = `${window.location.origin}${window.location.pathname}#${anchor}`;
1399
- void navigator.clipboard?.writeText(url).then(flashLink);
1400
- }, [anchor, flashLink]);
1401
- const toggleAll = React12.useCallback(() => {
1402
- if (mostlyOpen) collapseAll(endpointId, presentSections);
1403
- else expandAll(endpointId, presentSections);
1404
- }, [mostlyOpen, collapseAll, expandAll, endpointId, presentSections]);
1405
- const linkLabel = linkCopied ? "Copied!" : "Copy link to endpoint";
1406
- const linkIcon = linkCopied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3.5 w-3.5" });
1407
- const showToggleAll = presentSections.length >= 2;
1408
- const toggleAllLabel = mostlyOpen ? "Collapse all sections" : "Expand all sections";
1409
- const toggleAllIcon = mostlyOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsDownUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "h-3.5 w-3.5" });
1410
- const toggleAllNode = showToggleAll ? /* @__PURE__ */ jsxRuntime.jsx(IconButton, { label: toggleAllLabel, onClick: toggleAll, children: toggleAllIcon }) : null;
1411
- return /* @__PURE__ */ jsxRuntime.jsx(components.SafeTooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
1412
- /* @__PURE__ */ jsxRuntime.jsx(IconButton, { label: linkLabel, onClick: copyLink, active: linkCopied, children: linkIcon }),
1413
- toggleAllNode
1414
- ] }) });
1415
- }
1416
- chunkOLISEQHS_cjs.__name(MetaActions, "MetaActions");
1417
- function PathDisplay({ path }) {
1418
- return /* @__PURE__ */ jsxRuntime.jsx(
1419
- "code",
1420
- {
1421
- className: "block font-mono text-lg md:text-xl font-semibold text-foreground leading-tight",
1422
- style: { overflowWrap: "anywhere", wordBreak: "break-word" },
1423
- children: chunk7EYHNP3E_cjs.relativePath(path)
1424
- }
1425
- );
1426
- }
1427
- chunkOLISEQHS_cjs.__name(PathDisplay, "PathDisplay");
1428
- function EndpointHeader({
1429
- endpoint,
1430
- anchor,
1431
- isLoadedInPlayground,
1432
- onTryIt,
1433
- presentSections
1434
- }) {
1435
- const endpointMd = React12.useMemo(() => chunk7EYHNP3E_cjs.endpointToMarkdown(endpoint), [endpoint]);
1436
- const [aiCopied, setAiCopied] = React12.useState(false);
1437
- const onAiCopy = React12.useCallback(() => {
1438
- if (typeof window === "undefined") return;
1439
- void navigator.clipboard?.writeText(endpointMd).then(() => {
1440
- setAiCopied(true);
1441
- setTimeout(() => setAiCopied(false), 1200);
1442
- });
1443
- }, [endpointMd]);
1444
- const tryItLabel = isLoadedInPlayground ? "Loaded" : "Try it";
1445
- const aiCopyIcon = aiCopied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" });
1446
- const aiCopyLabel = aiCopied ? "Copied" : "AI Copy";
1447
- const descriptionNode = endpoint.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(chunk7IYXZUJO_cjs.MarkdownMessage, { content: endpoint.description }) }) : null;
1448
- return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-3", children: [
1449
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
1450
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
1451
- /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: endpoint.method }),
1452
- /* @__PURE__ */ jsxRuntime.jsx(MetaActions, { anchor, presentSections })
1453
- ] }),
1454
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
1455
- /* @__PURE__ */ jsxRuntime.jsxs(
1456
- components.Button,
1457
- {
1458
- size: "sm",
1459
- variant: "secondary",
1460
- onClick: onAiCopy,
1461
- title: "Copy endpoint as Markdown for AI",
1462
- "aria-label": "Copy endpoint as Markdown for AI",
1463
- className: "h-7 text-xs gap-1.5 px-2.5",
1464
- children: [
1465
- aiCopyIcon,
1466
- aiCopyLabel
1467
- ]
1468
- }
1469
- ),
1470
- /* @__PURE__ */ jsxRuntime.jsxs(
1471
- components.Button,
1472
- {
1473
- size: "sm",
1474
- variant: isLoadedInPlayground ? "secondary" : "default",
1475
- onClick: onTryIt,
1476
- className: "h-7 text-xs gap-1.5 px-2.5",
1477
- children: [
1478
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-3 w-3" }),
1479
- tryItLabel
1480
- ]
1481
- }
1482
- )
1483
- ] })
1484
- ] }),
1485
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(PathDisplay, { path: endpoint.path }) }),
1486
- descriptionNode
1487
- ] });
1488
- }
1489
- chunkOLISEQHS_cjs.__name(EndpointHeader, "EndpointHeader");
1490
- function ParamRow({ param }) {
1491
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2.5 bg-background space-y-1", children: [
1492
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
1493
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs font-medium text-foreground", children: param.name }),
1494
- param.required && /* @__PURE__ */ jsxRuntime.jsx(
1495
- "span",
1496
- {
1497
- title: "Required",
1498
- className: "text-[9px] text-destructive font-bold leading-none",
1499
- children: "*"
1500
- }
1501
- ),
1502
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/70", children: param.type })
1503
- ] }),
1504
- param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed break-words", children: param.description })
1505
- ] });
1506
- }
1507
- chunkOLISEQHS_cjs.__name(ParamRow, "ParamRow");
1508
- function ParamGroup({ label, params }) {
1509
- if (params.length === 0) return null;
1510
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1511
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-muted-foreground/60 px-1", children: label }),
1512
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: params.map((p) => /* @__PURE__ */ jsxRuntime.jsx(ParamRow, { param: p }, `${label}-${p.name}`)) })
1513
- ] });
1514
- }
1515
- chunkOLISEQHS_cjs.__name(ParamGroup, "ParamGroup");
1516
- function Parameters({ pathParams, queryParams }) {
1517
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
1518
- /* @__PURE__ */ jsxRuntime.jsx(ParamGroup, { label: "Path", params: pathParams }),
1519
- /* @__PURE__ */ jsxRuntime.jsx(ParamGroup, { label: "Query", params: queryParams })
1520
- ] });
1521
- }
1522
- chunkOLISEQHS_cjs.__name(Parameters, "Parameters");
1523
-
1524
- // src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts
1525
- var MAX_DEPTH = 5;
1526
- function mergeAllOf(branches) {
1527
- const properties = {};
1528
- const required = [];
1529
- for (const b of branches) {
1530
- if (b.properties) Object.assign(properties, b.properties);
1531
- if (Array.isArray(b.required)) required.push(...b.required);
1532
- }
1533
- return { type: "object", properties, required };
1534
- }
1535
- chunkOLISEQHS_cjs.__name(mergeAllOf, "mergeAllOf");
1536
- function describeType(node) {
1537
- if (node.type === "array") {
1538
- const itemLabel = node.items ? describeType(node.items).label : "any";
1539
- return { label: `array<${itemLabel}>`, kind: "array" };
1540
- }
1541
- if (node.type === "object" || node.properties) {
1542
- return { label: "object", kind: "object" };
1543
- }
1544
- const base = node.type || "any";
1545
- if (Array.isArray(node.enum) && node.enum.length > 0) {
1546
- return { label: `${base} enum`, kind: "primitive" };
1547
- }
1548
- if (node.format) {
1549
- return { label: `${base} (${node.format})`, kind: "primitive" };
1550
- }
1551
- return { label: base, kind: "primitive" };
1552
- }
1553
- chunkOLISEQHS_cjs.__name(describeType, "describeType");
1554
- function resolveCombinators(node) {
1555
- if (Array.isArray(node.allOf) && node.allOf.length > 0) {
1556
- return { ...mergeAllOf(node.allOf), description: node.description };
1557
- }
1558
- if (Array.isArray(node.oneOf) && node.oneOf.length > 0) {
1559
- return { ...node.oneOf[0], description: node.description ?? node.oneOf[0].description };
1560
- }
1561
- if (Array.isArray(node.anyOf) && node.anyOf.length > 0) {
1562
- return { ...node.anyOf[0], description: node.description ?? node.anyOf[0].description };
1563
- }
1564
- return node;
1565
- }
1566
- chunkOLISEQHS_cjs.__name(resolveCombinators, "resolveCombinators");
1567
- function buildNode(name, schema, isRequired, depth) {
1568
- const resolved = resolveCombinators(schema);
1569
- const { label, kind } = describeType(resolved);
1570
- const node = {
1571
- name,
1572
- type: label,
1573
- kind,
1574
- required: isRequired,
1575
- description: resolved.description
1576
- };
1577
- if (Array.isArray(resolved.enum) && resolved.enum.length > 0) {
1578
- node.enumValues = resolved.enum.map((v) => String(v));
1579
- }
1580
- if (depth >= MAX_DEPTH) return node;
1581
- if (kind === "object" && resolved.properties) {
1582
- const required = new Set(resolved.required ?? []);
1583
- node.children = Object.entries(resolved.properties).map(
1584
- ([key, child]) => buildNode(key, child, required.has(key), depth + 1)
1585
- );
1586
- } else if (kind === "array" && resolved.items) {
1587
- node.children = [buildNode("[]", resolved.items, false, depth + 1)];
1588
- }
1589
- return node;
1590
- }
1591
- chunkOLISEQHS_cjs.__name(buildNode, "buildNode");
1592
- function buildSchemaTree(schema) {
1593
- if (!schema) return [];
1594
- const root = buildNode("", schema, false, 0);
1595
- if (root.children && root.children.length > 0) return root.children;
1596
- if (root.kind === "primitive" || !root.children && root.name === "") {
1597
- return [{ ...root, name: root.name || "(body)" }];
1598
- }
1599
- return [];
1600
- }
1601
- chunkOLISEQHS_cjs.__name(buildSchemaTree, "buildSchemaTree");
1602
- function FieldRow({ field, depth, showTreeLine = true }) {
1603
- const isExpandable = (field.kind === "object" || field.kind === "array") && Array.isArray(field.children) && field.children.length > 0;
1604
- const [open, setOpen] = React12.useState(depth < 2);
1605
- const padLeft = showTreeLine ? depth * 14 : 0;
1606
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-background", children: [
1607
- /* @__PURE__ */ jsxRuntime.jsxs(
1608
- "div",
1609
- {
1610
- className: lib.cn(
1611
- "grid grid-cols-[16px_minmax(0,1fr)] items-baseline gap-2 px-3 py-2",
1612
- isExpandable && "cursor-pointer hover:bg-muted/30"
1613
- ),
1614
- style: { paddingLeft: 12 + padLeft },
1615
- onClick: () => isExpandable && setOpen((v) => !v),
1616
- role: isExpandable ? "button" : void 0,
1617
- "aria-expanded": isExpandable ? open : void 0,
1618
- children: [
1619
- /* @__PURE__ */ jsxRuntime.jsx(
1620
- lucideReact.ChevronRight,
1621
- {
1622
- className: lib.cn(
1623
- "h-3.5 w-3.5 text-muted-foreground/50 shrink-0 transition-transform",
1624
- !isExpandable && "opacity-0",
1625
- open && "rotate-90"
1626
- )
1627
- }
1628
- ),
1629
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-1", children: [
1630
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
1631
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-xs font-medium text-foreground", children: field.name }),
1632
- field.required && /* @__PURE__ */ jsxRuntime.jsx(
1633
- "span",
1634
- {
1635
- title: "Required",
1636
- className: "text-[9px] text-destructive font-bold leading-none",
1637
- children: "*"
1638
- }
1639
- ),
1640
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/70", children: field.type })
1641
- ] }),
1642
- field.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed break-words", children: field.description }),
1643
- field.enumValues && field.enumValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 pt-0.5", children: field.enumValues.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
1644
- "code",
1645
- {
1646
- className: "inline-flex items-center rounded border border-border/60 bg-muted/40 px-1.5 py-px font-mono text-[10px] text-muted-foreground",
1647
- children: v
1648
- },
1649
- v
1650
- )) })
1651
- ] })
1652
- ]
1653
- }
1654
- ),
1655
- isExpandable && open && /* @__PURE__ */ jsxRuntime.jsx("div", { children: field.children.map((child, i) => /* @__PURE__ */ jsxRuntime.jsx(
1656
- FieldRow,
1657
- {
1658
- field: child,
1659
- depth: depth + 1
1660
- },
1661
- `${child.name}-${i}`
1662
- )) })
1663
- ] });
1664
- }
1665
- chunkOLISEQHS_cjs.__name(FieldRow, "FieldRow");
1666
- function SchemaFields({ schema }) {
1667
- const tree = React12.useMemo(() => buildSchemaTree(schema), [schema]);
1668
- if (tree.length === 0) return null;
1669
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: tree.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { field: node, depth: 0 }, `${node.name}-${i}`)) });
1670
- }
1671
- chunkOLISEQHS_cjs.__name(SchemaFields, "SchemaFields");
1672
- function RequestBody({ body }) {
1673
- const typeLabel = body.schema ? body.type === "array" ? `array<${body.schema.items?.type ?? "object"}>` : body.type : body.type;
1674
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1675
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
1676
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground/80", children: typeLabel }),
1677
- body.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: body.description })
1678
- ] }),
1679
- body.schema && /* @__PURE__ */ jsxRuntime.jsx(SchemaFields, { schema: body.schema })
1680
- ] });
1681
- }
1682
- chunkOLISEQHS_cjs.__name(RequestBody, "RequestBody");
1683
- var EXAMPLE_JSON_TREE_CONFIG = {
1684
- maxAutoExpandDepth: 2,
1685
- maxAutoExpandArrayItems: 5,
1686
- maxAutoExpandObjectKeys: 8,
1687
- maxStringLength: 160,
1688
- collectionLimit: 25,
1689
- showCollectionInfo: true,
1690
- showExpandControls: false,
1691
- showActionButtons: false,
1692
- preserveKeyOrder: true,
1693
- className: "border-0 rounded-none"
1694
- };
1695
- function ResponseBody({ example, contentType }) {
1696
- const parsed = React12.useMemo(() => {
1697
- try {
1698
- return JSON.parse(example);
1699
- } catch {
1700
- return null;
1701
- }
1702
- }, [example]);
1703
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t bg-muted/20", children: [
1704
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-3 py-1.5 border-b border-border/50", children: [
1705
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[10px] uppercase tracking-wider text-muted-foreground/70", children: contentType ?? "application/json" }),
1706
- /* @__PURE__ */ jsxRuntime.jsx(
1707
- components.CopyButton,
1708
- {
1709
- value: example,
1710
- variant: "ghost",
1711
- size: "sm",
1712
- className: "h-6 px-2 text-[10px] text-muted-foreground",
1713
- children: "Copy"
1714
- }
1715
- )
1716
- ] }),
1717
- parsed != null ? /* @__PURE__ */ jsxRuntime.jsx(
1718
- chunkT3MWM23F_cjs.JsonTree_default,
1719
- {
1720
- title: "",
1721
- data: parsed,
1722
- mode: "compact",
1723
- config: EXAMPLE_JSON_TREE_CONFIG
1724
- }
1725
- ) : /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-3 text-[11px] font-mono text-foreground/70 whitespace-pre-wrap break-all leading-relaxed", children: example })
1726
- ] });
1727
- }
1728
- chunkOLISEQHS_cjs.__name(ResponseBody, "ResponseBody");
1729
- function StatusTag({ code }) {
1730
- const numeric = Number.parseInt(code, 10);
1731
- 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";
1732
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: lib.cn(
1733
- "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",
1734
- cls
1735
- ), children: code });
1736
- }
1737
- chunkOLISEQHS_cjs.__name(StatusTag, "StatusTag");
1738
- function ResponseRow({ response }) {
1739
- const hasExample = Boolean(response.example);
1740
- const numeric = Number.parseInt(response.code, 10);
1741
- const isSuccess = Number.isFinite(numeric) && numeric >= 200 && numeric < 300;
1742
- const [open, setOpen] = React12.useState(hasExample && isSuccess);
1743
- if (!hasExample) {
1744
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 px-3 py-2 bg-background", children: [
1745
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 shrink-0 flex justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { code: response.code }) }),
1746
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground leading-relaxed break-words min-w-0", children: response.description })
1747
- ] });
1748
- }
1749
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-background", children: [
1750
- /* @__PURE__ */ jsxRuntime.jsxs(
1751
- "button",
1752
- {
1753
- type: "button",
1754
- onClick: () => setOpen((v) => !v),
1755
- className: "w-full flex items-center gap-3 px-3 py-2 text-left hover:bg-muted/40 cursor-pointer transition-colors",
1756
- "aria-expanded": open,
1757
- children: [
1758
- /* @__PURE__ */ jsxRuntime.jsx(
1759
- lucideReact.ChevronRight,
1760
- {
1761
- className: lib.cn(
1762
- "h-3.5 w-3.5 text-muted-foreground/60 transition-transform shrink-0",
1763
- open && "rotate-90"
1764
- )
1765
- }
1766
- ),
1767
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 shrink-0 flex justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { code: response.code }) }),
1768
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground leading-relaxed break-words min-w-0 flex-1", children: response.description })
1769
- ]
1770
- }
1771
- ),
1772
- open && /* @__PURE__ */ jsxRuntime.jsx(
1773
- ResponseBody,
1774
- {
1775
- example: response.example,
1776
- contentType: response.contentType
1777
- }
1778
- )
1779
- ] });
1780
- }
1781
- chunkOLISEQHS_cjs.__name(ResponseRow, "ResponseRow");
1782
- function Responses({ responses }) {
1783
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y border rounded-md overflow-hidden", children: responses.map((r) => /* @__PURE__ */ jsxRuntime.jsx(ResponseRow, { response: r }, r.code)) });
1784
- }
1785
- chunkOLISEQHS_cjs.__name(Responses, "Responses");
1786
-
1787
- // src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/Section/defaults.ts
1788
- var DEFAULTS_BY_METHOD = {
1789
- GET: { parameters: true, responses: true },
1790
- DELETE: { parameters: true, responses: true },
1791
- POST: { requestBody: true, responses: true },
1792
- PUT: { requestBody: true, responses: true },
1793
- PATCH: { requestBody: true, responses: true }
1794
- };
1795
- function defaultSectionOpen(method, sectionId) {
1796
- return DEFAULTS_BY_METHOD[method.toUpperCase()]?.[sectionId] ?? false;
1797
- }
1798
- chunkOLISEQHS_cjs.__name(defaultSectionOpen, "defaultSectionOpen");
1799
-
1800
- // src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/types.ts
1801
- var ALL_SECTION_IDS = [
1802
- "parameters",
1803
- "requestBody",
1804
- "responses",
1805
- "codeSamples"
1806
- ];
1807
-
1808
- // src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/hooks/useSectionHash.ts
1809
- function parseSectionHash(hash) {
1810
- const raw = hash.startsWith("#") ? hash.slice(1) : hash;
1811
- if (!raw.startsWith("section=")) return null;
1812
- const value = raw.slice("section=".length);
1813
- const dot = value.lastIndexOf(".");
1814
- if (dot <= 0 || dot === value.length - 1) return null;
1815
- const endpointId = value.slice(0, dot);
1816
- const sectionIdCandidate = value.slice(dot + 1);
1817
- if (!ALL_SECTION_IDS.includes(sectionIdCandidate)) return null;
1818
- return { endpointId, sectionId: sectionIdCandidate };
1819
- }
1820
- chunkOLISEQHS_cjs.__name(parseSectionHash, "parseSectionHash");
1821
- function buildSectionHash(endpointId, sectionId) {
1822
- return `section=${endpointId}.${sectionId}`;
1823
- }
1824
- chunkOLISEQHS_cjs.__name(buildSectionHash, "buildSectionHash");
1825
- function useSectionHashRouter() {
1826
- const setSectionOpen = useEndpointDocStore((s) => s.setSectionOpen);
1827
- React12.useEffect(() => {
1828
- if (typeof window === "undefined") return;
1829
- function apply() {
1830
- const parsed = parseSectionHash(window.location.hash);
1831
- if (!parsed) return;
1832
- setSectionOpen(parsed.endpointId, parsed.sectionId, true);
1833
- requestAnimationFrame(() => {
1834
- const el = document.getElementById(parsed.endpointId);
1835
- el?.scrollIntoView({ behavior: "smooth", block: "start" });
1836
- });
1837
- }
1838
- chunkOLISEQHS_cjs.__name(apply, "apply");
1839
- apply();
1840
- window.addEventListener("hashchange", apply);
1841
- return () => window.removeEventListener("hashchange", apply);
1842
- }, [setSectionOpen]);
1843
- }
1844
- chunkOLISEQHS_cjs.__name(useSectionHashRouter, "useSectionHashRouter");
1845
- function SectionHeader({ sectionId, title, badge, open, onToggle }) {
1846
- const { endpointId } = useEndpointDocContext();
1847
- const [copied, setCopied] = React12.useState(false);
1848
- const copyHash = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((e) => {
1849
- e.stopPropagation();
1850
- if (typeof window === "undefined") return;
1851
- const hash = buildSectionHash(endpointId, sectionId);
1852
- const url = `${window.location.origin}${window.location.pathname}#${hash}`;
1853
- void navigator.clipboard?.writeText(url).then(() => {
1854
- setCopied(true);
1855
- setTimeout(() => setCopied(false), 1200);
1856
- });
1857
- }, "copyHash");
1858
- return /* @__PURE__ */ jsxRuntime.jsxs(
1859
- "div",
1860
- {
1861
- className: lib.cn(
1862
- "group/section w-full flex items-center gap-2 py-1.5 -ml-1 px-1 rounded cursor-pointer",
1863
- "hover:bg-muted/30 transition-colors"
1864
- ),
1865
- onClick: onToggle,
1866
- role: "button",
1867
- "aria-expanded": open,
1868
- tabIndex: 0,
1869
- onKeyDown: (e) => {
1870
- if (e.key === "Enter" || e.key === " ") {
1871
- e.preventDefault();
1872
- onToggle();
1873
- }
1874
- },
1875
- children: [
1876
- /* @__PURE__ */ jsxRuntime.jsx(
1877
- lucideReact.ChevronDown,
1878
- {
1879
- className: lib.cn(
1880
- "h-3.5 w-3.5 text-muted-foreground/50 transition-transform shrink-0",
1881
- !open && "-rotate-90"
1882
- )
1883
- }
1884
- ),
1885
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground/80", children: title }),
1886
- typeof badge === "number" && badge > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50 tabular-nums", children: badge }),
1887
- /* @__PURE__ */ jsxRuntime.jsx(
1888
- "button",
1889
- {
1890
- type: "button",
1891
- onClick: copyHash,
1892
- title: "Copy link to this section",
1893
- className: lib.cn(
1894
- "ml-auto shrink-0 p-1 rounded text-muted-foreground/40 hover:text-foreground hover:bg-muted transition-all",
1895
- "opacity-0 group-hover/section:opacity-100 focus-visible:opacity-100",
1896
- copied && "opacity-100 text-emerald-500"
1897
- ),
1898
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-3 w-3" })
1899
- }
1900
- )
1901
- ]
1902
- }
1903
- );
1904
- }
1905
- chunkOLISEQHS_cjs.__name(SectionHeader, "SectionHeader");
1906
- function Section({ id, title, badge, children }) {
1907
- const { endpointId, method } = useEndpointDocContext();
1908
- const defaultOpen = defaultSectionOpen(method, id);
1909
- const open = useIsSectionOpen(endpointId, id, defaultOpen);
1910
- const toggleSection = useEndpointDocStore((s) => s.toggleSection);
1911
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2.5", children: [
1912
- /* @__PURE__ */ jsxRuntime.jsx(
1913
- SectionHeader,
1914
- {
1915
- sectionId: id,
1916
- title,
1917
- badge,
1918
- open,
1919
- onToggle: () => toggleSection(endpointId, id, defaultOpen)
1920
- }
1921
- ),
1922
- open && /* @__PURE__ */ jsxRuntime.jsx("div", { children })
1923
- ] });
1924
- }
1925
- chunkOLISEQHS_cjs.__name(Section, "Section");
1926
- function EndpointDoc({ endpoint, isLoadedInPlayground, onTryIt, schemaId }) {
1927
- const scopedSchemaId = schemaId ?? endpoint.schemaId ?? null;
1928
- const anchor = endpointAnchor(endpoint, scopedSchemaId);
1929
- const pathParams = endpoint.parameters?.filter((p) => endpoint.path.includes(`{${p.name}}`)) ?? [];
1930
- const queryParams = endpoint.parameters?.filter((p) => !endpoint.path.includes(`{${p.name}}`)) ?? [];
1931
- const hasParameters = pathParams.length > 0 || queryParams.length > 0;
1932
- const hasResponses = (endpoint.responses?.length ?? 0) > 0;
1933
- const presentSections = [];
1934
- if (hasParameters) presentSections.push("parameters");
1935
- if (endpoint.requestBody) presentSections.push("requestBody");
1936
- presentSections.push("codeSamples");
1937
- if (hasResponses) presentSections.push("responses");
1938
- return /* @__PURE__ */ jsxRuntime.jsx(EndpointDocProvider, { endpointId: anchor, method: endpoint.method, children: /* @__PURE__ */ jsxRuntime.jsxs(
1939
- "section",
1940
- {
1941
- id: anchor,
1942
- "data-endpoint-anchor": anchor,
1943
- "data-schema-id": scopedSchemaId ?? "",
1944
- className: "scroll-mt-24 py-10 first:pt-0",
1945
- children: [
1946
- /* @__PURE__ */ jsxRuntime.jsx(
1947
- EndpointHeader,
1948
- {
1949
- endpoint,
1950
- anchor,
1951
- isLoadedInPlayground,
1952
- onTryIt,
1953
- presentSections
1954
- }
1955
- ),
1956
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 space-y-5", children: [
1957
- hasParameters && /* @__PURE__ */ jsxRuntime.jsx(
1958
- Section,
1959
- {
1960
- id: "parameters",
1961
- title: "Parameters",
1962
- badge: pathParams.length + queryParams.length,
1963
- children: /* @__PURE__ */ jsxRuntime.jsx(Parameters, { pathParams, queryParams })
1964
- }
1965
- ),
1966
- endpoint.requestBody && /* @__PURE__ */ jsxRuntime.jsx(Section, { id: "requestBody", title: "Request body", children: /* @__PURE__ */ jsxRuntime.jsx(RequestBody, { body: endpoint.requestBody }) }),
1967
- /* @__PURE__ */ jsxRuntime.jsx(Section, { id: "codeSamples", title: "Code samples", children: /* @__PURE__ */ jsxRuntime.jsx(CodeSamples, { endpoint }) }),
1968
- hasResponses && /* @__PURE__ */ jsxRuntime.jsx(
1969
- Section,
1970
- {
1971
- id: "responses",
1972
- title: "Responses",
1973
- badge: endpoint.responses.length,
1974
- children: /* @__PURE__ */ jsxRuntime.jsx(Responses, { responses: endpoint.responses })
1975
- }
1976
- )
1977
- ] })
1978
- ]
1979
- }
1980
- ) });
1981
- }
1982
- chunkOLISEQHS_cjs.__name(EndpointDoc, "EndpointDoc");
1983
- var readNavbarOffset = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
1984
- if (typeof document === "undefined") return 0;
1985
- const raw = getComputedStyle(document.documentElement).getPropertyValue("--navbar-height");
1986
- const parsed = parseInt(raw || "", 10);
1987
- return Number.isFinite(parsed) ? parsed : 0;
1988
- }, "readNavbarOffset");
1989
- var isSameEndpoint = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((a, b) => a !== null && a.method === b.method && a.path === b.path, "isSameEndpoint");
1990
- function buildEndpointRow(ep, loadedEndpoint, schemaId) {
1991
- const keySchema = schemaId ? `${schemaId}-` : "";
1992
- return {
1993
- key: `${keySchema}${ep.method}-${ep.path}`,
1994
- endpoint: ep,
1995
- isLoaded: isSameEndpoint(loadedEndpoint, ep),
1996
- schemaId
1997
- };
1998
- }
1999
- chunkOLISEQHS_cjs.__name(buildEndpointRow, "buildEndpointRow");
2000
- function buildSchemaSectionVM(entry, selectedVersion, loadedEndpoint) {
2001
- const title = entry.info?.title ?? entry.source.name;
2002
- const version = entry.info?.version ?? null;
2003
- const description = entry.info?.description ?? null;
2004
- let state;
2005
- if (entry.loading) {
2006
- state = { kind: "loading" };
2007
- } else if (entry.error) {
2008
- state = { kind: "error", message: entry.error };
2009
- } else {
2010
- const visible = chunk7EYHNP3E_cjs.deduplicateEndpoints(entry.endpoints, selectedVersion);
2011
- state = visible.length === 0 ? { kind: "empty" } : {
2012
- kind: "ready",
2013
- rows: visible.map((ep) => buildEndpointRow(ep, loadedEndpoint, entry.source.id))
2014
- };
2015
- }
2016
- return {
2017
- schemaId: entry.source.id,
2018
- title,
2019
- version,
2020
- description,
2021
- state,
2022
- rawSchema: entry.rawSchema,
2023
- baseUrl: entry.resolvedBaseUrl,
2024
- allEndpoints: entry.endpoints
2025
- };
2026
- }
2027
- chunkOLISEQHS_cjs.__name(buildSchemaSectionVM, "buildSchemaSectionVM");
2028
- var DocsView = React12__default.default.forwardRef(/* @__PURE__ */ chunkOLISEQHS_cjs.__name(function DocsView2(props, ref) {
2029
- const scrollRef = React12.useRef(null);
2030
- const scrollTargetRef = React12.useRef(null);
2031
- const { onActiveChange } = props;
2032
- useSectionHashRouter();
2033
- const ensureScrollTarget = React12.useCallback(() => {
2034
- if (scrollTargetRef.current) return scrollTargetRef.current;
2035
- if (!scrollRef.current) return null;
2036
- scrollTargetRef.current = getScrollParent(scrollRef.current);
2037
- return scrollTargetRef.current;
2038
- }, []);
2039
- const scrollToAnchor = React12.useCallback(
2040
- (anchor) => {
2041
- const root = scrollRef.current;
2042
- if (!root) return;
2043
- const el = root.querySelector(`[data-endpoint-anchor="${anchor}"]`);
2044
- if (!el) return;
2045
- const target = ensureScrollTarget();
2046
- if (!target) return;
2047
- const navbar = readNavbarOffset();
2048
- const top = el.getBoundingClientRect().top - getTargetTop(target) + getScrollTop(target) - navbar - 8;
2049
- scrollTargetTo(target, top);
2050
- },
2051
- [ensureScrollTarget]
2052
- );
2053
- React12__default.default.useImperativeHandle(ref, () => ({ scrollToAnchor }), [scrollToAnchor]);
2054
- React12.useEffect(() => {
2055
- const root = scrollRef.current;
2056
- if (!root) return;
2057
- const target = ensureScrollTarget();
2058
- if (!target) return;
2059
- let rafId = 0;
2060
- let lastActive = null;
2061
- const compute = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2062
- rafId = 0;
2063
- const sections = root.querySelectorAll("[data-endpoint-anchor]");
2064
- if (sections.length === 0) return;
2065
- const navbar = readNavbarOffset();
2066
- const viewportTop = getTargetTop(target);
2067
- const threshold = viewportTop + navbar + getViewportHeight(target) * 0.25;
2068
- let active = null;
2069
- for (const s of Array.from(sections)) {
2070
- const top = s.getBoundingClientRect().top;
2071
- if (top <= threshold) {
2072
- active = s;
2073
- } else {
2074
- break;
2075
- }
2076
- }
2077
- const anchor = active?.dataset.endpointAnchor ?? null;
2078
- if (anchor !== lastActive) {
2079
- lastActive = anchor;
2080
- onActiveChange(anchor, active?.dataset.schemaId || null);
2081
- }
2082
- }, "compute");
2083
- const onScroll = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2084
- if (rafId) return;
2085
- rafId = requestAnimationFrame(compute);
2086
- }, "onScroll");
2087
- compute();
2088
- target.addEventListener("scroll", onScroll, { passive: true });
2089
- window.addEventListener("resize", onScroll, { passive: true });
2090
- return () => {
2091
- target.removeEventListener("scroll", onScroll);
2092
- window.removeEventListener("resize", onScroll);
2093
- if (rafId) cancelAnimationFrame(rafId);
2094
- };
2095
- }, [onActiveChange, ensureScrollTarget, props]);
2096
- if (props.grouping === "sections") {
2097
- return /* @__PURE__ */ jsxRuntime.jsx(SectionsBody, { scrollRef, ...props });
2098
- }
2099
- return /* @__PURE__ */ jsxRuntime.jsx(SelectorBody, { scrollRef, ...props });
2100
- }, "DocsView"));
2101
- function SelectorBody({
2102
- scrollRef,
2103
- info,
2104
- rawSchema,
2105
- resolvedBaseUrl,
2106
- endpoints,
2107
- selectedVersion,
2108
- loadedEndpoint,
2109
- onTryEndpoint
2110
- }) {
2111
- const visibleEndpoints = React12.useMemo(
2112
- () => chunk7EYHNP3E_cjs.deduplicateEndpoints(endpoints, selectedVersion),
2113
- [endpoints, selectedVersion]
2114
- );
2115
- const rows = React12.useMemo(
2116
- () => visibleEndpoints.map((ep) => buildEndpointRow(ep, loadedEndpoint, ep.schemaId ?? null)),
2117
- [visibleEndpoints, loadedEndpoint]
2118
- );
2119
- const isEmpty = rows.length === 0;
2120
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12", children: [
2121
- info && /* @__PURE__ */ jsxRuntime.jsx(
2122
- ApiIntroSection,
2123
- {
2124
- info,
2125
- schema: rawSchema,
2126
- endpoints: visibleEndpoints,
2127
- resolvedBaseUrl
2128
- }
2129
- ),
2130
- isEmpty ? /* @__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: rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
2131
- EndpointDoc,
2132
- {
2133
- endpoint: row.endpoint,
2134
- isLoadedInPlayground: row.isLoaded,
2135
- onTryIt: () => onTryEndpoint(row.endpoint),
2136
- schemaId: row.schemaId
2137
- },
2138
- row.key
2139
- )) })
2140
- ] }) });
2141
- }
2142
- chunkOLISEQHS_cjs.__name(SelectorBody, "SelectorBody");
2143
- function SectionsBody({
2144
- scrollRef,
2145
- schemasData,
2146
- selectedVersion,
2147
- loadedEndpoint,
2148
- onTryEndpoint
2149
- }) {
2150
- const sections = React12.useMemo(
2151
- () => schemasData.map((e) => buildSchemaSectionVM(e, selectedVersion, loadedEndpoint)),
2152
- [schemasData, selectedVersion, loadedEndpoint]
2153
- );
2154
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12 space-y-16", children: sections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(SchemaSectionView, { section, onTryEndpoint }, section.schemaId)) }) });
2155
- }
2156
- chunkOLISEQHS_cjs.__name(SectionsBody, "SectionsBody");
2157
- var SchemaSectionView = React12__default.default.memo(/* @__PURE__ */ chunkOLISEQHS_cjs.__name(function SchemaSectionView2({
2158
- section,
2159
- onTryEndpoint
2160
- }) {
2161
- const canCopy = section.rawSchema !== null && section.allEndpoints.length > 0;
2162
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { "data-schema-anchor": section.schemaId, className: "scroll-mt-20", children: [
2163
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "mb-8 pb-4 border-b", children: [
2164
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
2165
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-3 min-w-0", children: [
2166
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: section.title }),
2167
- section.version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-xs text-muted-foreground/70", children: [
2168
- "v",
2169
- section.version
2170
- ] })
2171
- ] }),
2172
- canCopy && /* @__PURE__ */ jsxRuntime.jsx(
2173
- SchemaCopyMenu,
2174
- {
2175
- schema: section.rawSchema,
2176
- endpoints: section.allEndpoints,
2177
- baseUrl: section.baseUrl
2178
- }
2179
- )
2180
- ] }),
2181
- section.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground whitespace-pre-wrap", children: section.description })
2182
- ] }),
2183
- /* @__PURE__ */ jsxRuntime.jsx(SchemaSectionStateView, { section, onTryEndpoint })
2184
- ] });
2185
- }, "SchemaSectionView"));
2186
- function SchemaSectionStateView({
2187
- section,
2188
- onTryEndpoint
2189
- }) {
2190
- switch (section.state.kind) {
2191
- case "loading":
2192
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-8 text-center text-sm text-muted-foreground", children: [
2193
- "Loading ",
2194
- section.title,
2195
- "\u2026"
2196
- ] });
2197
- case "error":
2198
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-8 text-center text-sm text-destructive", children: [
2199
- "Failed to load ",
2200
- section.title,
2201
- ": ",
2202
- section.state.message
2203
- ] });
2204
- case "empty":
2205
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground", children: "No endpoints in this schema." });
2206
- case "ready":
2207
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/60", children: section.state.rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
2208
- EndpointDoc,
2209
- {
2210
- endpoint: row.endpoint,
2211
- isLoadedInPlayground: row.isLoaded,
2212
- onTryIt: () => onTryEndpoint(row.endpoint),
2213
- schemaId: row.schemaId
2214
- },
2215
- row.key
2216
- )) });
2217
- }
2218
- }
2219
- chunkOLISEQHS_cjs.__name(SchemaSectionStateView, "SchemaSectionStateView");
2220
- var MAX_DEPTH2 = 6;
2221
- function defaultForSchema(schema) {
2222
- if (!schema) return null;
2223
- if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
2224
- switch (schema.type) {
2225
- case "object": {
2226
- const out = {};
2227
- for (const [k, v] of Object.entries(schema.properties ?? {})) {
2228
- out[k] = defaultForSchema(v);
2229
- }
2230
- return out;
2231
- }
2232
- case "array":
2233
- return [];
2234
- case "integer":
2235
- case "number":
2236
- return 0;
2237
- case "boolean":
2238
- return false;
2239
- case "string":
2240
- return "";
2241
- default:
2242
- if (schema.properties) {
2243
- const out = {};
2244
- for (const [k, v] of Object.entries(schema.properties)) {
2245
- out[k] = defaultForSchema(v);
2246
- }
2247
- return out;
2248
- }
2249
- return "";
2250
- }
2251
- }
2252
- chunkOLISEQHS_cjs.__name(defaultForSchema, "defaultForSchema");
2253
- function BodyFormEditor({ schema, value, onChange }) {
2254
- return /* @__PURE__ */ jsxRuntime.jsx(
2255
- SchemaField,
2256
- {
2257
- schema,
2258
- value,
2259
- onChange,
2260
- depth: 0,
2261
- required: false
2262
- }
2263
- );
2264
- }
2265
- chunkOLISEQHS_cjs.__name(BodyFormEditor, "BodyFormEditor");
2266
- function SchemaField({ schema, value, onChange, depth, required, label }) {
2267
- if (depth > MAX_DEPTH2) {
2268
- return /* @__PURE__ */ jsxRuntime.jsx(RawJsonField, { label, value, onChange });
2269
- }
2270
- if (Array.isArray(schema.enum) && schema.enum.length > 0) {
2271
- return /* @__PURE__ */ jsxRuntime.jsx(EnumField, { schema, value, onChange, label, required });
2272
- }
2273
- switch (schema.type) {
2274
- case "object":
2275
- return /* @__PURE__ */ jsxRuntime.jsx(ObjectField, { schema, value, onChange, depth, label });
2276
- case "array":
2277
- return /* @__PURE__ */ jsxRuntime.jsx(ArrayField, { schema, value, onChange, depth, label, required });
2278
- case "boolean":
2279
- return /* @__PURE__ */ jsxRuntime.jsx(BooleanField, { value, onChange, label, schema, required });
2280
- case "integer":
2281
- case "number":
2282
- return /* @__PURE__ */ jsxRuntime.jsx(NumberField, { value, onChange, label, schema, required });
2283
- case "string":
2284
- default:
2285
- if (!schema.type && schema.properties) {
2286
- return /* @__PURE__ */ jsxRuntime.jsx(ObjectField, { schema, value, onChange, depth, label });
2287
- }
2288
- return /* @__PURE__ */ jsxRuntime.jsx(StringField, { value, onChange, label, schema, required });
2289
- }
2290
- }
2291
- chunkOLISEQHS_cjs.__name(SchemaField, "SchemaField");
2292
- function FieldHeader({
2293
- label,
2294
- type,
2295
- required,
2296
- description
2297
- }) {
2298
- if (!label) return null;
2299
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
2300
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
2301
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
2302
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
2303
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: type })
2304
- ] }),
2305
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground/70 leading-snug", children: description })
2306
- ] });
2307
- }
2308
- chunkOLISEQHS_cjs.__name(FieldHeader, "FieldHeader");
2309
- function StringField({
2310
- value,
2311
- onChange,
2312
- label,
2313
- schema,
2314
- required
2315
- }) {
2316
- const stringValue = typeof value === "string" ? value : value == null ? "" : String(value);
2317
- const placeholder = schema.format ? `${schema.type ?? "string"} (${schema.format})` : schema.description || schema.type || "string";
2318
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2319
- /* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: schema.format ? `string (${schema.format})` : "string", required, description: schema.description }),
2320
- /* @__PURE__ */ jsxRuntime.jsx(
2321
- components.Input,
2322
- {
2323
- value: stringValue,
2324
- onChange: (e) => onChange(e.target.value),
2325
- placeholder,
2326
- className: "h-8 text-xs font-mono"
2327
- }
2328
- )
2329
- ] });
2330
- }
2331
- chunkOLISEQHS_cjs.__name(StringField, "StringField");
2332
- function NumberField({
2333
- value,
2334
- onChange,
2335
- label,
2336
- schema,
2337
- required
2338
- }) {
2339
- const raw = value == null ? "" : String(value);
2340
- const type = schema.type === "integer" ? "integer" : "number";
2341
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2342
- /* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: schema.format ? `${type} (${schema.format})` : type, required, description: schema.description }),
2343
- /* @__PURE__ */ jsxRuntime.jsx(
2344
- components.Input,
2345
- {
2346
- type: "number",
2347
- value: raw,
2348
- onChange: (e) => {
2349
- const v = e.target.value;
2350
- if (v === "") return onChange(null);
2351
- const n = schema.type === "integer" ? parseInt(v, 10) : parseFloat(v);
2352
- onChange(Number.isNaN(n) ? null : n);
2353
- },
2354
- placeholder: type,
2355
- className: "h-8 text-xs font-mono"
2356
- }
2357
- )
2358
- ] });
2359
- }
2360
- chunkOLISEQHS_cjs.__name(NumberField, "NumberField");
2361
- function BooleanField({
2362
- value,
2363
- onChange,
2364
- label,
2365
- schema,
2366
- required
2367
- }) {
2368
- const bool = value === true;
2369
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2370
- /* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: "boolean", required, description: schema.description }),
2371
- /* @__PURE__ */ jsxRuntime.jsx(components.Switch, { checked: bool, onCheckedChange: onChange, className: "mt-0.5 shrink-0" })
2372
- ] });
2373
- }
2374
- chunkOLISEQHS_cjs.__name(BooleanField, "BooleanField");
2375
- function EnumField({
2376
- schema,
2377
- value,
2378
- onChange,
2379
- label,
2380
- required
2381
- }) {
2382
- const options = (schema.enum ?? []).map((v) => ({
2383
- value: String(v),
2384
- label: String(v)
2385
- }));
2386
- const strValue = value == null ? "" : String(value);
2387
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2388
- /* @__PURE__ */ jsxRuntime.jsx(FieldHeader, { label, type: `${schema.type ?? "enum"} enum`, required, description: schema.description }),
2389
- /* @__PURE__ */ jsxRuntime.jsx(
2390
- components.Combobox,
2391
- {
2392
- options,
2393
- value: strValue,
2394
- onValueChange: (v) => {
2395
- if (schema.type === "integer") onChange(parseInt(v, 10));
2396
- else if (schema.type === "number") onChange(parseFloat(v));
2397
- else onChange(v);
2398
- },
2399
- placeholder: "Select\u2026",
2400
- searchPlaceholder: "Search\u2026",
2401
- className: "h-8 text-xs"
2402
- }
2403
- )
2404
- ] });
2405
- }
2406
- chunkOLISEQHS_cjs.__name(EnumField, "EnumField");
2407
- function RawJsonField({
2408
- label,
2409
- value,
2410
- onChange
2411
- }) {
2412
- const [text, setText] = React12__default.default.useState(() => JSON.stringify(value ?? null, null, 2));
2413
- React12__default.default.useEffect(() => {
2414
- setText(JSON.stringify(value ?? null, null, 2));
2415
- }, [value]);
2416
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2417
- label && /* @__PURE__ */ jsxRuntime.jsxs(SectionLabel, { children: [
2418
- label,
2419
- " (raw)"
2420
- ] }),
2421
- /* @__PURE__ */ jsxRuntime.jsx(
2422
- components.Textarea,
2423
- {
2424
- value: text,
2425
- onChange: (e) => {
2426
- setText(e.target.value);
2427
- try {
2428
- onChange(JSON.parse(e.target.value));
2429
- } catch {
2430
- }
2431
- },
2432
- className: "font-mono text-[11px] min-h-[80px]",
2433
- rows: 4
2434
- }
2435
- )
2436
- ] });
2437
- }
2438
- chunkOLISEQHS_cjs.__name(RawJsonField, "RawJsonField");
2439
- function ObjectField({
2440
- schema,
2441
- value,
2442
- onChange,
2443
- depth,
2444
- label
2445
- }) {
2446
- const obj = value && typeof value === "object" && !Array.isArray(value) ? value : {};
2447
- const required = new Set(schema.required ?? []);
2448
- const entries = Object.entries(schema.properties ?? {});
2449
- const setKey = React12.useCallback(
2450
- (key) => (next) => {
2451
- onChange({ ...obj, [key]: next });
2452
- },
2453
- [obj, onChange]
2454
- );
2455
- if (entries.length === 0) {
2456
- return /* @__PURE__ */ jsxRuntime.jsx(RawJsonField, { label, value: obj, onChange });
2457
- }
2458
- const wrapperClass = depth === 0 ? "space-y-3" : "space-y-2 border-l-2 border-border/60 pl-3 ml-px";
2459
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2460
- label && depth > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
2461
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
2462
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: "object" })
2463
- ] }),
2464
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: lib.cn(wrapperClass), children: entries.map(([key, subSchema]) => /* @__PURE__ */ jsxRuntime.jsx(
2465
- SchemaField,
2466
- {
2467
- schema: subSchema,
2468
- value: obj[key],
2469
- onChange: setKey(key),
2470
- depth: depth + 1,
2471
- required: required.has(key),
2472
- label: key
2473
- },
2474
- key
2475
- )) })
2476
- ] });
2477
- }
2478
- chunkOLISEQHS_cjs.__name(ObjectField, "ObjectField");
2479
- function ArrayField({
2480
- schema,
2481
- value,
2482
- onChange,
2483
- depth,
2484
- label,
2485
- required
2486
- }) {
2487
- const arr = Array.isArray(value) ? value : [];
2488
- const items = schema.items ?? { type: "string" };
2489
- const addItem = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => onChange([...arr, defaultForSchema(items)]), "addItem");
2490
- const removeAt = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((i) => onChange(arr.filter((_, idx) => idx !== i)), "removeAt");
2491
- const setAt = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((i) => (next) => onChange(arr.map((v, idx) => idx === i ? next : v)), "setAt");
2492
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2493
- label && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
2494
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: label }),
2495
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
2496
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: `array<${items.type ?? "any"}>` })
2497
- ] }),
2498
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 border-l-2 border-border/60 pl-3 ml-px", children: [
2499
- arr.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground/50 italic", children: "Empty array" }),
2500
- arr.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
2501
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2502
- SchemaField,
2503
- {
2504
- schema: items,
2505
- value: v,
2506
- onChange: setAt(i),
2507
- depth: depth + 1,
2508
- required: false,
2509
- label: `${label ?? ""}[${i}]`
2510
- }
2511
- ) }),
2512
- /* @__PURE__ */ jsxRuntime.jsx(
2513
- "button",
2514
- {
2515
- type: "button",
2516
- onClick: () => removeAt(i),
2517
- title: "Remove item",
2518
- 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",
2519
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-3.5 w-3.5" })
2520
- }
2521
- )
2522
- ] }, i)),
2523
- /* @__PURE__ */ jsxRuntime.jsxs(
2524
- "button",
2525
- {
2526
- type: "button",
2527
- onClick: addItem,
2528
- className: "inline-flex items-center gap-1.5 text-[10px] text-muted-foreground hover:text-foreground transition-colors py-1",
2529
- children: [
2530
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3" }),
2531
- "Add item"
2532
- ]
2533
- }
2534
- )
2535
- ] })
2536
- ] });
2537
- }
2538
- chunkOLISEQHS_cjs.__name(ArrayField, "ArrayField");
2539
- function EndpointResetButton() {
2540
- const { state, setParameters, setRequestBody } = chunk7EYHNP3E_cjs.usePlaygroundContext();
2541
- const ep = state.selectedEndpoint;
2542
- const { reset } = useEndpointDraft(state.activeSchemaId, ep);
2543
- const hasDraft = Object.keys(state.parameters).length > 0 || state.requestBody.length > 0;
2544
- const onClick = React12.useCallback(() => {
2545
- setParameters({});
2546
- setRequestBody("");
2547
- reset();
2548
- }, [setParameters, setRequestBody, reset]);
2549
- if (!ep || !hasDraft) return null;
2550
- return /* @__PURE__ */ jsxRuntime.jsxs(
2551
- "button",
2552
- {
2553
- type: "button",
2554
- onClick,
2555
- title: "Reset parameters & body (keeps auth)",
2556
- className: lib.cn(
2557
- "inline-flex items-center gap-1 text-[10px] text-muted-foreground",
2558
- "hover:text-foreground transition-colors"
2559
- ),
2560
- children: [
2561
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "h-2.5 w-2.5" }),
2562
- "Reset"
2563
- ]
2564
- }
2565
- );
2566
- }
2567
- chunkOLISEQHS_cjs.__name(EndpointResetButton, "EndpointResetButton");
2568
- function ParamFields({ label, params }) {
2569
- const { state, setParameters } = chunk7EYHNP3E_cjs.usePlaygroundContext();
2570
- function handleChange(name, value) {
2571
- setParameters({ ...state.parameters, [name]: value });
2572
- }
2573
- chunkOLISEQHS_cjs.__name(handleChange, "handleChange");
2574
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2575
- /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: label }),
2576
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: params.map((p) => {
2577
- const value = state.parameters[p.name] ?? "";
2578
- const placeholder = p.description || p.name;
2579
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2580
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
2581
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-foreground/80", children: p.name }),
2582
- p.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-destructive font-bold leading-none", children: "*" }),
2583
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[10px] text-muted-foreground/50", children: p.type })
2584
- ] }),
2585
- /* @__PURE__ */ jsxRuntime.jsx(
2586
- components.Input,
2587
- {
2588
- value,
2589
- onChange: (e) => handleChange(p.name, e.target.value),
2590
- placeholder,
2591
- className: "h-8 text-xs font-mono"
2592
- }
2593
- )
2594
- ] }, p.name);
2595
- }) })
2596
- ] });
2597
- }
2598
- chunkOLISEQHS_cjs.__name(ParamFields, "ParamFields");
2599
- function RequestPanel() {
2600
- const {
2601
- state,
2602
- apiKeys,
2603
- apiKeysLoading,
2604
- setRequestBody,
2605
- setRequestHeaders,
2606
- setSelectedApiKey,
2607
- setManualApiToken,
2608
- sendRequest
2609
- } = chunk7EYHNP3E_cjs.usePlaygroundContext();
2610
- const apiKeyOptions = React12.useMemo(
2611
- () => apiKeys.map((k) => ({
2612
- value: k.id,
2613
- label: k.name || "Unnamed key",
2614
- // Surface the first 8 chars of the secret so the user
2615
- // can tell two similarly-named keys apart at a glance.
2616
- description: k.secret ? `${k.secret.slice(0, 8)}\u2026` : void 0
2617
- })),
2618
- [apiKeys]
2619
- );
2620
- const hasApiKeys = apiKeyOptions.length > 0;
2621
- const ep = state.selectedEndpoint;
2622
- const isJsonValid = state.requestBody ? chunk7EYHNP3E_cjs.isValidJson(state.requestBody) : true;
2623
- const curlCommand = React12.useMemo(() => {
2624
- if (!state.requestUrl) return "";
2625
- const absoluteUrl = chunk7EYHNP3E_cjs.resolveAbsolute(state.requestUrl);
2626
- const apiKey = state.selectedApiKey ? chunk7EYHNP3E_cjs.findApiKeyById(apiKeys, state.selectedApiKey) : null;
2627
- const hdrs = chunk7EYHNP3E_cjs.parseRequestHeaders(state.requestHeaders);
2628
- if (apiKey) hdrs["X-API-Key"] = apiKey.secret || apiKey.id;
2629
- let cmd = `curl -X ${state.requestMethod} "${absoluteUrl}"`;
2630
- Object.entries(hdrs).forEach(([k, v]) => {
2631
- cmd += ` \\
2632
- -H "${k}: ${v}"`;
2633
- });
2634
- if (state.requestBody && state.requestMethod !== "GET" && isJsonValid) {
2635
- cmd += ` \\
2636
- -d '${state.requestBody}'`;
2637
- }
2638
- return cmd;
2639
- }, [state, apiKeys, isJsonValid]);
2640
- const pathParams = React12.useMemo(
2641
- () => ep?.parameters?.filter((p) => ep.path.includes(`{${p.name}}`)) ?? [],
2642
- [ep]
2643
- );
2644
- const queryParams = React12.useMemo(
2645
- () => ep?.parameters?.filter((p) => !ep.path.includes(`{${p.name}}`)) ?? [],
2646
- [ep]
2647
- );
2648
- state.loading || !state.requestUrl || !isJsonValid;
2649
- const displayUrl = chunk7EYHNP3E_cjs.resolveAbsolute(state.requestUrl || ep?.path || "");
2650
- const hasBody = ep?.method !== "GET";
2651
- const bodyType = ep?.requestBody?.type ?? "";
2652
- const hasPathParams = pathParams.length > 0;
2653
- const hasQueryParams = queryParams.length > 0;
2654
- const hasCurl = Boolean(curlCommand);
2655
- const epPath = ep ? chunk7EYHNP3E_cjs.relativePath(ep.path) : "";
2656
- const urlChanged = displayUrl !== "" && displayUrl !== epPath;
2657
- if (!ep) {
2658
- return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Send, text: "Select an endpoint to build a request" });
2659
- }
2660
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2661
- (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: [
2662
- 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" }),
2663
- /* @__PURE__ */ jsxRuntime.jsx(EndpointResetButton, {})
2664
- ] }),
2665
- /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "px-4 py-3 space-y-3", children: [
2666
- hasPathParams && /* @__PURE__ */ jsxRuntime.jsx(ParamFields, { label: "Path Parameters", params: pathParams }),
2667
- hasQueryParams && /* @__PURE__ */ jsxRuntime.jsx(ParamFields, { label: "Query Parameters", params: queryParams }),
2668
- hasBody && /* @__PURE__ */ jsxRuntime.jsx(
2669
- BodySection,
2670
- {
2671
- schema: ep.requestBody?.schema,
2672
- bodyType,
2673
- bodyDescription: ep.requestBody?.description,
2674
- value: state.requestBody,
2675
- onChange: setRequestBody,
2676
- isJsonValid
2677
- }
2678
- ),
2679
- /* @__PURE__ */ jsxRuntime.jsx(
2680
- CollapsibleSection,
2681
- {
2682
- label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
2683
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Key, { className: "h-2.5 w-2.5" }),
2684
- "Auth & Headers"
2685
- ] }),
2686
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 pt-2", children: [
2687
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2688
- /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "API Key" }),
2689
- /* @__PURE__ */ jsxRuntime.jsx(
2690
- components.Combobox,
2691
- {
2692
- options: apiKeyOptions,
2693
- value: state.selectedApiKey ?? "",
2694
- onValueChange: (v) => setSelectedApiKey(v || null),
2695
- placeholder: apiKeysLoading ? "Loading keys\u2026" : hasApiKeys ? "Select an API key" : "No API keys yet",
2696
- searchPlaceholder: "Search keys\u2026",
2697
- emptyText: "No matching key",
2698
- disabled: apiKeysLoading || !hasApiKeys,
2699
- className: "h-8"
2700
- }
2701
- ),
2702
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[10px] text-muted-foreground", children: [
2703
- "Picks are sent via the",
2704
- " ",
2705
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: "X-API-Key" }),
2706
- " header."
2707
- ] })
2708
- ] }),
2709
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2710
- /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Bearer Token" }),
2711
- /* @__PURE__ */ jsxRuntime.jsx(
2712
- components.Input,
2713
- {
2714
- type: "password",
2715
- placeholder: "Leave empty to use JWT from localStorage",
2716
- value: state.manualApiToken,
2717
- onChange: (e) => setManualApiToken(e.target.value),
2718
- className: "font-mono text-xs h-8"
2719
- }
2720
- )
2721
- ] }),
2722
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2723
- /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Headers" }),
2724
- /* @__PURE__ */ jsxRuntime.jsx(
2725
- components.Textarea,
2726
- {
2727
- value: state.requestHeaders,
2728
- onChange: (e) => setRequestHeaders(e.target.value),
2729
- className: "font-mono text-[11px] min-h-[60px] resize-y",
2730
- rows: 3
2731
- }
2732
- )
2733
- ] })
2734
- ] })
2735
- }
2736
- ),
2737
- hasCurl && /* @__PURE__ */ jsxRuntime.jsx(
2738
- CollapsibleSection,
2739
- {
2740
- label: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
2741
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Terminal, { className: "h-2.5 w-2.5" }),
2742
- "cURL"
2743
- ] }),
2744
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2745
- chunk7IYXZUJO_cjs.PrettyCode_default,
2746
- {
2747
- data: curlCommand,
2748
- language: "bash",
2749
- isCompact: true,
2750
- maxLines: 50
2751
- }
2752
- ) })
2753
- }
2754
- ),
2755
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4" })
2756
- ] })
2757
- ] });
2758
- }
2759
- chunkOLISEQHS_cjs.__name(RequestPanel, "RequestPanel");
2760
- function BodySection({ schema, bodyType, bodyDescription, value, onChange, isJsonValid }) {
2761
- const hasSchema = !!schema;
2762
- const [mode, setMode] = React12__default.default.useState(hasSchema ? "form" : "json");
2763
- const parsed = React12__default.default.useMemo(() => {
2764
- if (!value) return null;
2765
- try {
2766
- return JSON.parse(value);
2767
- } catch {
2768
- return null;
2769
- }
2770
- }, [value]);
2771
- const handleFormChange = React12.useCallback(
2772
- (next) => {
2773
- onChange(JSON.stringify(next, null, 2));
2774
- },
2775
- [onChange]
2776
- );
2777
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2778
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
2779
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2 min-w-0", children: [
2780
- /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Body" }),
2781
- bodyType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/40 font-mono", children: bodyType }),
2782
- bodyDescription && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/60 truncate", children: bodyDescription })
2783
- ] }),
2784
- hasSchema && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex rounded-md border overflow-hidden text-[10px]", children: [
2785
- /* @__PURE__ */ jsxRuntime.jsx(ModeButton, { active: mode === "form", onClick: () => setMode("form"), children: "Form" }),
2786
- /* @__PURE__ */ jsxRuntime.jsx(ModeButton, { active: mode === "json", onClick: () => setMode("json"), children: "JSON" })
2787
- ] }),
2788
- mode === "json" && isJsonValid && value && /* @__PURE__ */ jsxRuntime.jsxs(
2789
- "button",
2790
- {
2791
- type: "button",
2792
- onClick: () => {
2793
- try {
2794
- onChange(JSON.stringify(JSON.parse(value), null, 2));
2795
- } catch {
2796
- }
2797
- },
2798
- className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors",
2799
- children: [
2800
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-2.5 w-2.5" }),
2801
- "Format"
2802
- ]
2803
- }
2804
- )
2805
- ] }),
2806
- mode === "form" && hasSchema ? /* @__PURE__ */ jsxRuntime.jsx(
2807
- BodyFormEditor,
2808
- {
2809
- schema,
2810
- value: parsed,
2811
- onChange: handleFormChange
2812
- }
2813
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2814
- /* @__PURE__ */ jsxRuntime.jsx(
2815
- components.Textarea,
2816
- {
2817
- placeholder: '{\n "key": "value"\n}',
2818
- value,
2819
- onChange: (e) => onChange(e.target.value),
2820
- className: lib.cn(
2821
- "font-mono text-[11px] min-h-[90px] resize-y",
2822
- !isJsonValid && "border-destructive focus-visible:ring-destructive/30"
2823
- ),
2824
- rows: 4
2825
- }
2826
- ),
2827
- !isJsonValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-destructive", children: "Invalid JSON" })
2828
- ] })
2829
- ] });
2830
- }
2831
- chunkOLISEQHS_cjs.__name(BodySection, "BodySection");
2832
- function ModeButton({
2833
- active,
2834
- onClick,
2835
- children
2836
- }) {
2837
- return /* @__PURE__ */ jsxRuntime.jsx(
2838
- "button",
2839
- {
2840
- type: "button",
2841
- onClick,
2842
- className: lib.cn(
2843
- "px-2 py-0.5 font-medium transition-colors",
2844
- active ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:text-foreground"
2845
- ),
2846
- children
2847
- }
2848
- );
2849
- }
2850
- chunkOLISEQHS_cjs.__name(ModeButton, "ModeButton");
2851
- function looksLikeSpaShell(html) {
2852
- const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
2853
- const bodyContent = (bodyMatch?.[1] ?? html).replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<!--[\s\S]*?-->/g, "").trim();
2854
- if (bodyContent.length === 0) return true;
2855
- const singleEmptyContainer = /^<(div|main|section)[^>]*>\s*<\/\1>$/i;
2856
- if (singleEmptyContainer.test(bodyContent)) return true;
2857
- return false;
2858
- }
2859
- chunkOLISEQHS_cjs.__name(looksLikeSpaShell, "looksLikeSpaShell");
2860
- function PreviewView({ html }) {
2861
- const isSpaShell = React12.useMemo(() => looksLikeSpaShell(html), [html]);
2862
- if (!html) {
2863
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 text-center text-xs text-muted-foreground", children: "Empty response body" });
2864
- }
2865
- if (isSpaShell) {
2866
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-16 px-6 text-center gap-3 min-h-[400px]", children: [
2867
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center h-10 w-10 rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "h-5 w-5 text-muted-foreground" }) }),
2868
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-sm space-y-1.5", children: [
2869
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: "Looks like a single-page app shell" }),
2870
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground leading-relaxed", children: [
2871
- "This page renders its content with JavaScript at runtime. Scripts are disabled in the sandbox, so Preview would show a blank page. Switch to ",
2872
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Pretty" }),
2873
- " or",
2874
- " ",
2875
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Raw" }),
2876
- " to inspect the HTML source."
2877
- ] })
2878
- ] })
2879
- ] });
2880
- }
2881
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full min-h-[400px]", children: [
2882
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 flex items-center gap-1.5 px-3 py-1.5 bg-muted/30 border-b text-[10px] text-muted-foreground/70", children: [
2883
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "h-3 w-3" }),
2884
- "Sandboxed preview \u2014 scripts, forms and popups are disabled"
2885
- ] }),
2886
- /* @__PURE__ */ jsxRuntime.jsx(
2887
- "div",
2888
- {
2889
- className: "flex-1 min-h-[360px] p-2",
2890
- style: {
2891
- backgroundColor: "#fff",
2892
- backgroundImage: "linear-gradient(45deg, #f3f4f6 25%, transparent 25%), linear-gradient(-45deg, #f3f4f6 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #f3f4f6 75%), linear-gradient(-45deg, transparent 75%, #f3f4f6 75%)",
2893
- backgroundSize: "16px 16px",
2894
- backgroundPosition: "0 0, 0 8px, 8px -8px, -8px 0px"
2895
- },
2896
- children: /* @__PURE__ */ jsxRuntime.jsx(
2897
- "iframe",
2898
- {
2899
- title: "Response preview",
2900
- srcDoc: html,
2901
- sandbox: "",
2902
- className: "w-full h-full min-h-[360px] bg-white border-0 rounded shadow-sm"
2903
- }
2904
- )
2905
- }
2906
- )
2907
- ] });
2908
- }
2909
- chunkOLISEQHS_cjs.__name(PreviewView, "PreviewView");
2910
- var JSON_TREE_CONFIG = {
2911
- maxAutoExpandDepth: 2,
2912
- maxAutoExpandArrayItems: 10,
2913
- maxAutoExpandObjectKeys: 5,
2914
- maxStringLength: 200,
2915
- collectionLimit: 50,
2916
- showCollectionInfo: true,
2917
- showExpandControls: true,
2918
- showActionButtons: false,
2919
- preserveKeyOrder: true,
2920
- className: "border-0 rounded-none"
2921
- };
2922
- function PrettyView({ treeData, rawText, detected }) {
2923
- if (detected.kind === "json" && treeData != null) {
2924
- return /* @__PURE__ */ jsxRuntime.jsx(chunkT3MWM23F_cjs.JsonTree_default, { title: "Response Body", data: treeData, config: JSON_TREE_CONFIG });
2925
- }
2926
- if (!rawText) {
2927
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 text-center text-xs text-muted-foreground", children: "Empty response body" });
2928
- }
2929
- return /* @__PURE__ */ jsxRuntime.jsx(
2930
- chunk7IYXZUJO_cjs.PrettyCode_default,
2931
- {
2932
- data: rawText,
2933
- language: detected.prism,
2934
- variant: "plain",
2935
- isCompact: true
2936
- }
2937
- );
2938
- }
2939
- chunkOLISEQHS_cjs.__name(PrettyView, "PrettyView");
2940
- function RawView({ rawText }) {
2941
- if (!rawText) {
2942
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 text-center text-xs text-muted-foreground", children: "Empty response body" });
2943
- }
2944
- return /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-4 text-[11px] font-mono text-foreground/70 whitespace-pre-wrap break-all leading-relaxed", children: rawText });
2945
- }
2946
- chunkOLISEQHS_cjs.__name(RawView, "RawView");
2947
- function StatusBar({ response, rawText, contentType }) {
2948
- const sizeKb = rawText ? `${(rawText.length / 1024).toFixed(1)} KB` : "";
2949
- const duration = response.duration != null ? `${response.duration}ms` : "";
2950
- const hasStatus = response.status != null;
2951
- const hasCopy = Boolean(rawText);
2952
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-4 py-2 flex items-center justify-between gap-3 bg-muted/20", children: [
2953
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
2954
- hasStatus && /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: response.status }),
2955
- response.statusText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground truncate", children: response.statusText }),
2956
- sizeKb && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/50 tabular-nums shrink-0", children: sizeKb }),
2957
- duration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/50 tabular-nums shrink-0", children: duration }),
2958
- contentType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/50 font-mono truncate", children: contentType })
2959
- ] }),
2960
- hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
2961
- components.CopyButton,
2962
- {
2963
- value: rawText,
2964
- variant: "ghost",
2965
- size: "sm",
2966
- className: "h-6 px-2 text-[10px] text-muted-foreground shrink-0",
2967
- children: "Copy"
2968
- }
2969
- )
2970
- ] });
2971
- }
2972
- chunkOLISEQHS_cjs.__name(StatusBar, "StatusBar");
2973
-
2974
- // src/tools/OpenapiViewer/components/shared/ResponsePanel/detectContent.ts
2975
- function normaliseContentType(raw) {
2976
- if (!raw) return null;
2977
- const semi = raw.indexOf(";");
2978
- return (semi === -1 ? raw : raw.slice(0, semi)).trim().toLowerCase();
2979
- }
2980
- chunkOLISEQHS_cjs.__name(normaliseContentType, "normaliseContentType");
2981
- function readContentType(headers) {
2982
- if (!headers) return null;
2983
- if (typeof headers.get === "function") {
2984
- return headers.get("content-type");
2985
- }
2986
- if (typeof headers === "object") {
2987
- for (const [k, v] of Object.entries(headers)) {
2988
- if (k.toLowerCase() === "content-type") {
2989
- return typeof v === "string" ? v : null;
2990
- }
2991
- }
2992
- }
2993
- return null;
2994
- }
2995
- chunkOLISEQHS_cjs.__name(readContentType, "readContentType");
2996
- function kindFromContentType(mime) {
2997
- if (!mime) return "text";
2998
- if (mime === "application/json" || mime.endsWith("+json")) return "json";
2999
- if (mime === "text/html" || mime === "application/xhtml+xml") return "html";
3000
- if (mime === "application/xml" || mime === "text/xml" || mime.endsWith("+xml")) return "xml";
3001
- if (mime === "text/css") return "css";
3002
- if (mime === "application/javascript" || mime === "text/javascript" || mime === "application/x-javascript") return "javascript";
3003
- return "text";
3004
- }
3005
- chunkOLISEQHS_cjs.__name(kindFromContentType, "kindFromContentType");
3006
- function kindFromBody(body) {
3007
- const trimmed = body.trimStart();
3008
- if (!trimmed) return null;
3009
- if (trimmed.startsWith("<!DOCTYPE") || /^<html[\s>]/i.test(trimmed)) return "html";
3010
- if (trimmed.startsWith("<?xml")) return "xml";
3011
- if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
3012
- try {
3013
- JSON.parse(trimmed);
3014
- return "json";
3015
- } catch {
3016
- }
3017
- }
3018
- return null;
3019
- }
3020
- chunkOLISEQHS_cjs.__name(kindFromBody, "kindFromBody");
3021
- var PRISM_BY_KIND = {
3022
- json: "json",
3023
- // ``markup`` is Prism's HTML/XML grammar — there isn't a separate
3024
- // ``html`` language. XML piggy-backs on the same tokeniser.
3025
- html: "markup",
3026
- xml: "markup",
3027
- css: "css",
3028
- javascript: "javascript",
3029
- text: "markup"
3030
- };
3031
- function detectContent(headers, rawBody) {
3032
- const contentType = normaliseContentType(readContentType(headers));
3033
- const headerKind = kindFromContentType(contentType);
3034
- const kind = headerKind === "text" ? kindFromBody(rawBody) ?? "text" : headerKind;
3035
- return {
3036
- kind,
3037
- prism: PRISM_BY_KIND[kind],
3038
- contentType
3039
- };
3040
- }
3041
- chunkOLISEQHS_cjs.__name(detectContent, "detectContent");
3042
-
3043
- // src/tools/OpenapiViewer/components/shared/ResponsePanel/useResponseView.ts
3044
- function useResponseView(data, headers) {
3045
- return React12.useMemo(() => {
3046
- if (data == null) {
3047
- return {
3048
- treeData: null,
3049
- rawText: "",
3050
- detected: detectContent(headers, "")
3051
- };
3052
- }
3053
- if (typeof data === "string") {
3054
- try {
3055
- return {
3056
- treeData: JSON.parse(data),
3057
- rawText: data,
3058
- detected: detectContent(headers, data)
3059
- };
3060
- } catch {
3061
- return {
3062
- treeData: null,
3063
- rawText: data,
3064
- detected: detectContent(headers, data)
3065
- };
3066
- }
3067
- }
3068
- const stringified = (() => {
3069
- try {
3070
- return JSON.stringify(data, null, 2);
3071
- } catch {
3072
- return String(data);
3073
- }
3074
- })();
3075
- return {
3076
- treeData: data,
3077
- rawText: stringified,
3078
- detected: detectContent(headers, stringified)
3079
- };
3080
- }, [data, headers]);
3081
- }
3082
- chunkOLISEQHS_cjs.__name(useResponseView, "useResponseView");
3083
- var LABELS = {
3084
- pretty: "Pretty",
3085
- raw: "Raw",
3086
- preview: "Preview"
3087
- };
3088
- function ViewTabs({ active, onChange, showPreview }) {
3089
- const tabs = showPreview ? ["pretty", "raw", "preview"] : ["pretty", "raw"];
3090
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-b px-3 py-1.5 flex items-center gap-1", children: tabs.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
3091
- "button",
3092
- {
3093
- type: "button",
3094
- onClick: () => onChange(t),
3095
- className: lib.cn(
3096
- "h-6 px-2.5 rounded text-[11px] font-medium transition-colors",
3097
- active === t ? "bg-muted text-foreground" : "text-muted-foreground/70 hover:text-foreground hover:bg-muted/50"
3098
- ),
3099
- children: LABELS[t]
3100
- },
3101
- t
3102
- )) });
3103
- }
3104
- chunkOLISEQHS_cjs.__name(ViewTabs, "ViewTabs");
3105
- function ResponsePanel() {
3106
- const { state } = chunk7EYHNP3E_cjs.usePlaygroundContext();
3107
- const { response, loading, selectedEndpoint } = state;
3108
- const { treeData, rawText, detected } = useResponseView(response?.data, response?.headers);
3109
- const showPreview = detected.kind === "html";
3110
- const [mode, setMode] = React12.useState(showPreview ? "preview" : "pretty");
3111
- React12.useEffect(() => {
3112
- setMode(showPreview ? "preview" : "pretty");
3113
- }, [selectedEndpoint, response, showPreview]);
3114
- if (loading) {
3115
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center h-full gap-2", children: [
3116
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
3117
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Sending\u2026" })
3118
- ] });
3119
- }
3120
- if (!selectedEndpoint) return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Terminal, text: "Response will appear here" });
3121
- if (!response) return /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { icon: lucideReact.Send, text: 'Press "Send Request" to see the response' });
3122
- const hasError = Boolean(response.error);
3123
- const hasStatus = response.status != null;
3124
- if (hasError && !hasStatus) {
3125
- return /* @__PURE__ */ jsxRuntime.jsx(
3126
- EmptyState,
3127
- {
3128
- icon: lucideReact.WifiOff,
3129
- text: response.error,
3130
- className: "text-destructive [&_svg]:text-destructive"
3131
- }
3132
- );
3133
- }
3134
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3135
- /* @__PURE__ */ jsxRuntime.jsx(StatusBar, { response, rawText, contentType: detected.contentType }),
3136
- 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 }) }),
3137
- /* @__PURE__ */ jsxRuntime.jsx(ViewTabs, { active: mode, onChange: setMode, showPreview }),
3138
- /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { children: [
3139
- mode === "pretty" && /* @__PURE__ */ jsxRuntime.jsx(PrettyView, { treeData, rawText, detected }),
3140
- mode === "raw" && /* @__PURE__ */ jsxRuntime.jsx(RawView, { rawText }),
3141
- mode === "preview" && /* @__PURE__ */ jsxRuntime.jsx(PreviewView, { html: rawText })
3142
- ] })
3143
- ] });
3144
- }
3145
- chunkOLISEQHS_cjs.__name(ResponsePanel, "ResponsePanel");
3146
- function SendButton({ className }) {
3147
- const { state, sendRequest } = chunk7EYHNP3E_cjs.usePlaygroundContext();
3148
- const ep = state.selectedEndpoint;
3149
- const builder = React12.useMemo(
3150
- () => ep ? new chunk7EYHNP3E_cjs.UrlBuilder(ep, state.parameters) : null,
3151
- [ep, state.parameters]
3152
- );
3153
- const missingRequired = builder?.missingRequired() ?? [];
3154
- const unsubstituted = builder?.unfilledPlaceholders() ?? [];
3155
- const isJsonValid = state.requestBody ? chunk7EYHNP3E_cjs.isValidJson(state.requestBody) : true;
3156
- const blockers = [];
3157
- if (missingRequired.length > 0) {
3158
- blockers.push(
3159
- `Fill required parameter${missingRequired.length > 1 ? "s" : ""}: ${missingRequired.join(", ")}`
3160
- );
3161
- } else if (unsubstituted.length > 0) {
3162
- blockers.push(`URL still has unfilled placeholder${unsubstituted.length > 1 ? "s" : ""}: ${unsubstituted.map((n) => `{${n}}`).join(", ")}`);
3163
- }
3164
- if (!isJsonValid) blockers.push("Request body is not valid JSON");
3165
- const disabled = state.loading || !state.requestUrl || blockers.length > 0;
3166
- const tooltip = blockers.length > 0 ? blockers.join("\n") : void 0;
3167
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: lib.cn("space-y-2", className), children: [
3168
- 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: [
3169
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-3.5 w-3.5 shrink-0 mt-px" }),
3170
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "leading-snug", children: blockers[0] })
3171
- ] }),
3172
- /* @__PURE__ */ jsxRuntime.jsx(
3173
- components.Button,
3174
- {
3175
- onClick: sendRequest,
3176
- disabled,
3177
- size: "sm",
3178
- title: tooltip,
3179
- className: "w-full gap-2 h-9",
3180
- children: state.loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3181
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
3182
- "Sending\u2026"
3183
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3184
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3.5 w-3.5" }),
3185
- "Send Request"
3186
- ] })
3187
- }
3188
- )
3189
- ] });
3190
- }
3191
- chunkOLISEQHS_cjs.__name(SendButton, "SendButton");
3192
- var WIDTH_NARROW = "clamp(380px, 30vw, 480px)";
3193
- var WIDTH_WIDE = "clamp(720px, 60vw, 1280px)";
3194
- function SlideInPlayground({ open, onClose }) {
3195
- const { state } = chunk7EYHNP3E_cjs.usePlaygroundContext();
3196
- const ep = state.selectedEndpoint;
3197
- const showResponse = state.response !== null || state.loading;
3198
- const width = showResponse ? WIDTH_WIDE : WIDTH_NARROW;
3199
- 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: [
3200
- /* @__PURE__ */ jsxRuntime.jsxs(components.SidePanel.Header, { children: [
3201
- /* @__PURE__ */ jsxRuntime.jsx(components.SidePanel.Title, { children: "Playground" }),
3202
- ep && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
3203
- /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: ep.method }),
3204
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-[11px] text-muted-foreground truncate", children: chunk7EYHNP3E_cjs.relativePath(ep.path) })
3205
- ] }),
3206
- /* @__PURE__ */ jsxRuntime.jsx(components.SidePanel.Close, { className: "ml-auto" })
3207
- ] }),
3208
- /* @__PURE__ */ jsxRuntime.jsxs(
3209
- components.SidePanel.Body,
3210
- {
3211
- className: lib.cn(
3212
- "overflow-hidden grid divide-x transition-[grid-template-columns] duration-250",
3213
- showResponse ? "grid-cols-[minmax(0,1fr)_minmax(0,1fr)]" : "grid-cols-1"
3214
- ),
3215
- children: [
3216
- /* @__PURE__ */ jsxRuntime.jsxs(Panel, { children: [
3217
- /* @__PURE__ */ jsxRuntime.jsx(RequestPanel, {}),
3218
- ep && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t px-4 py-3 bg-background", children: /* @__PURE__ */ jsxRuntime.jsx(SendButton, {}) })
3219
- ] }),
3220
- showResponse && /* @__PURE__ */ jsxRuntime.jsx(Panel, { children: /* @__PURE__ */ jsxRuntime.jsx(ResponsePanel, {}) })
3221
- ]
3222
- }
3223
- )
3224
- ] }) });
3225
- }
3226
- chunkOLISEQHS_cjs.__name(SlideInPlayground, "SlideInPlayground");
3227
- function TryItSheet({ open, onOpenChange }) {
3228
- const { state } = chunk7EYHNP3E_cjs.usePlaygroundContext();
3229
- const showResponse = state.response !== null || state.loading;
3230
- 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: [
3231
- /* @__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" }) }),
3232
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-h-0 flex flex-col divide-y", children: [
3233
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-h-0 flex flex-col", children: [
3234
- /* @__PURE__ */ jsxRuntime.jsx(RequestPanel, {}),
3235
- state.selectedEndpoint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t px-4 py-3 bg-background", children: /* @__PURE__ */ jsxRuntime.jsx(SendButton, {}) })
3236
- ] }),
3237
- showResponse && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(ResponsePanel, {}) })
3238
- ] })
3239
- ] }) });
3240
- }
3241
- chunkOLISEQHS_cjs.__name(TryItSheet, "TryItSheet");
3242
- var DocsLayout = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
3243
- const { state, config, setSelectedEndpoint } = chunk7EYHNP3E_cjs.usePlaygroundContext();
3244
- const isDesktop = hooks.useMediaQuery("(min-width: 1024px)");
3245
- const isMobile = !isDesktop;
3246
- const grouping = config.schemaGrouping ?? "selector";
3247
- const preloadAll = grouping === "sections";
3248
- const urlSyncEnabled = config.urlSync === void 0 ? true : typeof config.urlSync === "boolean" ? config.urlSync : Boolean(config.urlSync.enabled);
3249
- const {
3250
- endpoints,
3251
- schemaInfo,
3252
- rawSchema,
3253
- resolvedBaseUrl,
3254
- loading,
3255
- error,
3256
- schemas,
3257
- currentSchema,
3258
- setCurrentSchema,
3259
- schemasData
3260
- } = useOpenApiSchema({
3261
- schemas: config.schemas,
3262
- defaultSchemaId: config.defaultSchemaId,
3263
- baseUrl: config.baseUrl,
3264
- preloadAll
3265
- });
3266
- const [activeAnchor, setActiveAnchor] = React12.useState(null);
3267
- const [activeSchemaId, setActiveSchemaId] = React12.useState(null);
3268
- const [sheetOpen, setSheetOpen] = React12.useState(false);
3269
- const docsRef = React12.useRef(null);
3270
- const slideOpen = !isMobile && state.selectedEndpoint !== null;
3271
- const endpointsBySchema = React12.useMemo(() => {
3272
- if (grouping !== "sections") return {};
3273
- const byId = lodashEs.keyBy(schemasData, (e) => e.source.id);
3274
- const out = {};
3275
- for (const src of schemas) out[src.id] = byId[src.id]?.endpoints ?? [];
3276
- return out;
3277
- }, [grouping, schemasData, schemas]);
3278
- const handleTry = React12.useCallback(
3279
- (ep) => {
3280
- setSelectedEndpoint(ep);
3281
- if (isMobile) setSheetOpen(true);
3282
- },
3283
- [isMobile, setSelectedEndpoint]
3284
- );
3285
- const handleCloseSlide = React12.useCallback(() => {
3286
- setSelectedEndpoint(null);
3287
- }, [setSelectedEndpoint]);
3288
- const handleNavigate = React12.useCallback(
3289
- (anchor, schemaId) => {
3290
- if (schemaId && schemaId !== currentSchema?.id && grouping === "selector") {
3291
- setCurrentSchema(schemaId);
3292
- requestAnimationFrame(() => {
3293
- docsRef.current?.scrollToAnchor(anchor);
3294
- });
3295
- return;
3296
- }
3297
- docsRef.current?.scrollToAnchor(anchor);
3298
- },
3299
- [currentSchema?.id, grouping, setCurrentSchema]
3300
- );
3301
- const handleActiveChange = React12.useCallback((anchor, schemaId) => {
3302
- setActiveAnchor(anchor);
3303
- setActiveSchemaId(schemaId);
3304
- }, []);
3305
- const effectiveSchemaId = grouping === "sections" ? activeSchemaId : currentSchema?.id ?? null;
3306
- const handleHashTarget = React12.useCallback(
3307
- (target) => {
3308
- if (!target.schemaId && !target.anchor) return;
3309
- const matched = target.schemaId ? schemas.find((s) => s.id === target.schemaId || slugifySchemaId(s.id) === target.schemaId) : null;
3310
- const needsSchemaSwitch = matched && grouping === "selector" && matched.id !== currentSchema?.id;
3311
- if (needsSchemaSwitch) {
3312
- setCurrentSchema(matched.id);
3313
- }
3314
- if (target.anchor) {
3315
- const anchor = target.anchor;
3316
- if (needsSchemaSwitch) {
3317
- requestAnimationFrame(() => {
3318
- docsRef.current?.scrollToAnchor(anchor);
3319
- });
3320
- } else {
3321
- docsRef.current?.scrollToAnchor(anchor);
3322
- }
3323
- }
3324
- },
3325
- [schemas, grouping, currentSchema?.id, setCurrentSchema]
3326
- );
3327
- useDocsUrlSync({
3328
- enabled: urlSyncEnabled,
3329
- currentSchemaId: effectiveSchemaId,
3330
- activeAnchor,
3331
- onHashTarget: handleHashTarget
3332
- });
3333
- if (loading) {
3334
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[260px_1fr] items-start", children: [
3335
- /* @__PURE__ */ jsxRuntime.jsx(
3336
- "div",
3337
- {
3338
- className: "sticky top-[var(--navbar-height,64px)] border-r p-3 space-y-1.5 overflow-y-auto",
3339
- style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
3340
- children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-full rounded" }, i))
3341
- }
3342
- ),
3343
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 space-y-4", children: [
3344
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-1/2" }),
3345
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-full" }),
3346
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-3/4" }),
3347
- /* @__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: [
3348
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-6 w-1/3" }),
3349
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-20 w-full" })
3350
- ] }, i)) })
3351
- ] })
3352
- ] });
3353
- }
3354
- if (error) {
3355
- return /* @__PURE__ */ jsxRuntime.jsx(
3356
- "div",
3357
- {
3358
- className: "flex items-center justify-center p-8",
3359
- style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
3360
- children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-destructive", children: [
3361
- "Failed to load schema: ",
3362
- error
3363
- ] })
3364
- }
3365
- );
3366
- }
3367
- if (isMobile) {
3368
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
3369
- /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
3370
- grouping === "sections" ? /* @__PURE__ */ jsxRuntime.jsx(
3371
- DocsView,
3372
- {
3373
- ref: docsRef,
3374
- grouping: "sections",
3375
- schemasData,
3376
- selectedVersion: state.selectedVersion,
3377
- loadedEndpoint: state.selectedEndpoint,
3378
- onTryEndpoint: handleTry,
3379
- onActiveChange: handleActiveChange
3380
- }
3381
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3382
- DocsView,
3383
- {
3384
- ref: docsRef,
3385
- info: schemaInfo,
3386
- rawSchema,
3387
- resolvedBaseUrl,
3388
- endpoints,
3389
- selectedVersion: state.selectedVersion,
3390
- loadedEndpoint: state.selectedEndpoint,
3391
- onTryEndpoint: handleTry,
3392
- onActiveChange: handleActiveChange
3393
- }
3394
- ),
3395
- /* @__PURE__ */ jsxRuntime.jsx(TryItSheet, { open: sheetOpen, onOpenChange: setSheetOpen })
3396
- ] });
3397
- }
3398
- return /* @__PURE__ */ jsxRuntime.jsx(components.TooltipProvider, { delayDuration: 350, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[260px_minmax(0,1fr)] items-start", children: [
3399
- /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
3400
- /* @__PURE__ */ jsxRuntime.jsx(
3401
- "div",
3402
- {
3403
- className: "sticky top-[var(--navbar-height,64px)]",
3404
- style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
3405
- children: /* @__PURE__ */ jsxRuntime.jsx(
3406
- DocsSidebar,
3407
- {
3408
- info: schemaInfo,
3409
- endpoints,
3410
- schemas,
3411
- currentSchemaId: currentSchema?.id ?? null,
3412
- onSchemaChange: setCurrentSchema,
3413
- activeEndpointId: activeAnchor,
3414
- selectedVersion: state.selectedVersion,
3415
- onNavigate: handleNavigate,
3416
- grouping,
3417
- endpointsBySchema,
3418
- rawSchema,
3419
- resolvedBaseUrl
3420
- }
3421
- )
3422
- }
3423
- ),
3424
- grouping === "sections" ? /* @__PURE__ */ jsxRuntime.jsx(
3425
- DocsView,
3426
- {
3427
- ref: docsRef,
3428
- grouping: "sections",
3429
- schemasData,
3430
- selectedVersion: state.selectedVersion,
3431
- loadedEndpoint: state.selectedEndpoint,
3432
- onTryEndpoint: handleTry,
3433
- onActiveChange: handleActiveChange
3434
- }
3435
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3436
- DocsView,
3437
- {
3438
- ref: docsRef,
3439
- info: schemaInfo,
3440
- rawSchema,
3441
- resolvedBaseUrl,
3442
- endpoints,
3443
- selectedVersion: state.selectedVersion,
3444
- loadedEndpoint: state.selectedEndpoint,
3445
- onTryEndpoint: handleTry,
3446
- onActiveChange: handleActiveChange
3447
- }
3448
- ),
3449
- /* @__PURE__ */ jsxRuntime.jsx(SlideInPlayground, { open: slideOpen, onClose: handleCloseSlide })
3450
- ] }) });
3451
- }, "DocsLayout");
3452
-
3453
- exports.DocsLayout = DocsLayout;
3454
- //# sourceMappingURL=DocsLayout-OURFYWQE.cjs.map
3455
- //# sourceMappingURL=DocsLayout-OURFYWQE.cjs.map