@apiboost/omnispec 1.0.0 → 1.1.0-next.1

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 (73) hide show
  1. package/dist/cjs/asyncapi/index.js +3 -3
  2. package/dist/cjs/chunks/AsyncApiSpec-CHvM1swf.js +1880 -0
  3. package/dist/cjs/chunks/AsyncApiSpec-CHvM1swf.js.map +1 -0
  4. package/dist/cjs/chunks/{Collapsible-BHAHk_Ep.js → Collapsible-Jlb_vtdW.js} +286 -225
  5. package/dist/cjs/chunks/Collapsible-Jlb_vtdW.js.map +1 -0
  6. package/dist/cjs/chunks/{OmniSpecRenderer-CE4wxVTL.js → OmniSpecRenderer-Dj6Z6W2J.js} +3 -3
  7. package/dist/cjs/chunks/{OmniSpecRenderer-CE4wxVTL.js.map → OmniSpecRenderer-Dj6Z6W2J.js.map} +1 -1
  8. package/dist/cjs/chunks/{OpenApiSpec-D0JtmOVQ.js → OpenApiSpec-BPtXvk7C.js} +8 -8
  9. package/dist/cjs/chunks/{OpenApiSpec-D0JtmOVQ.js.map → OpenApiSpec-BPtXvk7C.js.map} +1 -1
  10. package/dist/cjs/chunks/{OpenIdConnectManual-oEnN0QJ-.js → OpenIdConnectManual-DBP0Do-3.js} +6 -67
  11. package/dist/cjs/chunks/OpenIdConnectManual-DBP0Do-3.js.map +1 -0
  12. package/dist/cjs/chunks/{ref-resolver-DWu6Q6E5.js → ref-resolver-0A8GNRI3.js} +6 -2
  13. package/dist/cjs/chunks/{ref-resolver-DWu6Q6E5.js.map → ref-resolver-0A8GNRI3.js.map} +1 -1
  14. package/dist/cjs/core/public.js +2 -2
  15. package/dist/cjs/index.js +6 -6
  16. package/dist/cjs/openapi/index.js +4 -4
  17. package/dist/cjs/wc/index.js +1 -1
  18. package/dist/esm/asyncapi/index.js +3 -3
  19. package/dist/esm/chunks/AsyncApiSpec-BPiA9b5T.js +1878 -0
  20. package/dist/esm/chunks/AsyncApiSpec-BPiA9b5T.js.map +1 -0
  21. package/dist/esm/chunks/{Collapsible-DA6-nS46.js → Collapsible-0ryLh6wX.js} +286 -227
  22. package/dist/esm/chunks/Collapsible-0ryLh6wX.js.map +1 -0
  23. package/dist/esm/chunks/{OmniSpecRenderer-MqsQFXro.js → OmniSpecRenderer-yF2Zw_B9.js} +3 -3
  24. package/dist/esm/chunks/{OmniSpecRenderer-MqsQFXro.js.map → OmniSpecRenderer-yF2Zw_B9.js.map} +1 -1
  25. package/dist/esm/chunks/{OpenApiSpec-Cy-oW6jA.js → OpenApiSpec-MGJ3oFHZ.js} +4 -4
  26. package/dist/esm/chunks/{OpenApiSpec-Cy-oW6jA.js.map → OpenApiSpec-MGJ3oFHZ.js.map} +1 -1
  27. package/dist/esm/chunks/{OpenIdConnectManual-COfITasf.js → OpenIdConnectManual-BS-n811Z.js} +5 -64
  28. package/dist/esm/chunks/OpenIdConnectManual-BS-n811Z.js.map +1 -0
  29. package/dist/esm/chunks/{ref-resolver-BIrHJOjz.js → ref-resolver-B0C36NuQ.js} +6 -3
  30. package/dist/esm/chunks/{ref-resolver-BIrHJOjz.js.map → ref-resolver-B0C36NuQ.js.map} +1 -1
  31. package/dist/esm/core/public.js +2 -2
  32. package/dist/esm/index.js +6 -6
  33. package/dist/esm/openapi/index.js +4 -4
  34. package/dist/esm/wc/index.js +1 -1
  35. package/dist/types/asyncapi/AsyncApiSpec.d.ts.map +1 -1
  36. package/dist/types/asyncapi/components/BindingsSection.d.ts +26 -0
  37. package/dist/types/asyncapi/components/BindingsSection.d.ts.map +1 -0
  38. package/dist/types/asyncapi/components/ChannelDetail.d.ts +1 -1
  39. package/dist/types/asyncapi/components/ChannelDetail.d.ts.map +1 -1
  40. package/dist/types/asyncapi/components/ComponentsSection.d.ts +1 -1
  41. package/dist/types/asyncapi/components/ComponentsSection.d.ts.map +1 -1
  42. package/dist/types/asyncapi/components/MessagePayload.d.ts +22 -0
  43. package/dist/types/asyncapi/components/MessagePayload.d.ts.map +1 -0
  44. package/dist/types/asyncapi/components/SecurityRequirementBadges.d.ts +22 -0
  45. package/dist/types/asyncapi/components/SecurityRequirementBadges.d.ts.map +1 -0
  46. package/dist/types/asyncapi/components/SecuritySchemesSection.d.ts +23 -0
  47. package/dist/types/asyncapi/components/SecuritySchemesSection.d.ts.map +1 -0
  48. package/dist/types/asyncapi/components/ServerList.d.ts +1 -1
  49. package/dist/types/asyncapi/components/ServerList.d.ts.map +1 -1
  50. package/dist/types/asyncapi/components/TagGroupHeader.d.ts +18 -0
  51. package/dist/types/asyncapi/components/TagGroupHeader.d.ts.map +1 -0
  52. package/dist/types/asyncapi/components/field-display.d.ts +20 -0
  53. package/dist/types/asyncapi/components/field-display.d.ts.map +1 -0
  54. package/dist/types/asyncapi/parser/asyncapi-parser.d.ts.map +1 -1
  55. package/dist/types/asyncapi/schema-formats.d.ts +26 -0
  56. package/dist/types/asyncapi/schema-formats.d.ts.map +1 -0
  57. package/dist/types/asyncapi/tag-grouping.d.ts +39 -0
  58. package/dist/types/asyncapi/tag-grouping.d.ts.map +1 -0
  59. package/dist/types/asyncapi/types/asyncapi.types.d.ts +35 -0
  60. package/dist/types/asyncapi/types/asyncapi.types.d.ts.map +1 -1
  61. package/dist/types/openapi/parser/ref-resolver.d.ts +8 -0
  62. package/dist/types/openapi/parser/ref-resolver.d.ts.map +1 -1
  63. package/dist/wc/standalone.js +1 -1
  64. package/dist/wc/standalone.js.map +1 -1
  65. package/package.json +2 -2
  66. package/dist/cjs/chunks/AsyncApiSpec-TBlyRxTP.js +0 -819
  67. package/dist/cjs/chunks/AsyncApiSpec-TBlyRxTP.js.map +0 -1
  68. package/dist/cjs/chunks/Collapsible-BHAHk_Ep.js.map +0 -1
  69. package/dist/cjs/chunks/OpenIdConnectManual-oEnN0QJ-.js.map +0 -1
  70. package/dist/esm/chunks/AsyncApiSpec-C3lsUpZk.js +0 -817
  71. package/dist/esm/chunks/AsyncApiSpec-C3lsUpZk.js.map +0 -1
  72. package/dist/esm/chunks/Collapsible-DA6-nS46.js.map +0 -1
  73. package/dist/esm/chunks/OpenIdConnectManual-COfITasf.js.map +0 -1
@@ -0,0 +1,1880 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var css = require('@emotion/css');
6
+ var useSpecFetcher = require('./useSpecFetcher-BKz1jHTV.js');
7
+ var Collapsible = require('./Collapsible-Jlb_vtdW.js');
8
+ var ErrorBoundary = require('./ErrorBoundary-c1piU8da.js');
9
+ var refResolver = require('./ref-resolver-0A8GNRI3.js');
10
+ require('@emotion/styled');
11
+ require('./ssrf-guard-B6T2A7Ho.js');
12
+
13
+ function unionTags(a, b) {
14
+ if (!a && !b) return void 0;
15
+ const byName = /* @__PURE__ */ new Map();
16
+ for (const tag of [...a ?? [], ...b ?? []]) {
17
+ if (!byName.has(tag.name)) byName.set(tag.name, tag);
18
+ }
19
+ return Array.from(byName.values());
20
+ }
21
+ function mergeSchema(base, override) {
22
+ if (!base) return override;
23
+ if (!override) return base;
24
+ const result = { ...base, ...override };
25
+ const baseProps = base.properties;
26
+ const overrideProps = override.properties;
27
+ if (baseProps || overrideProps) {
28
+ result.properties = { ...baseProps ?? {}, ...overrideProps ?? {} };
29
+ }
30
+ const required = Array.from(
31
+ /* @__PURE__ */ new Set([...base.required ?? [], ...override.required ?? []])
32
+ );
33
+ if (required.length > 0) result.required = required;
34
+ return result;
35
+ }
36
+ function mergeMessageLayer(base, override) {
37
+ const result = { ...base };
38
+ for (const [key, value] of Object.entries(override)) {
39
+ if (key === "traits" || value === void 0) continue;
40
+ if (key === "tags") {
41
+ result.tags = unionTags(base.tags, value);
42
+ } else if (key === "headers") {
43
+ result.headers = mergeSchema(base.headers, value);
44
+ } else if (key === "examples") {
45
+ result.examples = [...base.examples ?? [], ...value ?? []];
46
+ } else if (key === "bindings") {
47
+ result.bindings = { ...base.bindings ?? {}, ...value };
48
+ } else {
49
+ result[key] = value;
50
+ }
51
+ }
52
+ return result;
53
+ }
54
+ function applyMessageTraits(msg) {
55
+ if (!msg.traits || msg.traits.length === 0) return msg;
56
+ let acc = {};
57
+ for (const trait of msg.traits) acc = mergeMessageLayer(acc, trait);
58
+ return mergeMessageLayer(acc, msg);
59
+ }
60
+ function mergeOperationLayer(base, override) {
61
+ const result = { ...base };
62
+ for (const [key, value] of Object.entries(override)) {
63
+ if (key === "traits" || value === void 0) continue;
64
+ if (key === "tags") {
65
+ result.tags = unionTags(base.tags, value);
66
+ } else if (key === "bindings") {
67
+ result.bindings = { ...base.bindings ?? {}, ...value };
68
+ } else {
69
+ result[key] = value;
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ function applyOperationTraits(op) {
75
+ if (!op.traits || op.traits.length === 0) return op;
76
+ let acc = {};
77
+ for (const trait of op.traits) acc = mergeOperationLayer(acc, trait);
78
+ return mergeOperationLayer(acc, op);
79
+ }
80
+ async function parseAsyncApiSpec(specInput) {
81
+ const raw = typeof specInput === "string" ? parseSpecString(specInput) : specInput;
82
+ const api = await refResolver.resolveRefs(raw);
83
+ const majorVersion = parseInt(api.asyncapi.split(".")[0], 10);
84
+ const isV3 = majorVersion >= 3;
85
+ const servers = extractServers(api, raw);
86
+ const rawApi = raw;
87
+ const channels = isV3 ? extractChannelsV3(api, rawApi) : extractChannelsV2(api);
88
+ const components = extractComponents(api);
89
+ const root = api;
90
+ const tags = api.tags?.map((tag) => {
91
+ const raw2 = tag;
92
+ return {
93
+ name: tag.name,
94
+ description: tag.description,
95
+ displayName: raw2["x-displayName"],
96
+ externalDocs: raw2.externalDocs
97
+ };
98
+ })?.filter((tag) => !tag["x-internal"]);
99
+ return {
100
+ title: api.info.title,
101
+ description: api.info.description,
102
+ version: api.info.version,
103
+ specVersion: api.asyncapi,
104
+ servers,
105
+ channels: channels.filter((ch) => !ch.xInternal),
106
+ components,
107
+ tags,
108
+ tagGroups: root["x-tagGroups"],
109
+ externalDocs: api.externalDocs,
110
+ contact: api.info.contact,
111
+ license: api.info.license,
112
+ termsOfService: api.info.termsOfService,
113
+ logo: api.info["x-logo"]
114
+ };
115
+ }
116
+ function extractServers(api, rawApi) {
117
+ if (!api.servers) return [];
118
+ const toServer = (s, name, rawSecurity) => ({
119
+ name,
120
+ url: s.host ? `${s.protocol}://${s.host}${s.pathname ?? ""}` : s.url ?? "",
121
+ protocol: s.protocol,
122
+ protocolVersion: s.protocolVersion,
123
+ description: s.description,
124
+ variables: s.variables,
125
+ security: s.security,
126
+ securityNames: deriveSecurityNames(rawSecurity, s.security),
127
+ bindings: s.bindings
128
+ });
129
+ if (Array.isArray(api.servers)) {
130
+ const rawServers2 = Array.isArray(rawApi.servers) ? rawApi.servers : [];
131
+ return api.servers.map((s, idx) => toServer(s, s.name ?? `server-${idx}`, rawServers2[idx]?.security));
132
+ }
133
+ const rawServers = !Array.isArray(rawApi.servers) && rawApi.servers || {};
134
+ return Object.entries(api.servers).map(([name, s]) => toServer(s, name, rawServers[name]?.security));
135
+ }
136
+ function extractChannelsV2(api) {
137
+ if (!api.channels) return [];
138
+ return Object.entries(api.channels).map(([channelName, ch]) => {
139
+ const operations = [];
140
+ if (ch.publish) {
141
+ operations.push(convertOperationV2("publish", ch.publish));
142
+ }
143
+ if (ch.subscribe) {
144
+ operations.push(convertOperationV2("subscribe", ch.subscribe));
145
+ }
146
+ const raw = ch;
147
+ return {
148
+ name: channelName,
149
+ address: channelName,
150
+ description: ch.description,
151
+ operations: operations.filter((op) => !op.xInternal),
152
+ parameters: ch.parameters,
153
+ bindings: ch.bindings,
154
+ xInternal: raw["x-internal"]
155
+ };
156
+ });
157
+ }
158
+ function convertOperationV2(action, rawOp) {
159
+ const op = applyOperationTraits(rawOp);
160
+ const messages = [];
161
+ if (op.message) {
162
+ if ("oneOf" in op.message) {
163
+ for (const m of op.message.oneOf) {
164
+ messages.push(convertMessage(m));
165
+ }
166
+ } else {
167
+ messages.push(convertMessage(op.message));
168
+ }
169
+ }
170
+ const raw = op;
171
+ return {
172
+ action,
173
+ operationId: op.operationId,
174
+ summary: op.summary,
175
+ description: op.description,
176
+ messages,
177
+ message: messages[0],
178
+ tags: op.tags,
179
+ bindings: op.bindings,
180
+ securityNames: deriveSecurityNames(void 0, op.security),
181
+ xBadges: raw["x-badges"],
182
+ xInternal: raw["x-internal"]
183
+ };
184
+ }
185
+ function resolveChannelName(rawChannel, resolvedChannel, addressToName) {
186
+ const refString = rawChannel && typeof rawChannel === "object" && "$ref" in rawChannel && typeof rawChannel.$ref === "string" ? rawChannel.$ref : resolvedChannel && typeof resolvedChannel === "object" && "$ref" in resolvedChannel && typeof resolvedChannel.$ref === "string" ? resolvedChannel.$ref : void 0;
187
+ if (refString) {
188
+ const last = refString.split("/").pop();
189
+ return last !== void 0 ? refResolver.decodeJsonPointerSegment(last) : void 0;
190
+ }
191
+ const address = resolvedChannel?.address;
192
+ if (address && addressToName.has(address)) {
193
+ return addressToName.get(address);
194
+ }
195
+ return void 0;
196
+ }
197
+ function extractChannelsV3(api, rawApi) {
198
+ if (!api.channels) return [];
199
+ const channelMap = /* @__PURE__ */ new Map();
200
+ const addressToName = /* @__PURE__ */ new Map();
201
+ for (const [channelName, ch] of Object.entries(api.channels)) {
202
+ const raw = ch;
203
+ const address = ch.address ?? channelName;
204
+ addressToName.set(address, channelName);
205
+ channelMap.set(channelName, {
206
+ name: channelName,
207
+ address,
208
+ description: ch.description,
209
+ operations: [],
210
+ parameters: ch.parameters,
211
+ bindings: ch.bindings,
212
+ xInternal: raw["x-internal"]
213
+ });
214
+ }
215
+ if (api.operations) {
216
+ for (const [opKey, resolvedOp] of Object.entries(api.operations)) {
217
+ const op = applyOperationTraits(resolvedOp);
218
+ const rawOp = rawApi.operations?.[opKey];
219
+ const channelName = resolveChannelName(rawOp?.channel, op.channel, addressToName);
220
+ const collectMessages = (list) => {
221
+ const out = [];
222
+ for (const msg of list ?? []) {
223
+ if (msg && typeof msg === "object" && "$ref" in msg) continue;
224
+ out.push(convertMessage(msg));
225
+ }
226
+ return out;
227
+ };
228
+ const messages = collectMessages(op.messages);
229
+ const replyMessages = collectMessages(op.reply?.messages);
230
+ const raw = op;
231
+ const operation = {
232
+ action: op.action,
233
+ summary: op.summary,
234
+ description: op.description,
235
+ messages,
236
+ message: messages[0],
237
+ tags: op.tags,
238
+ bindings: op.bindings,
239
+ securityNames: deriveSecurityNames(rawOp?.security, op.security),
240
+ reply: replyMessages.length > 0 ? { messages: replyMessages } : void 0,
241
+ xBadges: raw["x-badges"],
242
+ xInternal: raw["x-internal"]
243
+ };
244
+ if (operation.xInternal) continue;
245
+ if (channelName && channelMap.has(channelName)) {
246
+ channelMap.get(channelName).operations.push(operation);
247
+ }
248
+ }
249
+ }
250
+ return Array.from(channelMap.values());
251
+ }
252
+ function convertMessage(rawMsg) {
253
+ const msg = applyMessageTraits(rawMsg);
254
+ return {
255
+ name: msg.name,
256
+ title: msg.title,
257
+ summary: msg.summary,
258
+ description: msg.description,
259
+ contentType: msg.contentType,
260
+ schemaFormat: msg.schemaFormat,
261
+ payload: msg.payload,
262
+ headers: msg.headers,
263
+ correlationId: msg.correlationId,
264
+ tags: msg.tags,
265
+ examples: msg.examples,
266
+ bindings: msg.bindings
267
+ };
268
+ }
269
+ function extractComponents(api) {
270
+ const components = api.components;
271
+ const rawMessages = api.components?.messages ?? {};
272
+ const messages = {};
273
+ for (const [name, msg] of Object.entries(rawMessages)) {
274
+ messages[name] = convertMessage(msg);
275
+ }
276
+ return {
277
+ schemas: api.components?.schemas ?? {},
278
+ messages,
279
+ securitySchemes: components?.securitySchemes ?? {}
280
+ };
281
+ }
282
+ function deriveSecurityNames(raw, resolved) {
283
+ const rawArr = raw ?? [];
284
+ const resArr = resolved ?? [];
285
+ const count = Math.max(rawArr.length, resArr.length);
286
+ if (count === 0) return void 0;
287
+ const names = [];
288
+ for (let i = 0; i < count; i++) {
289
+ const rawEntry = rawArr[i];
290
+ const resEntry = resArr[i];
291
+ if (rawEntry && typeof rawEntry === "object" && typeof rawEntry.$ref === "string") {
292
+ names.push(refResolver.decodeJsonPointerSegment(rawEntry.$ref.split("/").pop()));
293
+ } else if (resEntry && typeof resEntry === "object") {
294
+ if (typeof resEntry.type === "string") {
295
+ names.push(resEntry.type);
296
+ } else {
297
+ names.push(...Object.keys(resEntry));
298
+ }
299
+ }
300
+ }
301
+ return names.length > 0 ? names : void 0;
302
+ }
303
+ function parseSpecString(input) {
304
+ const trimmed = input.trim();
305
+ if (trimmed.startsWith("{")) {
306
+ try {
307
+ return JSON.parse(trimmed);
308
+ } catch {
309
+ }
310
+ }
311
+ return refResolver.parse(trimmed);
312
+ }
313
+
314
+ function useAsyncApiSpec(spec) {
315
+ const parser = React.useCallback(async (raw) => {
316
+ return parseAsyncApiSpec(raw);
317
+ }, []);
318
+ return useSpecFetcher.useSpecFetcher(spec, parser);
319
+ }
320
+
321
+ const containerStyle$4 = css.css({
322
+ marginBottom: "2rem",
323
+ paddingBottom: "1.5rem",
324
+ borderBottom: "1px solid var(--omnispec-border-color)"
325
+ });
326
+ const titleStyle$5 = css.css({
327
+ margin: "0 0 0.25rem",
328
+ fontSize: "var(--omnispec-h2-font-size)",
329
+ color: "var(--omnispec-h2-color)",
330
+ fontWeight: 700,
331
+ display: "inline"
332
+ });
333
+ const versionStyle$1 = css.css({
334
+ fontSize: "var(--omnispec-font-size-sm)",
335
+ color: "var(--omnispec-fg-muted)",
336
+ marginLeft: "0.75rem",
337
+ fontFamily: "var(--omnispec-font-mono)"
338
+ });
339
+ const specBadgeStyle = css.css({
340
+ fontSize: "var(--omnispec-font-size-xs)",
341
+ color: "var(--omnispec-color-primary)",
342
+ border: "1px solid var(--omnispec-color-primary)",
343
+ borderRadius: "0.25rem",
344
+ padding: "1px 0.375rem",
345
+ marginLeft: "0.5rem",
346
+ fontFamily: "var(--omnispec-font-mono)"
347
+ });
348
+ const metaStyle = css.css({
349
+ fontSize: "var(--omnispec-font-size-sm)",
350
+ color: "var(--omnispec-fg-secondary)",
351
+ marginTop: "0.25rem"
352
+ });
353
+ const linkStyle = css.css({
354
+ color: "var(--omnispec-fg-link)",
355
+ textDecoration: "none",
356
+ "&:hover": {
357
+ textDecoration: "underline"
358
+ }
359
+ });
360
+ function AsyncOverview({ spec }) {
361
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.cx("omnispec-async-overview", containerStyle$4), children: [
362
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: titleStyle$5, children: spec.title }),
363
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: versionStyle$1, children: [
364
+ "v",
365
+ spec.version
366
+ ] }),
367
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: specBadgeStyle, children: [
368
+ "AsyncAPI ",
369
+ spec.specVersion
370
+ ] }),
371
+ spec.description && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: spec.description }),
372
+ spec.contact && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: metaStyle, children: [
373
+ spec.contact.name && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
374
+ "Contact: ",
375
+ spec.contact.name
376
+ ] }),
377
+ spec.contact.email && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
378
+ " <",
379
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: `mailto:${spec.contact.email}`, className: linkStyle, children: spec.contact.email }),
380
+ ">"
381
+ ] }),
382
+ spec.contact.url && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
383
+ " \xB7 ",
384
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: spec.contact.url, target: "_blank", rel: "noopener noreferrer", className: linkStyle, children: spec.contact.url })
385
+ ] })
386
+ ] }),
387
+ spec.license && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: metaStyle, children: [
388
+ "License: ",
389
+ spec.license.url ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: spec.license.url, target: "_blank", rel: "noopener noreferrer", className: linkStyle, children: spec.license.name }) : spec.license.name
390
+ ] }),
391
+ spec.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: metaStyle, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: spec.externalDocs.url, target: "_blank", rel: "noopener noreferrer", className: linkStyle, children: spec.externalDocs.description ?? "External Documentation" }) })
392
+ ] });
393
+ }
394
+
395
+ const protocolColors = {
396
+ kafka: "#231F20",
397
+ "kafka-secure": "#231F20",
398
+ mqtt: "#660066",
399
+ "mqtt5": "#660066",
400
+ amqp: "#FF6600",
401
+ "amqp1": "#FF6600",
402
+ ws: "#4A90D9",
403
+ wss: "#4A90D9",
404
+ http: "var(--omnispec-color-get)",
405
+ https: "var(--omnispec-color-get)",
406
+ nats: "#27AAE1",
407
+ redis: "#DC382D",
408
+ sns: "#FF9900",
409
+ sqs: "#FF9900",
410
+ stomp: "#6DB33F",
411
+ mercure: "#1D1D1D"
412
+ };
413
+ const badgeBase = css.css({
414
+ display: "inline-block",
415
+ padding: "0.125rem 0.5rem",
416
+ borderRadius: "0.25rem",
417
+ fontSize: "0.625rem",
418
+ fontWeight: 700,
419
+ fontFamily: "var(--omnispec-font-mono)",
420
+ color: "#ffffff",
421
+ letterSpacing: "0.0313rem"
422
+ });
423
+ const versionStyle = css.css({
424
+ fontWeight: 400,
425
+ opacity: 0.8
426
+ });
427
+ function ProtocolBadge({ protocol, version }) {
428
+ const color = protocolColors[protocol.toLowerCase()] ?? "var(--omnispec-fg-muted)";
429
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: css.cx(badgeBase, css.css({ backgroundColor: color })), children: [
430
+ protocol.toUpperCase(),
431
+ version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: versionStyle, children: [
432
+ " ",
433
+ version
434
+ ] })
435
+ ] });
436
+ }
437
+
438
+ function humanizeField(field) {
439
+ const spaced = field.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
440
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
441
+ }
442
+ function renderValue(value) {
443
+ if (value === null) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: mutedStyle, children: "null" });
444
+ if (typeof value === "boolean") return /* @__PURE__ */ jsxRuntime.jsx("code", { className: codeStyle, children: value ? "true" : "false" });
445
+ if (typeof value === "number") return /* @__PURE__ */ jsxRuntime.jsx("code", { className: codeStyle, children: String(value) });
446
+ if (typeof value === "string") return /* @__PURE__ */ jsxRuntime.jsx("span", { children: value });
447
+ return /* @__PURE__ */ jsxRuntime.jsx("code", { className: jsonStyle, children: JSON.stringify(value) });
448
+ }
449
+ function FieldRows({ fields }) {
450
+ if (fields.length === 0) return null;
451
+ return /* @__PURE__ */ jsxRuntime.jsx("dl", { className: listStyle$1, children: fields.map(([field, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rowStyle$1, children: [
452
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: nameStyle$1, children: humanizeField(field) }),
453
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: valueStyle, children: renderValue(value) })
454
+ ] }, field)) });
455
+ }
456
+ const listStyle$1 = css.css({
457
+ display: "grid",
458
+ gridTemplateColumns: "max-content 1fr",
459
+ gap: "0.25rem 1rem",
460
+ margin: "0.25rem 0 0"
461
+ });
462
+ const rowStyle$1 = css.css({ display: "contents" });
463
+ const nameStyle$1 = css.css({
464
+ fontSize: "var(--omnispec-font-size-xs)",
465
+ fontWeight: 600,
466
+ color: "var(--omnispec-fg-secondary)"
467
+ });
468
+ const valueStyle = css.css({
469
+ fontSize: "var(--omnispec-font-size-xs)",
470
+ color: "var(--omnispec-fg-primary)",
471
+ margin: 0,
472
+ minWidth: 0,
473
+ wordBreak: "break-word"
474
+ });
475
+ const codeStyle = css.css({
476
+ fontFamily: "var(--omnispec-font-mono)",
477
+ fontSize: "var(--omnispec-font-size-xs)"
478
+ });
479
+ const jsonStyle = css.css({
480
+ fontFamily: "var(--omnispec-font-mono)",
481
+ fontSize: "var(--omnispec-font-size-xs)",
482
+ color: "var(--omnispec-fg-code)",
483
+ wordBreak: "break-all"
484
+ });
485
+ const mutedStyle = css.css({
486
+ color: "var(--omnispec-fg-muted)"
487
+ });
488
+
489
+ const HIDDEN_KEYS = /* @__PURE__ */ new Set(["bindingVersion"]);
490
+ function BindingsSection({ bindings, title = "Bindings" }) {
491
+ if (!bindings || Object.keys(bindings).length === 0) return null;
492
+ const protocols = Object.entries(bindings).filter(
493
+ ([, cfg]) => cfg && typeof cfg === "object"
494
+ );
495
+ if (protocols.length === 0) return null;
496
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: containerStyle$3, children: [
497
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: titleStyle$4, children: title }),
498
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: protocolListStyle, children: protocols.map(([protocol, cfg]) => {
499
+ const rows = Object.entries(cfg).filter(
500
+ ([key, value]) => !HIDDEN_KEYS.has(key) && value !== void 0
501
+ );
502
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: protocolCardStyle, children: [
503
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: protocolHeaderStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ProtocolBadge, { protocol }) }),
504
+ rows.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FieldRows, { fields: rows }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: emptyStyle, children: "No binding fields." })
505
+ ] }, protocol);
506
+ }) })
507
+ ] });
508
+ }
509
+ const containerStyle$3 = css.css({
510
+ marginTop: "1rem"
511
+ });
512
+ const titleStyle$4 = css.css({
513
+ margin: "0 0 0.75rem",
514
+ fontSize: "var(--omnispec-font-size-md)",
515
+ fontWeight: 700,
516
+ color: "var(--omnispec-fg-primary)",
517
+ letterSpacing: "0.02em"
518
+ });
519
+ const protocolListStyle = css.css({
520
+ display: "flex",
521
+ flexDirection: "column",
522
+ gap: "0.5rem"
523
+ });
524
+ const protocolCardStyle = css.css({
525
+ padding: "0.625rem 0.75rem",
526
+ borderRadius: "var(--omnispec-border-radius)",
527
+ backgroundColor: "var(--omnispec-bg-secondary)"
528
+ });
529
+ const protocolHeaderStyle = css.css({
530
+ marginBottom: "0.5rem"
531
+ });
532
+ const emptyStyle = css.css({
533
+ margin: 0,
534
+ fontSize: "var(--omnispec-font-size-xs)",
535
+ color: "var(--omnispec-fg-muted)"
536
+ });
537
+
538
+ function SecurityRequirementBadges({ names, label = "Security" }) {
539
+ if (!names || names.length === 0) return null;
540
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rowStyle, children: [
541
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: labelStyle, children: label }),
542
+ names.map((name) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: `#security-${name}`, className: badgeStyle, children: [
543
+ /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.Icon, { name: "lock", size: "0.625rem", strokeWidth: 2.5 }),
544
+ name
545
+ ] }, name))
546
+ ] });
547
+ }
548
+ const rowStyle = css.css({
549
+ display: "flex",
550
+ alignItems: "center",
551
+ gap: "0.375rem",
552
+ flexWrap: "wrap",
553
+ marginTop: "0.5rem"
554
+ });
555
+ const labelStyle = css.css({
556
+ fontSize: "var(--omnispec-font-size-xxs)",
557
+ fontWeight: 600,
558
+ textTransform: "uppercase",
559
+ letterSpacing: "0.05em",
560
+ color: "var(--omnispec-fg-muted)"
561
+ });
562
+ const badgeStyle = css.css({
563
+ display: "inline-flex",
564
+ alignItems: "center",
565
+ gap: "0.3125rem",
566
+ fontSize: "var(--omnispec-font-size-xs)",
567
+ fontFamily: "var(--omnispec-font-mono)",
568
+ color: "var(--omnispec-fg-primary)",
569
+ backgroundColor: "var(--omnispec-bg-tertiary)",
570
+ padding: "0.1875rem 0.625rem",
571
+ borderRadius: "var(--omnispec-border-radius)",
572
+ fontWeight: 500,
573
+ textDecoration: "none",
574
+ "&:hover": {
575
+ textDecoration: "underline"
576
+ }
577
+ });
578
+
579
+ const containerStyle$2 = css.css({
580
+ marginBottom: "1.5rem"
581
+ });
582
+ const titleStyle$3 = css.css({
583
+ margin: "0 0 0.75rem",
584
+ fontSize: "var(--omnispec-h3-font-size)",
585
+ color: "var(--omnispec-h3-color)",
586
+ fontWeight: 600
587
+ });
588
+ const tabStripStyle = css.css({
589
+ display: "flex",
590
+ flexWrap: "wrap",
591
+ gap: "0.25rem",
592
+ marginBottom: "0.5rem"
593
+ });
594
+ const tabStyle = css.css({
595
+ padding: "0.25rem 0.75rem",
596
+ border: "none",
597
+ borderRadius: "var(--omnispec-border-radius)",
598
+ backgroundColor: "var(--omnispec-bg-tertiary)",
599
+ color: "var(--omnispec-fg-secondary)",
600
+ fontSize: "var(--omnispec-font-size-sm)",
601
+ fontFamily: "var(--omnispec-font-mono)",
602
+ cursor: "pointer",
603
+ "&:hover": {
604
+ color: "var(--omnispec-fg-primary)"
605
+ }
606
+ });
607
+ const tabActiveStyle = css.css({
608
+ backgroundColor: "var(--omnispec-color-primary)",
609
+ color: "#ffffff",
610
+ "&:hover": {
611
+ color: "#ffffff"
612
+ }
613
+ });
614
+ const cardStyle$1 = css.css({
615
+ padding: "0.75rem",
616
+ border: "1px solid var(--omnispec-border-color)",
617
+ borderRadius: "var(--omnispec-border-radius)",
618
+ backgroundColor: "var(--omnispec-bg-secondary)",
619
+ "&:hover": {
620
+ borderColor: "var(--omnispec-color-primary)"
621
+ }
622
+ });
623
+ const cardHeaderStyle = css.css({
624
+ display: "flex",
625
+ alignItems: "center",
626
+ gap: "0.5rem",
627
+ marginBottom: "0.375rem"
628
+ });
629
+ const serverNameStyle = css.css({
630
+ fontWeight: 600,
631
+ fontSize: "var(--omnispec-font-size-sm)",
632
+ color: "var(--omnispec-fg-primary)"
633
+ });
634
+ const urlStyle = css.css({
635
+ fontFamily: "var(--omnispec-font-mono)",
636
+ fontSize: "var(--omnispec-font-size-sm)",
637
+ color: "var(--omnispec-fg-code)",
638
+ display: "block",
639
+ marginBottom: "0.25rem"
640
+ });
641
+ const descriptionStyle = css.css({
642
+ margin: "0.25rem 0 0",
643
+ fontSize: "var(--omnispec-font-size-xs)",
644
+ color: "var(--omnispec-fg-secondary)"
645
+ });
646
+ const variablesStyle = css.css({
647
+ marginTop: "0.5rem",
648
+ fontSize: "var(--omnispec-font-size-xs)"
649
+ });
650
+ const varRowStyle = css.css({
651
+ display: "flex",
652
+ gap: "0.375rem",
653
+ marginBottom: "0.125rem"
654
+ });
655
+ const varNameStyle = css.css({
656
+ fontFamily: "var(--omnispec-font-mono)",
657
+ color: "var(--omnispec-fg-primary)",
658
+ fontWeight: 600
659
+ });
660
+ const varDefaultStyle = css.css({
661
+ fontFamily: "var(--omnispec-font-mono)",
662
+ color: "var(--omnispec-fg-muted)"
663
+ });
664
+ const varDescStyle = css.css({
665
+ color: "var(--omnispec-fg-secondary)"
666
+ });
667
+ const varEnumStyle = css.css({
668
+ fontFamily: "var(--omnispec-font-mono)",
669
+ color: "var(--omnispec-color-info)"
670
+ });
671
+ const varTokenStyle = css.css({
672
+ color: "var(--omnispec-color-primary)",
673
+ backgroundColor: "color-mix(in srgb, var(--omnispec-color-primary) 12%, transparent)",
674
+ borderRadius: "var(--omnispec-border-radius)",
675
+ padding: "0 0.125rem",
676
+ "&::before": { content: '"{"' },
677
+ "&::after": { content: '"}"' }
678
+ });
679
+ function highlightVariables(url) {
680
+ const parts = url.split(/(\{[^}]+\})/g);
681
+ return parts.map(
682
+ (part, i) => /^\{[^}]+\}$/.test(part) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: varTokenStyle, children: part.slice(1, -1) }, i) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: part }, i)
683
+ );
684
+ }
685
+ function ServerCard({ server }) {
686
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cardStyle$1, children: [
687
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cardHeaderStyle, children: [
688
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: serverNameStyle, children: server.name }),
689
+ /* @__PURE__ */ jsxRuntime.jsx(ProtocolBadge, { protocol: server.protocol, version: server.protocolVersion })
690
+ ] }),
691
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: urlStyle, children: highlightVariables(server.url) }),
692
+ server.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: descriptionStyle, children: server.description }),
693
+ server.variables && Object.entries(server.variables).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: variablesStyle, children: Object.entries(server.variables).map(([name, variable]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: varRowStyle, children: [
694
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: varNameStyle, children: name }),
695
+ variable.default && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: varDefaultStyle, children: [
696
+ "= ",
697
+ variable.default
698
+ ] }),
699
+ variable.enum && variable.enum.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: varEnumStyle, children: [
700
+ "enum: ",
701
+ variable.enum.join(" | ")
702
+ ] }),
703
+ variable.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: varDescStyle, children: variable.description })
704
+ ] }, name)) }),
705
+ /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { names: server.securityNames }),
706
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: server.bindings, title: "Server Bindings" })
707
+ ] });
708
+ }
709
+ function ServerList({ servers }) {
710
+ const [selected, setSelected] = React.useState(0);
711
+ if (servers.length === 0) return null;
712
+ const activeIndex = Math.min(selected, servers.length - 1);
713
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.cx("omnispec-async-servers", containerStyle$2), children: [
714
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: titleStyle$3, children: "Servers" }),
715
+ servers.length > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
716
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tabStripStyle, role: "tablist", "aria-label": "Servers", children: servers.map((server, idx) => /* @__PURE__ */ jsxRuntime.jsx(
717
+ "button",
718
+ {
719
+ type: "button",
720
+ role: "tab",
721
+ "aria-selected": idx === activeIndex,
722
+ className: css.cx(tabStyle, idx === activeIndex && tabActiveStyle),
723
+ onClick: () => setSelected(idx),
724
+ children: server.name
725
+ },
726
+ server.name
727
+ )) }),
728
+ /* @__PURE__ */ jsxRuntime.jsx(ServerCard, { server: servers[activeIndex] })
729
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ServerCard, { server: servers[0] })
730
+ ] });
731
+ }
732
+
733
+ function detectSchemaFormat(schemaFormat) {
734
+ if (!schemaFormat) return "json";
735
+ const f = schemaFormat.toLowerCase();
736
+ if (f.includes("avro")) return "avro";
737
+ if (f.includes("protobuf") || f.includes("proto")) return "protobuf";
738
+ return "json";
739
+ }
740
+ function avroToJsonSchema(avro) {
741
+ return convert(avro);
742
+ }
743
+ function convert(node) {
744
+ if (typeof node === "string") return primitive(node);
745
+ if (Array.isArray(node)) {
746
+ const nonNull = node.filter((n) => n !== "null");
747
+ const nullable = node.length !== nonNull.length;
748
+ if (nonNull.length === 1) {
749
+ return { ...convert(nonNull[0]), nullable };
750
+ }
751
+ return { oneOf: nonNull.map(convert), nullable };
752
+ }
753
+ if (node && typeof node === "object") {
754
+ const obj = node;
755
+ const type = obj.type;
756
+ if (type === "record") {
757
+ const fields = obj.fields ?? [];
758
+ const properties = {};
759
+ const required = [];
760
+ for (const field of fields) {
761
+ const name = field.name;
762
+ const schema = convert(field.type);
763
+ if (field.doc) schema.description = field.doc;
764
+ if (field.default !== void 0) schema.default = field.default;
765
+ properties[name] = schema;
766
+ if (field.default === void 0 && !schema.nullable) required.push(name);
767
+ }
768
+ const result = { type: "object", properties };
769
+ if (obj.doc) result.description = obj.doc;
770
+ if (required.length > 0) result.required = required;
771
+ return result;
772
+ }
773
+ if (type === "enum") {
774
+ return { type: "string", enum: obj.symbols ?? [] };
775
+ }
776
+ if (type === "array") {
777
+ return { type: "array", items: convert(obj.items) };
778
+ }
779
+ if (type === "map") {
780
+ return { type: "object", additionalProperties: convert(obj.values) };
781
+ }
782
+ if (type === "fixed") {
783
+ return { type: "string", format: `fixed(${obj.size ?? "?"})` };
784
+ }
785
+ if (typeof type === "string") {
786
+ const base = primitive(type);
787
+ if (obj.logicalType) base.format = String(obj.logicalType);
788
+ return base;
789
+ }
790
+ if (type && typeof type === "object") return convert(type);
791
+ }
792
+ return { type: "object" };
793
+ }
794
+ const AVRO_PRIMITIVES = {
795
+ null: { type: "null" },
796
+ boolean: { type: "boolean" },
797
+ int: { type: "integer", format: "int32" },
798
+ long: { type: "integer", format: "int64" },
799
+ float: { type: "number", format: "float" },
800
+ double: { type: "number", format: "double" },
801
+ bytes: { type: "string", format: "byte" },
802
+ string: { type: "string" }
803
+ };
804
+ function primitive(name) {
805
+ return { ...AVRO_PRIMITIVES[name] ?? { type: name } };
806
+ }
807
+
808
+ function MessagePayload({ message, idx }) {
809
+ const rawPayload = message.payload;
810
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
811
+ message.schemaFormat && /* @__PURE__ */ jsxRuntime.jsx("span", { className: schemaFormatBadgeStyle, children: message.schemaFormat }),
812
+ rawPayload && /* @__PURE__ */ jsxRuntime.jsx(PayloadBody, { rawPayload, schemaFormat: message.schemaFormat, message, idx })
813
+ ] });
814
+ }
815
+ function PayloadBody({
816
+ rawPayload,
817
+ schemaFormat,
818
+ message,
819
+ idx
820
+ }) {
821
+ if (typeof rawPayload.$ref === "string") {
822
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: unresolvedRefStyle, role: "alert", children: [
823
+ /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.Icon, { name: "warning", size: "0.875rem" }),
824
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
825
+ "Unresolved reference: ",
826
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: unresolvedRefCodeStyle, children: rawPayload.$ref })
827
+ ] })
828
+ ] });
829
+ }
830
+ const schema = detectSchemaFormat(schemaFormat) === "avro" ? avroToJsonSchema(rawPayload) : rawPayload;
831
+ return /* @__PURE__ */ jsxRuntime.jsx(
832
+ Collapsible.Tabs,
833
+ {
834
+ tabs: [
835
+ {
836
+ id: `schema-${idx}`,
837
+ label: "Payload Schema",
838
+ content: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(schema) })
839
+ },
840
+ {
841
+ id: `example-${idx}`,
842
+ label: "Example",
843
+ content: /* @__PURE__ */ jsxRuntime.jsx(MessageExample, { message, schema })
844
+ }
845
+ ]
846
+ }
847
+ );
848
+ }
849
+ function MessageExample({ message, schema }) {
850
+ const named = (message.examples ?? []).filter((ex) => ex.payload !== void 0).map((ex, i) => ({
851
+ name: ex.name ?? `example ${i + 1}`,
852
+ summary: ex.summary,
853
+ value: ex.payload
854
+ }));
855
+ const [selectedName, setSelectedName] = React.useState(named[0]?.name ?? "");
856
+ const active = named.find((ex) => ex.name === selectedName) ?? named[0];
857
+ const exampleSchema = schema ?? message.payload;
858
+ const code = active?.value !== void 0 ? JSON.stringify(active.value, null, 2) : exampleSchema ? JSON.stringify(Collapsible.generateExample(exampleSchema), null, 2) : "{}";
859
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
860
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.ExampleSelector, { examples: named, selectedName: selectedName || (named[0]?.name ?? ""), onSelect: setSelectedName }),
861
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.CodeBlock, { code, language: "json" })
862
+ ] });
863
+ }
864
+ const schemaFormatBadgeStyle = css.css({
865
+ display: "inline-block",
866
+ fontFamily: "var(--omnispec-font-mono)",
867
+ fontSize: "var(--omnispec-font-size-xxs)",
868
+ color: "var(--omnispec-fg-secondary)",
869
+ backgroundColor: "var(--omnispec-bg-tertiary)",
870
+ padding: "0.0625rem 0.375rem",
871
+ borderRadius: "var(--omnispec-border-radius)",
872
+ marginBottom: "0.5rem"
873
+ });
874
+ const unresolvedRefStyle = css.css({
875
+ display: "flex",
876
+ alignItems: "center",
877
+ gap: "0.5rem",
878
+ padding: "0.5rem 0.75rem",
879
+ borderRadius: "var(--omnispec-border-radius)",
880
+ backgroundColor: "color-mix(in srgb, var(--omnispec-color-warning) 12%, transparent)",
881
+ color: "var(--omnispec-color-warning)",
882
+ fontSize: "var(--omnispec-font-size-sm)"
883
+ });
884
+ const unresolvedRefCodeStyle = css.css({
885
+ fontFamily: "var(--omnispec-font-mono)",
886
+ fontSize: "var(--omnispec-font-size-xs)"
887
+ });
888
+
889
+ const actionLabels = {
890
+ publish: "PUB",
891
+ subscribe: "SUB",
892
+ send: "SEND",
893
+ receive: "RECV"
894
+ };
895
+ const actionColors = {
896
+ publish: "var(--omnispec-color-publish)",
897
+ subscribe: "var(--omnispec-color-subscribe)",
898
+ send: "var(--omnispec-color-publish)",
899
+ receive: "var(--omnispec-color-subscribe)"
900
+ };
901
+ function ChannelDetail({ channel, id, expandAll, expandGeneration }) {
902
+ const primaryAction = channel.operations[0]?.action;
903
+ const primaryLabel = actionLabels[primaryAction] ?? primaryAction?.toUpperCase() ?? "";
904
+ const primaryColor = actionColors[primaryAction] ?? "var(--omnispec-fg-muted)";
905
+ return /* @__PURE__ */ jsxRuntime.jsxs(
906
+ Collapsible.ExpandableCard,
907
+ {
908
+ id,
909
+ title: channel.address,
910
+ rightLabel: `${channel.operations.length} ${channel.operations.length === 1 ? "operation" : "operations"}`,
911
+ expandAll,
912
+ expandGeneration,
913
+ children: [
914
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MethodBar, { label: primaryLabel, path: channel.address, color: primaryColor }),
915
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: bodyStyle, children: [
916
+ channel.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: channel.description }) }),
917
+ channel.parameters && Object.keys(channel.parameters).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle, children: [
918
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle, children: "Parameters" }),
919
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: paramListStyle, children: Object.entries(channel.parameters).map(([name, param]) => {
920
+ const schema = param.schema ?? {};
921
+ const paramType = schema.type;
922
+ const paramFormat = schema.format;
923
+ const paramEnum = schema.enum;
924
+ const constraintBadges = Collapsible.buildConstraints(schema);
925
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramRowStyle, children: [
926
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramHeaderStyle, children: [
927
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: paramNameStyle, children: name }),
928
+ paramType && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: typeBadgeStyle$1, children: paramType })
929
+ ] }),
930
+ (paramFormat || constraintBadges.length > 0 || paramEnum && paramEnum.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramConstraintsStyle, children: [
931
+ paramFormat && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: paramFormat }),
932
+ constraintBadges.map((c) => /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: c }, c)),
933
+ paramEnum && paramEnum.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Collapsible.SchemaBadge, { variant: "enum", children: [
934
+ "enum: ",
935
+ paramEnum.map(String).join(" | ")
936
+ ] })
937
+ ] }),
938
+ param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: paramDescStyle, children: param.description })
939
+ ] }, name);
940
+ }) })
941
+ ] }),
942
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: channel.bindings, title: "Channel Bindings" }),
943
+ channel.operations.map((op, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { id: id ? `${id}-op-${idx}` : void 0, className: operationStyle, children: [
944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: opHeaderStyle, children: [
945
+ /* @__PURE__ */ jsxRuntime.jsx(
946
+ "span",
947
+ {
948
+ className: css.cx(actionBadgeBase, css.css({
949
+ backgroundColor: actionColors[op.action] ?? "var(--omnispec-fg-muted)"
950
+ })),
951
+ children: actionLabels[op.action] ?? op.action.toUpperCase()
952
+ }
953
+ ),
954
+ op.operationId && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opIdStyle, children: op.operationId }),
955
+ op.summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opSummaryStyle, children: op.summary })
956
+ ] }),
957
+ op.tags && op.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagChipsStyle, children: op.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: tagChipStyle, title: tag.description, children: tag.name }, tag.name)) }),
958
+ op.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: op.description }) }),
959
+ /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { names: op.securityNames }),
960
+ /* @__PURE__ */ jsxRuntime.jsx(OperationMessages, { operation: op, idx }),
961
+ op.reply && op.reply.messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyStyle, children: [
962
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: replyTitleStyle, children: "Reply" }),
963
+ op.reply.messages.map((replyMsg, i) => /* @__PURE__ */ jsxRuntime.jsx(MessageView, { message: replyMsg, idx: `${idx}-reply-${i}` }, i))
964
+ ] }),
965
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: op.bindings, title: "Operation Bindings" })
966
+ ] }, idx))
967
+ ] })
968
+ ]
969
+ }
970
+ );
971
+ }
972
+ function messageLabel(message, index) {
973
+ return message.title ?? message.name ?? `Message ${index + 1}`;
974
+ }
975
+ function OperationMessages({ operation, idx }) {
976
+ const messages = operation.messages ?? [];
977
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
978
+ if (messages.length === 0) return null;
979
+ const active = messages[Math.min(selectedIndex, messages.length - 1)];
980
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle, children: [
981
+ messages.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: messageSelectorStyle, children: [
982
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `msg-select-${idx}`, className: messageSelectorLabelStyle, children: "Message" }),
983
+ /* @__PURE__ */ jsxRuntime.jsx(
984
+ "select",
985
+ {
986
+ id: `msg-select-${idx}`,
987
+ className: messageSelectStyle,
988
+ value: selectedIndex,
989
+ onChange: (e) => setSelectedIndex(Number(e.target.value)),
990
+ children: messages.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: i, children: messageLabel(m, i) }, i))
991
+ }
992
+ ),
993
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: messageCountStyle, children: [
994
+ messages.length,
995
+ " messages"
996
+ ] })
997
+ ] }),
998
+ /* @__PURE__ */ jsxRuntime.jsx(MessageView, { message: active, idx })
999
+ ] });
1000
+ }
1001
+ function MessageView({ message, idx }) {
1002
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1003
+ /* @__PURE__ */ jsxRuntime.jsxs("h4", { className: sectionTitleStyle, children: [
1004
+ "Message",
1005
+ (message.title ?? message.name) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: messageTitleStyle, children: [
1006
+ " \u2014 ",
1007
+ message.title ?? message.name
1008
+ ] })
1009
+ ] }),
1010
+ message.summary && /* @__PURE__ */ jsxRuntime.jsx("p", { className: messageSummaryStyle$1, children: message.summary }),
1011
+ message.contentType && /* @__PURE__ */ jsxRuntime.jsx("code", { className: contentTypeStyle$1, children: message.contentType }),
1012
+ /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx }),
1013
+ message.correlationId && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: correlationIdStyle, children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: correlationIdLabelStyle, children: "correlationId" }),
1015
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: correlationIdLocationStyle, children: message.correlationId.location }),
1016
+ message.correlationId.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: correlationIdDescStyle, children: message.correlationId.description })
1017
+ ] }),
1018
+ message.headers && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headersWrapStyle, children: [
1019
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle, children: "Headers" }),
1020
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(message.headers) })
1021
+ ] }),
1022
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: message.bindings, title: "Message Bindings" })
1023
+ ] });
1024
+ }
1025
+ const bodyStyle = css.css({
1026
+ padding: "0.75rem 1rem",
1027
+ [useSpecFetcher.mq.desktop]: {
1028
+ padding: "1rem 1.25rem"
1029
+ }
1030
+ });
1031
+ const sectionStyle = css.css({
1032
+ marginBottom: "1.5rem"
1033
+ });
1034
+ const sectionTitleStyle = css.css({
1035
+ margin: "0 0 0.75rem",
1036
+ fontSize: "var(--omnispec-font-size-md)",
1037
+ fontWeight: 700,
1038
+ color: "var(--omnispec-fg-primary)",
1039
+ letterSpacing: "0.02em"
1040
+ });
1041
+ const paramListStyle = css.css({
1042
+ display: "flex",
1043
+ flexDirection: "column"
1044
+ });
1045
+ const paramRowStyle = css.css({
1046
+ padding: "0.75rem 0"
1047
+ });
1048
+ const paramHeaderStyle = css.css({
1049
+ display: "flex",
1050
+ alignItems: "center",
1051
+ gap: "0.5rem",
1052
+ flexWrap: "wrap"
1053
+ });
1054
+ const paramNameStyle = css.css({
1055
+ fontSize: "var(--omnispec-font-size-sm)",
1056
+ fontWeight: 700,
1057
+ backgroundColor: "transparent",
1058
+ padding: 0
1059
+ });
1060
+ const typeBadgeStyle$1 = css.css({
1061
+ fontSize: "var(--omnispec-font-size-xs)",
1062
+ fontWeight: 400
1063
+ });
1064
+ const paramDescStyle = css.css({
1065
+ margin: "0.25rem 0 0",
1066
+ fontSize: "var(--omnispec-font-size-base)",
1067
+ color: "var(--omnispec-fg-secondary)",
1068
+ lineHeight: 1.5
1069
+ });
1070
+ const paramConstraintsStyle = css.css({
1071
+ display: "flex",
1072
+ flexWrap: "wrap",
1073
+ gap: "0.375rem",
1074
+ marginTop: "0.375rem"
1075
+ });
1076
+ const operationStyle = css.css({
1077
+ padding: "0.75rem 0",
1078
+ borderTop: "1px solid var(--omnispec-border-color)"
1079
+ });
1080
+ const opHeaderStyle = css.css({
1081
+ display: "flex",
1082
+ alignItems: "center",
1083
+ gap: "0.5rem",
1084
+ marginBottom: "0.5rem"
1085
+ });
1086
+ const actionBadgeBase = css.css({
1087
+ display: "inline-block",
1088
+ padding: "0.125rem 0.375rem",
1089
+ borderRadius: "0.1875rem",
1090
+ fontSize: "0.5625rem",
1091
+ fontWeight: 700,
1092
+ fontFamily: "var(--omnispec-font-mono)",
1093
+ color: "#ffffff",
1094
+ letterSpacing: "0.0313rem"
1095
+ });
1096
+ const opIdStyle = css.css({
1097
+ fontSize: "var(--omnispec-font-size-sm)",
1098
+ fontWeight: 700,
1099
+ backgroundColor: "transparent",
1100
+ padding: 0
1101
+ });
1102
+ const opSummaryStyle = css.css({
1103
+ fontSize: "var(--omnispec-font-size-sm)",
1104
+ color: "var(--omnispec-fg-secondary)"
1105
+ });
1106
+ const messageTitleStyle = css.css({
1107
+ fontWeight: 400,
1108
+ color: "var(--omnispec-fg-primary)"
1109
+ });
1110
+ const messageSummaryStyle$1 = css.css({
1111
+ margin: "0 0 0.5rem",
1112
+ fontSize: "var(--omnispec-font-size-base)",
1113
+ color: "var(--omnispec-fg-secondary)"
1114
+ });
1115
+ const contentTypeStyle$1 = css.css({
1116
+ fontFamily: "var(--omnispec-font-mono)",
1117
+ fontSize: "var(--omnispec-font-size-xs)",
1118
+ color: "var(--omnispec-fg-muted)",
1119
+ display: "block",
1120
+ marginBottom: "0.5rem",
1121
+ backgroundColor: "transparent",
1122
+ padding: 0
1123
+ });
1124
+ const headersWrapStyle = css.css({
1125
+ marginTop: "1rem"
1126
+ });
1127
+ const messageSelectorStyle = css.css({
1128
+ display: "flex",
1129
+ alignItems: "center",
1130
+ gap: "0.5rem",
1131
+ flexWrap: "wrap",
1132
+ marginBottom: "0.75rem"
1133
+ });
1134
+ const messageSelectorLabelStyle = css.css({
1135
+ fontSize: "var(--omnispec-font-size-xs)",
1136
+ fontWeight: 600,
1137
+ color: "var(--omnispec-fg-muted)",
1138
+ textTransform: "uppercase",
1139
+ letterSpacing: "0.0313rem",
1140
+ whiteSpace: "nowrap"
1141
+ });
1142
+ const messageSelectStyle = css.css({
1143
+ padding: "0.375rem 0.625rem",
1144
+ border: "1px solid var(--omnispec-input-border)",
1145
+ borderRadius: "var(--omnispec-border-radius)",
1146
+ backgroundColor: "var(--omnispec-input-bg)",
1147
+ color: "var(--omnispec-fg-primary)",
1148
+ fontSize: "var(--omnispec-font-size-sm)",
1149
+ fontFamily: "var(--omnispec-font-mono)"
1150
+ });
1151
+ const messageCountStyle = css.css({
1152
+ fontSize: "var(--omnispec-font-size-xs)",
1153
+ color: "var(--omnispec-fg-muted)"
1154
+ });
1155
+ const correlationIdStyle = css.css({
1156
+ display: "flex",
1157
+ alignItems: "center",
1158
+ gap: "0.5rem",
1159
+ flexWrap: "wrap",
1160
+ marginTop: "0.75rem"
1161
+ });
1162
+ const correlationIdLabelStyle = css.css({
1163
+ fontSize: "var(--omnispec-font-size-xs)",
1164
+ fontWeight: 700,
1165
+ color: "var(--omnispec-fg-primary)",
1166
+ fontFamily: "var(--omnispec-font-mono)"
1167
+ });
1168
+ const correlationIdLocationStyle = css.css({
1169
+ fontFamily: "var(--omnispec-font-mono)",
1170
+ fontSize: "var(--omnispec-font-size-xs)",
1171
+ color: "var(--omnispec-fg-code)",
1172
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1173
+ padding: "1px 0.375rem",
1174
+ borderRadius: "0.1875rem"
1175
+ });
1176
+ const correlationIdDescStyle = css.css({
1177
+ fontSize: "var(--omnispec-font-size-xs)",
1178
+ color: "var(--omnispec-fg-secondary)"
1179
+ });
1180
+ const replyStyle = css.css({
1181
+ marginTop: "1rem",
1182
+ paddingLeft: "0.75rem",
1183
+ borderLeft: "0.125rem solid var(--omnispec-border-color)"
1184
+ });
1185
+ const replyTitleStyle = css.css({
1186
+ margin: "0 0 0.5rem",
1187
+ fontSize: "var(--omnispec-font-size-md)",
1188
+ fontWeight: 700,
1189
+ color: "var(--omnispec-fg-primary)",
1190
+ letterSpacing: "0.02em"
1191
+ });
1192
+ const tagChipsStyle = css.css({
1193
+ display: "flex",
1194
+ flexWrap: "wrap",
1195
+ gap: "0.25rem",
1196
+ marginBottom: "0.5rem"
1197
+ });
1198
+ const tagChipStyle = css.css({
1199
+ fontSize: "var(--omnispec-font-size-xxs)",
1200
+ fontFamily: "var(--omnispec-font-mono)",
1201
+ color: "var(--omnispec-fg-secondary)",
1202
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1203
+ padding: "1px 0.5rem",
1204
+ borderRadius: "0.625rem"
1205
+ });
1206
+
1207
+ function ComponentsSection({ components }) {
1208
+ const schemas = Object.entries(components.schemas);
1209
+ const messages = Object.entries(components.messages ?? {});
1210
+ if (schemas.length === 0 && messages.length === 0) return null;
1211
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1212
+ messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `omnispec-async-messages ${containerStyle$1}`, id: "messages", children: [
1213
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: titleStyle$2, children: "Messages" }),
1214
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaWrapperStyle, children: messages.map(([name, message]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaStyle, id: `message-${name}`, children: /* @__PURE__ */ jsxRuntime.jsxs(
1215
+ Collapsible.Collapsible,
1216
+ {
1217
+ title: /* @__PURE__ */ jsxRuntime.jsx("code", { className: schemaNameStyle, children: name }),
1218
+ defaultOpen: false,
1219
+ children: [
1220
+ message.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: messageSummaryStyle, children: message.title }),
1221
+ message.summary && /* @__PURE__ */ jsxRuntime.jsx("p", { className: messageSummaryStyle, children: message.summary }),
1222
+ message.contentType && /* @__PURE__ */ jsxRuntime.jsx("code", { className: contentTypeStyle, children: message.contentType }),
1223
+ /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx: `message-${name}` }),
1224
+ message.headers && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(message.headers) })
1225
+ ]
1226
+ }
1227
+ ) }, name)) })
1228
+ ] }),
1229
+ schemas.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `omnispec-async-components ${containerStyle$1}`, id: "schemas", children: [
1230
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: titleStyle$2, children: "Schemas" }),
1231
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaWrapperStyle, children: schemas.map(([name, schema]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaStyle, id: `schema-${name}`, children: /* @__PURE__ */ jsxRuntime.jsx(
1232
+ Collapsible.Collapsible,
1233
+ {
1234
+ title: /* @__PURE__ */ jsxRuntime.jsx("code", { className: schemaNameStyle, children: name }),
1235
+ defaultOpen: false,
1236
+ children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(schema) })
1237
+ }
1238
+ ) }, name)) })
1239
+ ] })
1240
+ ] });
1241
+ }
1242
+ const containerStyle$1 = css.css({
1243
+ marginTop: "2rem",
1244
+ paddingTop: "1.5rem",
1245
+ borderTop: "1px solid var(--omnispec-border-color)",
1246
+ [useSpecFetcher.mq.mobile]: {
1247
+ borderTop: "none",
1248
+ marginTop: "1.5rem",
1249
+ paddingTop: "1rem"
1250
+ }
1251
+ });
1252
+ const titleStyle$2 = css.css({
1253
+ margin: "0 0 1rem",
1254
+ fontSize: "var(--omnispec-h2-font-size)",
1255
+ color: "var(--omnispec-h2-color)",
1256
+ fontWeight: 700
1257
+ });
1258
+ const schemaWrapperStyle = css.css({
1259
+ border: "1px solid var(--omnispec-border-color)",
1260
+ borderRadius: "0.5rem",
1261
+ padding: "1.5rem 1rem"
1262
+ });
1263
+ const schemaStyle = css.css({
1264
+ marginBottom: "0.5rem"
1265
+ });
1266
+ const schemaNameStyle = css.css({
1267
+ fontFamily: "var(--omnispec-font-mono)",
1268
+ fontSize: "var(--omnispec-font-size-base)",
1269
+ fontWeight: 600,
1270
+ color: "var(--omnispec-color-primary)",
1271
+ backgroundColor: "transparent",
1272
+ padding: 0,
1273
+ "&:hover": {
1274
+ textDecoration: "underline"
1275
+ }
1276
+ });
1277
+ const messageSummaryStyle = css.css({
1278
+ margin: "0 0 0.5rem",
1279
+ fontSize: "var(--omnispec-font-size-sm)",
1280
+ color: "var(--omnispec-fg-secondary)"
1281
+ });
1282
+ const contentTypeStyle = css.css({
1283
+ display: "block",
1284
+ fontFamily: "var(--omnispec-font-mono)",
1285
+ fontSize: "var(--omnispec-font-size-xs)",
1286
+ color: "var(--omnispec-fg-muted)",
1287
+ marginBottom: "0.5rem"
1288
+ });
1289
+
1290
+ const SPECIAL_KEYS = /* @__PURE__ */ new Set(["type", "description", "flows"]);
1291
+ function SecuritySchemesSection({ securitySchemes }) {
1292
+ const entries = Object.entries(securitySchemes ?? {});
1293
+ if (entries.length === 0) return null;
1294
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `omnispec-async-security ${containerStyle}`, id: "security", children: [
1295
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: titleStyle$1, children: "Security Schemes" }),
1296
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: listStyle, children: entries.map(([name, scheme]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cardStyle, id: `security-${name}`, children: [
1297
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headerStyle$1, children: [
1298
+ /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.Icon, { name: "lock", size: "0.875rem" }),
1299
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: nameStyle, children: name }),
1300
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: typeBadgeStyle, children: scheme.type })
1301
+ ] }),
1302
+ scheme.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: descStyle$1, children: scheme.description }),
1303
+ /* @__PURE__ */ jsxRuntime.jsx(
1304
+ FieldRows,
1305
+ {
1306
+ fields: Object.entries(scheme).filter(
1307
+ ([key, value]) => !SPECIAL_KEYS.has(key) && value !== void 0 && typeof value !== "object"
1308
+ )
1309
+ }
1310
+ ),
1311
+ scheme.flows && Object.keys(scheme.flows).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: flowsStyle, children: Object.entries(scheme.flows).map(([flowName, flow]) => /* @__PURE__ */ jsxRuntime.jsx(OAuthFlow, { name: flowName, flow }, flowName)) })
1312
+ ] }, name)) })
1313
+ ] });
1314
+ }
1315
+ function OAuthFlow({ name, flow }) {
1316
+ const scopes = flow.availableScopes ?? flow.scopes ?? {};
1317
+ const urls = Object.entries(flow).filter(
1318
+ ([key, value]) => key !== "availableScopes" && key !== "scopes" && typeof value === "string"
1319
+ );
1320
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: flowCardStyle, children: [
1321
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: flowNameStyle, children: name }),
1322
+ /* @__PURE__ */ jsxRuntime.jsx(FieldRows, { fields: urls }),
1323
+ Object.keys(scopes).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: scopesStyle, children: [
1324
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: scopesLabelStyle, children: "Scopes" }),
1325
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: scopeListStyle, children: Object.entries(scopes).map(([scope, desc]) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: scopeRowStyle, children: [
1326
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: scopeNameStyle, children: scope }),
1327
+ desc && /* @__PURE__ */ jsxRuntime.jsx("span", { className: scopeDescStyle, children: desc })
1328
+ ] }, scope)) })
1329
+ ] })
1330
+ ] });
1331
+ }
1332
+ const containerStyle = css.css({
1333
+ marginTop: "1.5rem",
1334
+ paddingTop: "1rem",
1335
+ [useSpecFetcher.mq.desktop]: {
1336
+ marginTop: "2rem",
1337
+ paddingTop: "1.5rem",
1338
+ borderTop: "1px solid var(--omnispec-border-color)"
1339
+ }
1340
+ });
1341
+ const titleStyle$1 = css.css({
1342
+ margin: "0 0 1rem",
1343
+ fontSize: "var(--omnispec-h2-font-size)",
1344
+ color: "var(--omnispec-h2-color)",
1345
+ fontWeight: 700
1346
+ });
1347
+ const listStyle = css.css({
1348
+ display: "flex",
1349
+ flexDirection: "column",
1350
+ gap: "0.75rem"
1351
+ });
1352
+ const cardStyle = css.css({
1353
+ padding: "0.75rem 0.875rem",
1354
+ borderRadius: "var(--omnispec-border-radius)",
1355
+ backgroundColor: "var(--omnispec-bg-secondary)"
1356
+ });
1357
+ const headerStyle$1 = css.css({
1358
+ display: "flex",
1359
+ alignItems: "center",
1360
+ gap: "0.5rem",
1361
+ marginBottom: "0.375rem"
1362
+ });
1363
+ const nameStyle = css.css({
1364
+ fontFamily: "var(--omnispec-font-mono)",
1365
+ fontSize: "var(--omnispec-font-size-sm)",
1366
+ fontWeight: 700,
1367
+ color: "var(--omnispec-color-primary)",
1368
+ backgroundColor: "transparent",
1369
+ padding: 0
1370
+ });
1371
+ const typeBadgeStyle = css.css({
1372
+ fontSize: "var(--omnispec-font-size-xxs)",
1373
+ fontFamily: "var(--omnispec-font-mono)",
1374
+ color: "var(--omnispec-fg-secondary)",
1375
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1376
+ padding: "0.0625rem 0.375rem",
1377
+ borderRadius: "var(--omnispec-border-radius)"
1378
+ });
1379
+ const descStyle$1 = css.css({
1380
+ margin: "0 0 0.5rem",
1381
+ fontSize: "var(--omnispec-font-size-sm)",
1382
+ color: "var(--omnispec-fg-secondary)"
1383
+ });
1384
+ const flowsStyle = css.css({
1385
+ marginTop: "0.625rem",
1386
+ display: "flex",
1387
+ flexDirection: "column",
1388
+ gap: "0.5rem"
1389
+ });
1390
+ const flowCardStyle = css.css({
1391
+ padding: "0.5rem 0.625rem",
1392
+ borderRadius: "var(--omnispec-border-radius)",
1393
+ backgroundColor: "var(--omnispec-bg-tertiary)"
1394
+ });
1395
+ const flowNameStyle = css.css({
1396
+ fontFamily: "var(--omnispec-font-mono)",
1397
+ fontSize: "var(--omnispec-font-size-xs)",
1398
+ fontWeight: 700,
1399
+ color: "var(--omnispec-fg-primary)"
1400
+ });
1401
+ const scopesStyle = css.css({
1402
+ marginTop: "0.375rem"
1403
+ });
1404
+ const scopesLabelStyle = css.css({
1405
+ fontSize: "var(--omnispec-font-size-xxs)",
1406
+ fontWeight: 600,
1407
+ textTransform: "uppercase",
1408
+ letterSpacing: "0.05em",
1409
+ color: "var(--omnispec-fg-muted)"
1410
+ });
1411
+ const scopeListStyle = css.css({
1412
+ listStyle: "none",
1413
+ margin: "0.25rem 0 0",
1414
+ padding: 0,
1415
+ display: "flex",
1416
+ flexDirection: "column",
1417
+ gap: "0.125rem"
1418
+ });
1419
+ const scopeRowStyle = css.css({
1420
+ display: "flex",
1421
+ gap: "0.5rem",
1422
+ alignItems: "baseline",
1423
+ flexWrap: "wrap"
1424
+ });
1425
+ const scopeNameStyle = css.css({
1426
+ fontFamily: "var(--omnispec-font-mono)",
1427
+ fontSize: "var(--omnispec-font-size-xs)",
1428
+ color: "var(--omnispec-color-primary)"
1429
+ });
1430
+ const scopeDescStyle = css.css({
1431
+ fontSize: "var(--omnispec-font-size-xs)",
1432
+ color: "var(--omnispec-fg-secondary)"
1433
+ });
1434
+
1435
+ const UNTAGGED_LABEL = "Untagged";
1436
+ function slugify(value) {
1437
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "tag";
1438
+ }
1439
+ function channelTagNames(channel) {
1440
+ const names = /* @__PURE__ */ new Set();
1441
+ for (const op of channel.operations) {
1442
+ for (const tag of op.tags ?? []) names.add(tag.name);
1443
+ }
1444
+ return Array.from(names);
1445
+ }
1446
+ function hasAnyTags(channels) {
1447
+ return channels.some((ch) => channelTagNames(ch).length > 0);
1448
+ }
1449
+ function groupChannelsByTag(channels, specTags) {
1450
+ const byName = /* @__PURE__ */ new Map();
1451
+ const untagged = [];
1452
+ for (const channel of channels) {
1453
+ const names = channelTagNames(channel);
1454
+ if (names.length === 0) {
1455
+ untagged.push(channel);
1456
+ continue;
1457
+ }
1458
+ for (const name of names) {
1459
+ const list = byName.get(name) ?? [];
1460
+ list.push(channel);
1461
+ byName.set(name, list);
1462
+ }
1463
+ }
1464
+ const declared = (specTags ?? []).map((t) => t.name);
1465
+ const operationOnly = Array.from(byName.keys()).filter((name) => !declared.includes(name)).sort();
1466
+ const orderedNames = [...declared.filter((name) => byName.has(name)), ...operationOnly];
1467
+ const tagMetaByName = new Map((specTags ?? []).map((t) => [t.name, t]));
1468
+ const usedIds = /* @__PURE__ */ new Set();
1469
+ const uniqueId = (base) => {
1470
+ let id = base;
1471
+ let n = 2;
1472
+ while (usedIds.has(id)) id = `${base}-${n++}`;
1473
+ usedIds.add(id);
1474
+ return id;
1475
+ };
1476
+ const groups = orderedNames.map((name) => ({
1477
+ tag: tagMetaByName.get(name) ?? { name },
1478
+ id: uniqueId(slugify(name)),
1479
+ label: tagMetaByName.get(name)?.displayName ?? name,
1480
+ channels: byName.get(name) ?? []
1481
+ }));
1482
+ if (untagged.length > 0) {
1483
+ groups.push({ tag: void 0, id: uniqueId("untagged"), label: UNTAGGED_LABEL, channels: untagged });
1484
+ }
1485
+ return groups;
1486
+ }
1487
+
1488
+ function TagGroupHeader({ group }) {
1489
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headerStyle, children: [
1490
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: titleStyle, children: [
1491
+ group.label,
1492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: countStyle, children: group.channels.length })
1493
+ ] }),
1494
+ group.tag?.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: descStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: group.tag.description }) }),
1495
+ group.tag?.externalDocs && /* @__PURE__ */ jsxRuntime.jsxs(
1496
+ "a",
1497
+ {
1498
+ href: group.tag.externalDocs.url,
1499
+ target: "_blank",
1500
+ rel: "noopener noreferrer",
1501
+ className: docsStyle,
1502
+ children: [
1503
+ group.tag.externalDocs.description ?? "External docs",
1504
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " \u2197" })
1505
+ ]
1506
+ }
1507
+ )
1508
+ ] });
1509
+ }
1510
+ const headerStyle = css.css({
1511
+ marginBottom: "0.75rem",
1512
+ paddingBottom: "0.5rem",
1513
+ borderBottom: "0.125rem solid var(--omnispec-border-color)"
1514
+ });
1515
+ const titleStyle = css.css({
1516
+ display: "flex",
1517
+ alignItems: "center",
1518
+ gap: "0.625rem",
1519
+ margin: 0,
1520
+ fontSize: "var(--omnispec-h3-font-size)",
1521
+ fontWeight: 800,
1522
+ color: "var(--omnispec-h3-color)"
1523
+ });
1524
+ const countStyle = css.css({
1525
+ fontSize: "var(--omnispec-font-size-xs)",
1526
+ fontWeight: 500,
1527
+ color: "var(--omnispec-fg-muted)",
1528
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1529
+ padding: "0.125rem 0.5rem",
1530
+ borderRadius: "0.625rem",
1531
+ fontFamily: "var(--omnispec-font-mono)"
1532
+ });
1533
+ const descStyle = css.css({
1534
+ marginTop: "0.5rem",
1535
+ fontSize: "var(--omnispec-font-size-sm)",
1536
+ color: "var(--omnispec-fg-secondary)",
1537
+ lineHeight: 1.6
1538
+ });
1539
+ const docsStyle = css.css({
1540
+ display: "inline-flex",
1541
+ alignItems: "center",
1542
+ gap: "0.25rem",
1543
+ marginTop: "0.5rem",
1544
+ fontSize: "var(--omnispec-font-size-xs)",
1545
+ color: "var(--omnispec-fg-link)",
1546
+ textDecoration: "none",
1547
+ "&:hover": {
1548
+ textDecoration: "underline"
1549
+ }
1550
+ });
1551
+
1552
+ function AsyncApiSpec({
1553
+ spec,
1554
+ theme,
1555
+ layout = "sidebar",
1556
+ sidebarPosition = "left",
1557
+ defaultExpandOperations = false,
1558
+ downloadLink,
1559
+ sidebarNav,
1560
+ slots = {},
1561
+ schemaStyle,
1562
+ pro,
1563
+ onSpecLoaded,
1564
+ className
1565
+ }) {
1566
+ const resolvedSchemaStyle = useSpecFetcher.resolveSchemaStyle(schemaStyle, pro?.advancedSchemaStyles ?? false);
1567
+ const { data: parsedSpec, state } = useAsyncApiSpec(spec);
1568
+ const [searchQuery, setSearchQuery] = React.useState("");
1569
+ const [allExpanded, setAllExpanded] = React.useState(defaultExpandOperations);
1570
+ const [expandGeneration, setExpandGeneration] = React.useState(0);
1571
+ const [navGrouping, setNavGrouping] = React.useState("channel");
1572
+ const handleToggleExpand = React.useCallback(() => {
1573
+ setAllExpanded((prev) => !prev);
1574
+ setExpandGeneration((prev) => prev + 1);
1575
+ }, []);
1576
+ React.useMemo(() => {
1577
+ if (parsedSpec && onSpecLoaded) {
1578
+ const major = parseInt(parsedSpec.specVersion.split(".")[0], 10);
1579
+ onSpecLoaded({
1580
+ title: parsedSpec.title,
1581
+ version: parsedSpec.version,
1582
+ type: major >= 3 ? useSpecFetcher.SpecType.ASYNCAPI_3 : useSpecFetcher.SpecType.ASYNCAPI_2
1583
+ });
1584
+ }
1585
+ }, [parsedSpec, onSpecLoaded]);
1586
+ const filteredChannels = React.useMemo(() => {
1587
+ if (!parsedSpec || !searchQuery.trim()) return parsedSpec?.channels ?? [];
1588
+ const q = searchQuery.toLowerCase();
1589
+ return parsedSpec.channels.filter(
1590
+ (ch) => ch.address.toLowerCase().includes(q) || ch.description?.toLowerCase().includes(q) || ch.operations.some(
1591
+ (op) => op.operationId?.toLowerCase().includes(q) || op.summary?.toLowerCase().includes(q) || (op.tags ?? []).some((t) => t.name.toLowerCase().includes(q))
1592
+ )
1593
+ );
1594
+ }, [parsedSpec, searchQuery]);
1595
+ const grouped = React.useMemo(() => hasAnyTags(filteredChannels), [filteredChannels]);
1596
+ const tagGroups = React.useMemo(
1597
+ () => grouped ? groupChannelsByTag(filteredChannels, parsedSpec?.tags) : [],
1598
+ [grouped, filteredChannels, parsedSpec]
1599
+ );
1600
+ const channelDomId = React.useMemo(() => {
1601
+ const map = /* @__PURE__ */ new Map();
1602
+ if (grouped) {
1603
+ for (const group of tagGroups) {
1604
+ for (const ch of group.channels) {
1605
+ if (!map.has(ch.name)) map.set(ch.name, `${group.id}-channel-${ch.name}`);
1606
+ }
1607
+ }
1608
+ } else {
1609
+ for (const ch of filteredChannels) map.set(ch.name, `channel-${ch.name}`);
1610
+ }
1611
+ return map;
1612
+ }, [grouped, tagGroups, filteredChannels]);
1613
+ const operationDomId = React.useCallback(
1614
+ (channelName, idx) => `${channelDomId.get(channelName) ?? `channel-${channelName}`}-op-${idx}`,
1615
+ [channelDomId]
1616
+ );
1617
+ const opToCard = React.useMemo(() => {
1618
+ const map = /* @__PURE__ */ new Map();
1619
+ for (const ch of filteredChannels) {
1620
+ const card = channelDomId.get(ch.name) ?? `channel-${ch.name}`;
1621
+ ch.operations.forEach((_, idx) => map.set(`${card}-op-${idx}`, card));
1622
+ }
1623
+ return map;
1624
+ }, [filteredChannels, channelDomId]);
1625
+ const hasOperations = React.useMemo(
1626
+ () => filteredChannels.some((ch) => ch.operations.length > 0),
1627
+ [filteredChannels]
1628
+ );
1629
+ const navItems = React.useMemo(() => {
1630
+ if (!parsedSpec) return [];
1631
+ const actionLabel = (action) => action.toUpperCase();
1632
+ const actionColor = (action) => action === "subscribe" || action === "receive" ? "var(--omnispec-color-subscribe)" : "var(--omnispec-color-publish)";
1633
+ const channelNavItem = (ch, idPrefix) => ({
1634
+ id: `${idPrefix}channel-${ch.name}`,
1635
+ label: ch.address,
1636
+ badge: ch.operations.map((op) => actionLabel(op.action)).join("/") || void 0,
1637
+ badgeColor: actionColor(ch.operations[0]?.action ?? "")
1638
+ });
1639
+ const operationNavItems = () => filteredChannels.flatMap(
1640
+ (ch) => ch.operations.map((op, idx) => ({
1641
+ id: operationDomId(ch.name, idx),
1642
+ label: op.operationId ?? op.summary ?? `${actionLabel(op.action)} ${ch.address}`,
1643
+ badge: actionLabel(op.action),
1644
+ badgeColor: actionColor(op.action)
1645
+ }))
1646
+ );
1647
+ const tagGroupNavItem = (group) => ({
1648
+ id: `taggroup-${group.id}`,
1649
+ label: group.label,
1650
+ badge: String(group.channels.length),
1651
+ children: group.channels.map((ch) => channelNavItem(ch, `${group.id}-`))
1652
+ });
1653
+ const channelChildren = navGrouping === "operation" ? operationNavItems() : grouped ? nestByTagGroups(tagGroups, parsedSpec.tagGroups, tagGroupNavItem) : filteredChannels.map((ch) => channelNavItem(ch, ""));
1654
+ const items = [];
1655
+ if (parsedSpec.servers.length > 0) {
1656
+ items.push({ id: "servers", label: "Servers" });
1657
+ }
1658
+ items.push({
1659
+ id: "channels",
1660
+ label: navGrouping === "operation" ? "Operations" : "Channels",
1661
+ children: channelChildren
1662
+ });
1663
+ if (Object.keys(parsedSpec.components.messages ?? {}).length > 0) {
1664
+ items.push({
1665
+ id: "messages",
1666
+ label: "Messages",
1667
+ children: Object.keys(parsedSpec.components.messages).map((name) => ({
1668
+ id: `message-${name}`,
1669
+ label: name
1670
+ }))
1671
+ });
1672
+ }
1673
+ if (Object.keys(parsedSpec.components.schemas).length > 0) {
1674
+ items.push({
1675
+ id: "schemas",
1676
+ label: "Schemas",
1677
+ children: Object.keys(parsedSpec.components.schemas).map((name) => ({
1678
+ id: `schema-${name}`,
1679
+ label: name
1680
+ }))
1681
+ });
1682
+ }
1683
+ if (Object.keys(parsedSpec.components.securitySchemes).length > 0) {
1684
+ items.push({ id: "security", label: "Security Schemes" });
1685
+ }
1686
+ return items;
1687
+ }, [parsedSpec, grouped, tagGroups, filteredChannels, navGrouping, operationDomId]);
1688
+ const { navigateTo } = Collapsible.useHashScroll(filteredChannels.length);
1689
+ const handleNavSelect = React.useCallback((id) => {
1690
+ const cardId = opToCard.get(id);
1691
+ if (cardId) {
1692
+ Collapsible.requestExpand(cardId);
1693
+ navigateTo(id);
1694
+ return;
1695
+ }
1696
+ navigateTo(id);
1697
+ }, [navigateTo, opToCard]);
1698
+ const navSectionIds = React.useMemo(() => Collapsible.flattenNavItemIds(navItems), [navItems]);
1699
+ const activeSection = Collapsible.useScrollSpy(navSectionIds);
1700
+ if (state.status === "loading") {
1701
+ return /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `omnispec-asyncapi ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.LoadingScreen, {}) }) });
1702
+ }
1703
+ if (state.status === "error") {
1704
+ return /* @__PURE__ */ jsxRuntime.jsx(
1705
+ useSpecFetcher.SpecStatusScreen,
1706
+ {
1707
+ theme,
1708
+ layout,
1709
+ sidebarPosition,
1710
+ slots,
1711
+ sidebarNav,
1712
+ premiumThemingEnabled: pro?.premiumThemingEnabled ?? false,
1713
+ className: `omnispec-asyncapi ${className ?? ""}`,
1714
+ children: /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.ErrorMessage, { title: "Failed to load specification", message: state.error })
1715
+ }
1716
+ );
1717
+ }
1718
+ if (!parsedSpec) return null;
1719
+ const specNav = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1720
+ /* @__PURE__ */ jsxRuntime.jsx(
1721
+ Collapsible.SearchBar,
1722
+ {
1723
+ placeholder: "Filter channels...",
1724
+ onSearch: setSearchQuery
1725
+ }
1726
+ ),
1727
+ hasOperations && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: groupToggleStyle, role: "group", "aria-label": "Sidebar grouping", children: [
1728
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: groupToggleLabelStyle, children: "Group by" }),
1729
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: groupToggleButtonsStyle, children: [
1730
+ /* @__PURE__ */ jsxRuntime.jsx(
1731
+ "button",
1732
+ {
1733
+ type: "button",
1734
+ className: css.cx(groupToggleButtonStyle, navGrouping === "channel" && groupToggleActiveStyle),
1735
+ "aria-pressed": navGrouping === "channel",
1736
+ "aria-label": "Group by channel",
1737
+ onClick: () => setNavGrouping("channel"),
1738
+ children: "Channel"
1739
+ }
1740
+ ),
1741
+ /* @__PURE__ */ jsxRuntime.jsx(
1742
+ "button",
1743
+ {
1744
+ type: "button",
1745
+ className: css.cx(groupToggleButtonStyle, navGrouping === "operation" && groupToggleActiveStyle),
1746
+ "aria-pressed": navGrouping === "operation",
1747
+ "aria-label": "Group by operation",
1748
+ onClick: () => setNavGrouping("operation"),
1749
+ children: "Operation"
1750
+ }
1751
+ )
1752
+ ] })
1753
+ ] }),
1754
+ /* @__PURE__ */ jsxRuntime.jsx(
1755
+ useSpecFetcher.NavTree,
1756
+ {
1757
+ items: navItems,
1758
+ activeId: activeSection,
1759
+ onSelect: handleNavSelect
1760
+ }
1761
+ )
1762
+ ] });
1763
+ const sidebar = useSpecFetcher.buildSidebar(sidebarNav, specNav);
1764
+ const resolvedDownloadLink = Collapsible.resolveDownloadLink(downloadLink, spec);
1765
+ return /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.ConfigProvider, { config: { allowTryIt: false, layout, sidebarPosition, defaultExpandOperations, schemaStyle: resolvedSchemaStyle, slots, proRenderers: pro?.renderers ?? /* @__PURE__ */ new Map(), premiumThemingEnabled: pro?.premiumThemingEnabled ?? false }, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.ExpandProvider, { expandAll: allExpanded, expandGeneration, children: /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `omnispec-asyncapi ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.ErrorBoundary, { title: "Failed to render this API reference", children: /* @__PURE__ */ jsxRuntime.jsxs(
1766
+ useSpecFetcher.DocLayout,
1767
+ {
1768
+ layout,
1769
+ sidebarPosition,
1770
+ sidebar,
1771
+ sidebarHeader: slots.sidebarHeader,
1772
+ sidebarFooter: slots.sidebarFooter,
1773
+ header: slots.header,
1774
+ footer: slots.footer,
1775
+ children: [
1776
+ /* @__PURE__ */ jsxRuntime.jsx(
1777
+ Collapsible.SpecToolbar,
1778
+ {
1779
+ overview: /* @__PURE__ */ jsxRuntime.jsx(AsyncOverview, { spec: parsedSpec }),
1780
+ expandLabel: "channels",
1781
+ allExpanded,
1782
+ onToggleExpand: handleToggleExpand,
1783
+ downloadLink: resolvedDownloadLink
1784
+ }
1785
+ ),
1786
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id: "servers", children: /* @__PURE__ */ jsxRuntime.jsx(ServerList, { servers: parsedSpec.servers }) }),
1787
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { id: "channels", children: [
1788
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: css.css({ margin: "0 0 1rem", fontSize: "var(--omnispec-h2-font-size)", fontWeight: "var(--omnispec-h2-font-weight)", color: "var(--omnispec-h2-color)" }), children: "Channels" }),
1789
+ filteredChannels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: emptyStateStyle, children: parsedSpec.channels.length === 0 ? "No channels are defined for this API." : "No channels match your filter." }) : grouped ? tagGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("section", { id: `taggroup-${group.id}`, className: tagSectionStyle, children: [
1790
+ /* @__PURE__ */ jsxRuntime.jsx(TagGroupHeader, { group }),
1791
+ group.channels.map((channel) => /* @__PURE__ */ jsxRuntime.jsx(
1792
+ ChannelDetail,
1793
+ {
1794
+ id: `${group.id}-channel-${channel.name}`,
1795
+ channel,
1796
+ expandAll: allExpanded,
1797
+ expandGeneration
1798
+ },
1799
+ `${group.id}-${channel.name}`
1800
+ ))
1801
+ ] }, group.id)) : filteredChannels.map((channel) => /* @__PURE__ */ jsxRuntime.jsx(
1802
+ ChannelDetail,
1803
+ {
1804
+ id: `channel-${channel.name}`,
1805
+ channel,
1806
+ expandAll: allExpanded,
1807
+ expandGeneration
1808
+ },
1809
+ channel.name
1810
+ ))
1811
+ ] }),
1812
+ /* @__PURE__ */ jsxRuntime.jsx(ComponentsSection, { components: parsedSpec.components }),
1813
+ /* @__PURE__ */ jsxRuntime.jsx(SecuritySchemesSection, { securitySchemes: parsedSpec.components.securitySchemes })
1814
+ ]
1815
+ }
1816
+ ) }) }) }) }) });
1817
+ }
1818
+ function nestByTagGroups(groups, xTagGroups, toNav) {
1819
+ if (!xTagGroups?.length) return groups.map(toNav);
1820
+ const byTagName = /* @__PURE__ */ new Map();
1821
+ for (const g of groups) if (g.tag?.name) byTagName.set(g.tag.name, g);
1822
+ const used = /* @__PURE__ */ new Set();
1823
+ const grouped = xTagGroups.map((xg) => {
1824
+ const children = xg.tags.map((t) => byTagName.get(t)).filter((g) => !!g);
1825
+ children.forEach((g) => used.add(g));
1826
+ return {
1827
+ id: `xtaggroup-${xg.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "group"}`,
1828
+ label: xg.name,
1829
+ children: children.map(toNav)
1830
+ };
1831
+ }).filter((item) => (item.children?.length ?? 0) > 0);
1832
+ const leftover = groups.filter((g) => !used.has(g)).map(toNav);
1833
+ return [...grouped, ...leftover];
1834
+ }
1835
+ const emptyStateStyle = css.css({
1836
+ fontSize: "var(--omnispec-font-size-sm)",
1837
+ color: "var(--omnispec-fg-muted)",
1838
+ fontStyle: "italic"
1839
+ });
1840
+ const groupToggleStyle = css.css({
1841
+ display: "flex",
1842
+ alignItems: "center",
1843
+ gap: "0.5rem",
1844
+ padding: "0.5rem 0.75rem 0.25rem",
1845
+ flexWrap: "wrap"
1846
+ });
1847
+ const groupToggleLabelStyle = css.css({
1848
+ fontSize: "var(--omnispec-font-size-xxs)",
1849
+ fontWeight: 600,
1850
+ textTransform: "uppercase",
1851
+ letterSpacing: "0.05em",
1852
+ color: "var(--omnispec-fg-muted)"
1853
+ });
1854
+ const groupToggleButtonsStyle = css.css({
1855
+ display: "inline-flex",
1856
+ borderRadius: "var(--omnispec-border-radius)",
1857
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1858
+ padding: "0.125rem"
1859
+ });
1860
+ const groupToggleButtonStyle = css.css({
1861
+ border: "none",
1862
+ background: "transparent",
1863
+ color: "var(--omnispec-fg-secondary)",
1864
+ fontSize: "var(--omnispec-font-size-xs)",
1865
+ padding: "0.125rem 0.625rem",
1866
+ borderRadius: "calc(var(--omnispec-border-radius) - 1px)",
1867
+ cursor: "pointer"
1868
+ });
1869
+ const groupToggleActiveStyle = css.css({
1870
+ backgroundColor: "var(--omnispec-bg-primary)",
1871
+ color: "var(--omnispec-fg-primary)",
1872
+ fontWeight: 600,
1873
+ boxShadow: "var(--omnispec-shadow-sm, 0 1px 0.125rem rgba(0,0,0,0.1))"
1874
+ });
1875
+ const tagSectionStyle = css.css({
1876
+ marginBottom: "2rem"
1877
+ });
1878
+
1879
+ exports.AsyncApiSpec = AsyncApiSpec;
1880
+ //# sourceMappingURL=AsyncApiSpec-CHvM1swf.js.map