@apiboost/omnispec 1.1.0-next.1 → 1.1.0-next.3

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 (77) hide show
  1. package/dist/cjs/asyncapi/index.js +4 -4
  2. package/dist/cjs/chunks/{AsyncApiSpec-CHvM1swf.js → AsyncApiSpec-BzgUioEK.js} +872 -151
  3. package/dist/cjs/chunks/AsyncApiSpec-BzgUioEK.js.map +1 -0
  4. package/dist/cjs/chunks/{Collapsible-Jlb_vtdW.js → Collapsible-BTWyDBkX.js} +161 -2
  5. package/dist/cjs/chunks/Collapsible-BTWyDBkX.js.map +1 -0
  6. package/dist/cjs/chunks/{ErrorBoundary-c1piU8da.js → ErrorBoundary-CezYgQDG.js} +2 -2
  7. package/dist/cjs/chunks/{ErrorBoundary-c1piU8da.js.map → ErrorBoundary-CezYgQDG.js.map} +1 -1
  8. package/dist/cjs/chunks/{OmniSpecRenderer-Dj6Z6W2J.js → OmniSpecRenderer-CRipDRtC.js} +6 -6
  9. package/dist/cjs/chunks/{OmniSpecRenderer-Dj6Z6W2J.js.map → OmniSpecRenderer-CRipDRtC.js.map} +1 -1
  10. package/dist/cjs/chunks/{OpenApiSpec-BPtXvk7C.js → OpenApiSpec-BOlesoUX.js} +7 -7
  11. package/dist/cjs/chunks/OpenApiSpec-BOlesoUX.js.map +1 -0
  12. package/dist/cjs/chunks/{OpenIdConnectManual-DBP0Do-3.js → OpenIdConnectManual-Bh7tdxoH.js} +3 -162
  13. package/dist/cjs/chunks/OpenIdConnectManual-Bh7tdxoH.js.map +1 -0
  14. package/dist/cjs/chunks/{useSpecDetector-A4OwYrmY.js → useSpecDetector-BemsWW9u.js} +2 -2
  15. package/dist/cjs/chunks/{useSpecDetector-A4OwYrmY.js.map → useSpecDetector-BemsWW9u.js.map} +1 -1
  16. package/dist/cjs/chunks/{useSpecFetcher-BKz1jHTV.js → useSpecFetcher-BAbHnXax.js} +28 -1
  17. package/dist/{esm/chunks/useSpecFetcher-CZvAnU7Z.js.map → cjs/chunks/useSpecFetcher-BAbHnXax.js.map} +1 -1
  18. package/dist/cjs/core/public.js +5 -5
  19. package/dist/cjs/index.js +8 -8
  20. package/dist/cjs/openapi/index.js +5 -5
  21. package/dist/cjs/wc/index.js +4 -4
  22. package/dist/esm/asyncapi/index.js +4 -4
  23. package/dist/esm/chunks/{AsyncApiSpec-BPiA9b5T.js → AsyncApiSpec-B757IIHz.js} +880 -159
  24. package/dist/esm/chunks/AsyncApiSpec-B757IIHz.js.map +1 -0
  25. package/dist/esm/chunks/{Collapsible-0ryLh6wX.js → Collapsible-MyJB2agz.js} +161 -3
  26. package/dist/esm/chunks/Collapsible-MyJB2agz.js.map +1 -0
  27. package/dist/esm/chunks/{ErrorBoundary-posRNrbt.js → ErrorBoundary-9pDlZFfM.js} +2 -2
  28. package/dist/esm/chunks/{ErrorBoundary-posRNrbt.js.map → ErrorBoundary-9pDlZFfM.js.map} +1 -1
  29. package/dist/esm/chunks/{OmniSpecRenderer-yF2Zw_B9.js → OmniSpecRenderer-5RUZx-C7.js} +6 -6
  30. package/dist/esm/chunks/{OmniSpecRenderer-yF2Zw_B9.js.map → OmniSpecRenderer-5RUZx-C7.js.map} +1 -1
  31. package/dist/esm/chunks/{OpenApiSpec-MGJ3oFHZ.js → OpenApiSpec-wm3tH2vF.js} +5 -5
  32. package/dist/esm/chunks/OpenApiSpec-wm3tH2vF.js.map +1 -0
  33. package/dist/esm/chunks/{OpenIdConnectManual-BS-n811Z.js → OpenIdConnectManual-DPmTIIIy.js} +4 -162
  34. package/dist/esm/chunks/OpenIdConnectManual-DPmTIIIy.js.map +1 -0
  35. package/dist/esm/chunks/{useSpecDetector-5SGcKnJx.js → useSpecDetector-BJBNbfN5.js} +2 -2
  36. package/dist/esm/chunks/{useSpecDetector-5SGcKnJx.js.map → useSpecDetector-BJBNbfN5.js.map} +1 -1
  37. package/dist/esm/chunks/{useSpecFetcher-CZvAnU7Z.js → useSpecFetcher-BvVfMuzf.js} +28 -1
  38. package/dist/{cjs/chunks/useSpecFetcher-BKz1jHTV.js.map → esm/chunks/useSpecFetcher-BvVfMuzf.js.map} +1 -1
  39. package/dist/esm/core/public.js +4 -4
  40. package/dist/esm/index.js +8 -8
  41. package/dist/esm/openapi/index.js +5 -5
  42. package/dist/esm/wc/index.js +4 -4
  43. package/dist/types/asyncapi/AsyncApiSpec.d.ts +1 -1
  44. package/dist/types/asyncapi/AsyncApiSpec.d.ts.map +1 -1
  45. package/dist/types/asyncapi/components/AsyncOverview.d.ts.map +1 -1
  46. package/dist/types/asyncapi/components/ChannelDetail.d.ts +6 -1
  47. package/dist/types/asyncapi/components/ChannelDetail.d.ts.map +1 -1
  48. package/dist/types/asyncapi/components/ChannelReferenceDetail.d.ts +35 -0
  49. package/dist/types/asyncapi/components/ChannelReferenceDetail.d.ts.map +1 -0
  50. package/dist/types/asyncapi/components/ComponentsSection.d.ts.map +1 -1
  51. package/dist/types/asyncapi/components/ExternalDocsLink.d.ts +29 -0
  52. package/dist/types/asyncapi/components/ExternalDocsLink.d.ts.map +1 -0
  53. package/dist/types/asyncapi/components/MessagePayload.d.ts.map +1 -1
  54. package/dist/types/asyncapi/components/SecurityRequirementBadges.d.ts +13 -6
  55. package/dist/types/asyncapi/components/SecurityRequirementBadges.d.ts.map +1 -1
  56. package/dist/types/asyncapi/components/TagGroupHeader.d.ts +1 -1
  57. package/dist/types/asyncapi/components/TagGroupHeader.d.ts.map +1 -1
  58. package/dist/types/asyncapi/components/field-display.d.ts +11 -1
  59. package/dist/types/asyncapi/components/field-display.d.ts.map +1 -1
  60. package/dist/types/asyncapi/parser/asyncapi-parser.d.ts.map +1 -1
  61. package/dist/types/asyncapi/tag-grouping.d.ts +5 -1
  62. package/dist/types/asyncapi/tag-grouping.d.ts.map +1 -1
  63. package/dist/types/asyncapi/types/asyncapi.types.d.ts +37 -8
  64. package/dist/types/asyncapi/types/asyncapi.types.d.ts.map +1 -1
  65. package/dist/types/core/components/Layout/DocLayout.d.ts.map +1 -1
  66. package/dist/types/core/types/auth.types.d.ts +1 -1
  67. package/dist/wc/standalone.js +1 -1
  68. package/dist/wc/standalone.js.map +1 -1
  69. package/package.json +1 -1
  70. package/dist/cjs/chunks/AsyncApiSpec-CHvM1swf.js.map +0 -1
  71. package/dist/cjs/chunks/Collapsible-Jlb_vtdW.js.map +0 -1
  72. package/dist/cjs/chunks/OpenApiSpec-BPtXvk7C.js.map +0 -1
  73. package/dist/cjs/chunks/OpenIdConnectManual-DBP0Do-3.js.map +0 -1
  74. package/dist/esm/chunks/AsyncApiSpec-BPiA9b5T.js.map +0 -1
  75. package/dist/esm/chunks/Collapsible-0ryLh6wX.js.map +0 -1
  76. package/dist/esm/chunks/OpenApiSpec-MGJ3oFHZ.js.map +0 -1
  77. package/dist/esm/chunks/OpenIdConnectManual-BS-n811Z.js.map +0 -1
@@ -3,21 +3,13 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
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');
6
+ var useSpecFetcher = require('./useSpecFetcher-BAbHnXax.js');
7
+ var Collapsible = require('./Collapsible-BTWyDBkX.js');
8
+ var ErrorBoundary = require('./ErrorBoundary-CezYgQDG.js');
9
9
  var refResolver = require('./ref-resolver-0A8GNRI3.js');
10
10
  require('@emotion/styled');
11
11
  require('./ssrf-guard-B6T2A7Ho.js');
12
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
13
  function mergeSchema(base, override) {
22
14
  if (!base) return override;
23
15
  if (!override) return base;
@@ -37,9 +29,7 @@ function mergeMessageLayer(base, override) {
37
29
  const result = { ...base };
38
30
  for (const [key, value] of Object.entries(override)) {
39
31
  if (key === "traits" || value === void 0) continue;
40
- if (key === "tags") {
41
- result.tags = unionTags(base.tags, value);
42
- } else if (key === "headers") {
32
+ if (key === "headers") {
43
33
  result.headers = mergeSchema(base.headers, value);
44
34
  } else if (key === "examples") {
45
35
  result.examples = [...base.examples ?? [], ...value ?? []];
@@ -51,19 +41,22 @@ function mergeMessageLayer(base, override) {
51
41
  }
52
42
  return result;
53
43
  }
54
- function applyMessageTraits(msg) {
44
+ function applyMessageTraits(msg, isV3) {
55
45
  if (!msg.traits || msg.traits.length === 0) return msg;
56
- let acc = {};
46
+ if (isV3) {
47
+ let acc2 = {};
48
+ for (const trait of msg.traits) acc2 = mergeMessageLayer(acc2, trait);
49
+ return mergeMessageLayer(acc2, msg);
50
+ }
51
+ let acc = msg;
57
52
  for (const trait of msg.traits) acc = mergeMessageLayer(acc, trait);
58
- return mergeMessageLayer(acc, msg);
53
+ return acc;
59
54
  }
60
55
  function mergeOperationLayer(base, override) {
61
56
  const result = { ...base };
62
57
  for (const [key, value] of Object.entries(override)) {
63
58
  if (key === "traits" || value === void 0) continue;
64
- if (key === "tags") {
65
- result.tags = unionTags(base.tags, value);
66
- } else if (key === "bindings") {
59
+ if (key === "bindings") {
67
60
  result.bindings = { ...base.bindings ?? {}, ...value };
68
61
  } else {
69
62
  result[key] = value;
@@ -71,11 +64,16 @@ function mergeOperationLayer(base, override) {
71
64
  }
72
65
  return result;
73
66
  }
74
- function applyOperationTraits(op) {
67
+ function applyOperationTraits(op, isV3) {
75
68
  if (!op.traits || op.traits.length === 0) return op;
76
- let acc = {};
69
+ if (isV3) {
70
+ let acc2 = {};
71
+ for (const trait of op.traits) acc2 = mergeOperationLayer(acc2, trait);
72
+ return mergeOperationLayer(acc2, op);
73
+ }
74
+ let acc = op;
77
75
  for (const trait of op.traits) acc = mergeOperationLayer(acc, trait);
78
- return mergeOperationLayer(acc, op);
76
+ return acc;
79
77
  }
80
78
  async function parseAsyncApiSpec(specInput) {
81
79
  const raw = typeof specInput === "string" ? parseSpecString(specInput) : specInput;
@@ -84,8 +82,9 @@ async function parseAsyncApiSpec(specInput) {
84
82
  const isV3 = majorVersion >= 3;
85
83
  const servers = extractServers(api, raw);
86
84
  const rawApi = raw;
87
- const channels = isV3 ? extractChannelsV3(api, rawApi) : extractChannelsV2(api);
88
- const components = extractComponents(api);
85
+ const defaultContentType = api.defaultContentType;
86
+ const channels = isV3 ? extractChannelsV3(api, rawApi, defaultContentType) : extractChannelsV2(api, defaultContentType);
87
+ const components = extractComponents(api, isV3, defaultContentType);
89
88
  const root = api;
90
89
  const tags = api.tags?.map((tag) => {
91
90
  const raw2 = tag;
@@ -110,11 +109,13 @@ async function parseAsyncApiSpec(specInput) {
110
109
  contact: api.info.contact,
111
110
  license: api.info.license,
112
111
  termsOfService: api.info.termsOfService,
113
- logo: api.info["x-logo"]
112
+ logo: api.info["x-logo"],
113
+ defaultContentType
114
114
  };
115
115
  }
116
116
  function extractServers(api, rawApi) {
117
117
  if (!api.servers) return [];
118
+ const isV3 = parseInt(api.asyncapi.split(".")[0], 10) >= 3;
118
119
  const toServer = (s, name, rawSecurity) => ({
119
120
  name,
120
121
  url: s.host ? `${s.protocol}://${s.host}${s.pathname ?? ""}` : s.url ?? "",
@@ -124,6 +125,7 @@ function extractServers(api, rawApi) {
124
125
  variables: s.variables,
125
126
  security: s.security,
126
127
  securityNames: deriveSecurityNames(rawSecurity, s.security),
128
+ securityRequirements: deriveSecurityRequirements(rawSecurity, s.security, isV3),
127
129
  bindings: s.bindings
128
130
  });
129
131
  if (Array.isArray(api.servers)) {
@@ -133,15 +135,15 @@ function extractServers(api, rawApi) {
133
135
  const rawServers = !Array.isArray(rawApi.servers) && rawApi.servers || {};
134
136
  return Object.entries(api.servers).map(([name, s]) => toServer(s, name, rawServers[name]?.security));
135
137
  }
136
- function extractChannelsV2(api) {
138
+ function extractChannelsV2(api, defaultContentType) {
137
139
  if (!api.channels) return [];
138
140
  return Object.entries(api.channels).map(([channelName, ch]) => {
139
141
  const operations = [];
140
142
  if (ch.publish) {
141
- operations.push(convertOperationV2("publish", ch.publish));
143
+ operations.push(convertOperationV2("publish", ch.publish, defaultContentType));
142
144
  }
143
145
  if (ch.subscribe) {
144
- operations.push(convertOperationV2("subscribe", ch.subscribe));
146
+ operations.push(convertOperationV2("subscribe", ch.subscribe, defaultContentType));
145
147
  }
146
148
  const raw = ch;
147
149
  return {
@@ -151,20 +153,21 @@ function extractChannelsV2(api) {
151
153
  operations: operations.filter((op) => !op.xInternal),
152
154
  parameters: ch.parameters,
153
155
  bindings: ch.bindings,
156
+ // 2.x channels have no externalDocs or channel-level tags.
154
157
  xInternal: raw["x-internal"]
155
158
  };
156
159
  });
157
160
  }
158
- function convertOperationV2(action, rawOp) {
159
- const op = applyOperationTraits(rawOp);
161
+ function convertOperationV2(action, rawOp, defaultContentType) {
162
+ const op = applyOperationTraits(rawOp, false);
160
163
  const messages = [];
161
164
  if (op.message) {
162
165
  if ("oneOf" in op.message) {
163
166
  for (const m of op.message.oneOf) {
164
- messages.push(convertMessage(m));
167
+ messages.push(convertMessage(m, false, defaultContentType));
165
168
  }
166
169
  } else {
167
- messages.push(convertMessage(op.message));
170
+ messages.push(convertMessage(op.message, false, defaultContentType));
168
171
  }
169
172
  }
170
173
  const raw = op;
@@ -177,7 +180,9 @@ function convertOperationV2(action, rawOp) {
177
180
  message: messages[0],
178
181
  tags: op.tags,
179
182
  bindings: op.bindings,
183
+ externalDocs: op.externalDocs,
180
184
  securityNames: deriveSecurityNames(void 0, op.security),
185
+ securityRequirements: deriveSecurityRequirements(void 0, op.security, false),
181
186
  xBadges: raw["x-badges"],
182
187
  xInternal: raw["x-internal"]
183
188
  };
@@ -194,7 +199,7 @@ function resolveChannelName(rawChannel, resolvedChannel, addressToName) {
194
199
  }
195
200
  return void 0;
196
201
  }
197
- function extractChannelsV3(api, rawApi) {
202
+ function extractChannelsV3(api, rawApi, defaultContentType) {
198
203
  if (!api.channels) return [];
199
204
  const channelMap = /* @__PURE__ */ new Map();
200
205
  const addressToName = /* @__PURE__ */ new Map();
@@ -209,69 +214,108 @@ function extractChannelsV3(api, rawApi) {
209
214
  operations: [],
210
215
  parameters: ch.parameters,
211
216
  bindings: ch.bindings,
217
+ externalDocs: ch.externalDocs,
218
+ tags: ch.tags,
212
219
  xInternal: raw["x-internal"]
213
220
  });
214
221
  }
222
+ const orphanOperations = [];
215
223
  if (api.operations) {
216
224
  for (const [opKey, resolvedOp] of Object.entries(api.operations)) {
217
- const op = applyOperationTraits(resolvedOp);
225
+ const op = applyOperationTraits(resolvedOp, true);
218
226
  const rawOp = rawApi.operations?.[opKey];
219
227
  const channelName = resolveChannelName(rawOp?.channel, op.channel, addressToName);
220
228
  const collectMessages = (list) => {
221
229
  const out = [];
222
230
  for (const msg of list ?? []) {
223
231
  if (msg && typeof msg === "object" && "$ref" in msg) continue;
224
- out.push(convertMessage(msg));
232
+ out.push(convertMessage(msg, true, defaultContentType));
225
233
  }
226
234
  return out;
227
235
  };
228
- const messages = collectMessages(op.messages);
236
+ let messages = collectMessages(op.messages);
237
+ if (messages.length === 0 && channelName && api.channels?.[channelName]?.messages) {
238
+ messages = collectMessages(
239
+ Object.values(api.channels[channelName].messages)
240
+ );
241
+ }
229
242
  const replyMessages = collectMessages(op.reply?.messages);
243
+ const rawReplyChannel = rawOp?.reply?.channel;
244
+ const replyChannelName = resolveChannelName(
245
+ rawReplyChannel,
246
+ op.reply?.channel,
247
+ addressToName
248
+ );
230
249
  const raw = op;
250
+ const reply = replyMessages.length > 0 || op.reply?.address || replyChannelName ? {
251
+ messages: replyMessages,
252
+ address: op.reply?.address,
253
+ channelName: replyChannelName
254
+ } : void 0;
231
255
  const operation = {
232
256
  action: op.action,
257
+ // 3.x has no operationId field; the operations-map key is the id.
258
+ operationId: opKey,
259
+ title: op.title,
233
260
  summary: op.summary,
234
261
  description: op.description,
235
262
  messages,
236
263
  message: messages[0],
237
264
  tags: op.tags,
238
265
  bindings: op.bindings,
266
+ externalDocs: op.externalDocs,
239
267
  securityNames: deriveSecurityNames(rawOp?.security, op.security),
240
- reply: replyMessages.length > 0 ? { messages: replyMessages } : void 0,
268
+ securityRequirements: deriveSecurityRequirements(rawOp?.security, op.security, true),
269
+ reply,
241
270
  xBadges: raw["x-badges"],
242
271
  xInternal: raw["x-internal"]
243
272
  };
244
273
  if (operation.xInternal) continue;
245
274
  if (channelName && channelMap.has(channelName)) {
246
275
  channelMap.get(channelName).operations.push(operation);
276
+ } else {
277
+ orphanOperations.push(operation);
247
278
  }
248
279
  }
249
280
  }
250
- return Array.from(channelMap.values());
281
+ const channels = Array.from(channelMap.values());
282
+ if (orphanOperations.length > 0) {
283
+ channels.push({
284
+ name: "__unassigned__",
285
+ address: "Unassigned operations",
286
+ description: "These operations reference a channel that is not defined in this document.",
287
+ operations: orphanOperations
288
+ });
289
+ }
290
+ return channels;
251
291
  }
252
- function convertMessage(rawMsg) {
253
- const msg = applyMessageTraits(rawMsg);
292
+ function convertMessage(rawMsg, isV3, defaultContentType) {
293
+ const msg = applyMessageTraits(rawMsg, isV3);
294
+ const hasOwnContentType = typeof msg.contentType === "string" && msg.contentType.length > 0;
295
+ const contentType = hasOwnContentType ? msg.contentType : defaultContentType ?? "application/json";
254
296
  return {
255
297
  name: msg.name,
256
298
  title: msg.title,
257
299
  summary: msg.summary,
258
300
  description: msg.description,
259
- contentType: msg.contentType,
301
+ contentType,
302
+ contentTypeInherited: hasOwnContentType ? void 0 : true,
260
303
  schemaFormat: msg.schemaFormat,
261
304
  payload: msg.payload,
262
305
  headers: msg.headers,
263
306
  correlationId: msg.correlationId,
264
307
  tags: msg.tags,
265
308
  examples: msg.examples,
266
- bindings: msg.bindings
309
+ bindings: msg.bindings,
310
+ externalDocs: msg.externalDocs
267
311
  };
268
312
  }
269
- function extractComponents(api) {
313
+ function extractComponents(api, isV3, defaultContentType) {
270
314
  const components = api.components;
271
315
  const rawMessages = api.components?.messages ?? {};
272
316
  const messages = {};
273
317
  for (const [name, msg] of Object.entries(rawMessages)) {
274
- messages[name] = convertMessage(msg);
318
+ messages[name] = convertMessage(msg, isV3, defaultContentType);
275
319
  }
276
320
  return {
277
321
  schemas: api.components?.schemas ?? {},
@@ -300,6 +344,40 @@ function deriveSecurityNames(raw, resolved) {
300
344
  }
301
345
  return names.length > 0 ? names : void 0;
302
346
  }
347
+ function deriveSecurityRequirements(raw, resolved, isV3) {
348
+ const rawArr = raw ?? [];
349
+ const resArr = resolved ?? [];
350
+ const count = Math.max(rawArr.length, resArr.length);
351
+ if (count === 0) return void 0;
352
+ const out = [];
353
+ for (let i = 0; i < count; i++) {
354
+ const rawEntry = rawArr[i];
355
+ const resEntry = resArr[i];
356
+ if (isV3) {
357
+ let name;
358
+ if (rawEntry && typeof rawEntry === "object" && typeof rawEntry.$ref === "string") {
359
+ name = refResolver.decodeJsonPointerSegment(rawEntry.$ref.split("/").pop());
360
+ } else if (resEntry && typeof resEntry.type === "string") {
361
+ name = resEntry.type;
362
+ }
363
+ if (name === void 0) continue;
364
+ const rawScopes = rawEntry?.scopes;
365
+ const resScopes = resEntry?.scopes;
366
+ const scopesSource = Array.isArray(rawScopes) ? rawScopes : Array.isArray(resScopes) ? resScopes : [];
367
+ const scopes = scopesSource.map(String);
368
+ out.push([{ name, scopes }]);
369
+ } else {
370
+ const map = rawEntry ?? resEntry;
371
+ if (!map || typeof map !== "object") continue;
372
+ const inner = Object.entries(map).map(([name, scopes]) => ({
373
+ name,
374
+ scopes: Array.isArray(scopes) ? scopes.map(String) : []
375
+ }));
376
+ if (inner.length > 0) out.push(inner);
377
+ }
378
+ }
379
+ return out.length > 0 ? out : void 0;
380
+ }
303
381
  function parseSpecString(input) {
304
382
  const trimmed = input.trim();
305
383
  if (trimmed.startsWith("{")) {
@@ -318,6 +396,38 @@ function useAsyncApiSpec(spec) {
318
396
  return useSpecFetcher.useSpecFetcher(spec, parser);
319
397
  }
320
398
 
399
+ function ExternalDocsLink({ externalDocs, context, className }) {
400
+ const label = externalDocs.description ?? "External docs";
401
+ const ariaLabel = `${context ? `${context} external docs` : "External docs"}, opens in new tab`;
402
+ return /* @__PURE__ */ jsxRuntime.jsxs(
403
+ "a",
404
+ {
405
+ href: externalDocs.url,
406
+ target: "_blank",
407
+ rel: "noopener noreferrer",
408
+ "aria-label": ariaLabel,
409
+ className: css.cx(linkStyle$1, className),
410
+ children: [
411
+ label,
412
+ /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.Icon, { name: "external-link", size: "0.875em" })
413
+ ]
414
+ }
415
+ );
416
+ }
417
+ const linkStyle$1 = css.css({
418
+ display: "inline-flex",
419
+ alignItems: "center",
420
+ gap: "0.25rem",
421
+ fontSize: "var(--omnispec-font-size-xs)",
422
+ color: "var(--omnispec-fg-link)",
423
+ textDecoration: "none",
424
+ minWidth: 0,
425
+ overflowWrap: "anywhere",
426
+ "&:hover": {
427
+ textDecoration: "underline"
428
+ }
429
+ });
430
+
321
431
  const containerStyle$4 = css.css({
322
432
  marginBottom: "2rem",
323
433
  paddingBottom: "1.5rem",
@@ -388,7 +498,7 @@ function AsyncOverview({ spec }) {
388
498
  "License: ",
389
499
  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
500
  ] }),
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" }) })
501
+ spec.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: metaStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalDocsLink, { externalDocs: spec.externalDocs, context: spec.title ?? "API" }) })
392
502
  ] });
393
503
  }
394
504
 
@@ -436,16 +546,91 @@ function ProtocolBadge({ protocol, version }) {
436
546
  }
437
547
 
438
548
  function humanizeField(field) {
549
+ if (/^x-/i.test(field)) return field;
439
550
  const spaced = field.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
440
551
  return spaced.charAt(0).toUpperCase() + spaced.slice(1);
441
552
  }
553
+ function isPlainObject(value) {
554
+ return typeof value === "object" && value !== null && !Array.isArray(value);
555
+ }
556
+ const JSON_SCHEMA_TYPES = /* @__PURE__ */ new Set([
557
+ "string",
558
+ "number",
559
+ "integer",
560
+ "boolean",
561
+ "object",
562
+ "array",
563
+ "null"
564
+ ]);
565
+ function hasSchemaType(value) {
566
+ const t = value.type;
567
+ if (typeof t === "string") return JSON_SCHEMA_TYPES.has(t);
568
+ if (Array.isArray(t)) return t.every((x) => typeof x === "string" && JSON_SCHEMA_TYPES.has(x));
569
+ return false;
570
+ }
571
+ function isJsonSchema(value) {
572
+ return "properties" in value || "enum" in value || "items" in value || hasSchemaType(value);
573
+ }
574
+ function isScalarArray(value) {
575
+ return value.every(
576
+ (item) => item === null || typeof item !== "object"
577
+ );
578
+ }
442
579
  function renderValue(value) {
443
580
  if (value === null) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: mutedStyle, children: "null" });
444
581
  if (typeof value === "boolean") return /* @__PURE__ */ jsxRuntime.jsx("code", { className: codeStyle, children: value ? "true" : "false" });
445
582
  if (typeof value === "number") return /* @__PURE__ */ jsxRuntime.jsx("code", { className: codeStyle, children: String(value) });
446
583
  if (typeof value === "string") return /* @__PURE__ */ jsxRuntime.jsx("span", { children: value });
584
+ if (Array.isArray(value)) {
585
+ if (value.length === 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: mutedStyle, children: "none" });
586
+ if (isScalarArray(value)) {
587
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { children: value.map((item) => String(item)).join(", ") });
588
+ }
589
+ return /* @__PURE__ */ jsxRuntime.jsx("code", { className: jsonStyle, children: JSON.stringify(value, null, 2) });
590
+ }
591
+ if (isPlainObject(value)) {
592
+ if (isJsonSchema(value)) {
593
+ return /* @__PURE__ */ jsxRuntime.jsx(SchemaValue, { schema: value });
594
+ }
595
+ const nested = Object.entries(value).filter(([, v]) => v !== void 0);
596
+ if (nested.length === 0) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: mutedStyle, children: "none" });
597
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: nestedStyle, children: /* @__PURE__ */ jsxRuntime.jsx(FieldRows, { fields: nested }) });
598
+ }
447
599
  return /* @__PURE__ */ jsxRuntime.jsx("code", { className: jsonStyle, children: JSON.stringify(value) });
448
600
  }
601
+ function SchemaValue({ schema }) {
602
+ const properties = isPlainObject(schema.properties) ? schema.properties : void 0;
603
+ if (properties && Object.keys(properties).length > 0) {
604
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaTableStyle, children: Object.entries(properties).map(([name, propSchema]) => /* @__PURE__ */ jsxRuntime.jsx(
605
+ SchemaRow,
606
+ {
607
+ name,
608
+ schema: isPlainObject(propSchema) ? propSchema : {}
609
+ },
610
+ name
611
+ )) });
612
+ }
613
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: schemaTableStyle, children: /* @__PURE__ */ jsxRuntime.jsx(SchemaLeaf, { schema }) });
614
+ }
615
+ function SchemaRow({ name, schema }) {
616
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: schemaRowStyle, children: [
617
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: schemaNameStyle$1, children: name }),
618
+ /* @__PURE__ */ jsxRuntime.jsx(SchemaLeaf, { schema })
619
+ ] });
620
+ }
621
+ function SchemaLeaf({ schema }) {
622
+ const type = typeof schema.type === "string" ? schema.type : void 0;
623
+ const description = typeof schema.description === "string" ? schema.description : void 0;
624
+ const enumValues = Array.isArray(schema.enum) ? schema.enum : void 0;
625
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: schemaLeafStyle, children: [
626
+ type && /* @__PURE__ */ jsxRuntime.jsx("span", { className: schemaTypeStyle, children: type }),
627
+ description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: schemaDescStyle, children: description }),
628
+ enumValues && enumValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: enumWrapStyle, children: [
629
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: enumLabelStyle, children: "Allowed:" }),
630
+ enumValues.map((v, i) => /* @__PURE__ */ jsxRuntime.jsx("code", { className: enumItemStyle, children: String(v) }, i))
631
+ ] })
632
+ ] });
633
+ }
449
634
  function FieldRows({ fields }) {
450
635
  if (fields.length === 0) return null;
451
636
  return /* @__PURE__ */ jsxRuntime.jsx("dl", { className: listStyle$1, children: fields.map(([field, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rowStyle$1, children: [
@@ -457,7 +642,8 @@ const listStyle$1 = css.css({
457
642
  display: "grid",
458
643
  gridTemplateColumns: "max-content 1fr",
459
644
  gap: "0.25rem 1rem",
460
- margin: "0.25rem 0 0"
645
+ margin: "0.25rem 0 0",
646
+ minWidth: 0
461
647
  });
462
648
  const rowStyle$1 = css.css({ display: "contents" });
463
649
  const nameStyle$1 = css.css({
@@ -470,6 +656,7 @@ const valueStyle = css.css({
470
656
  color: "var(--omnispec-fg-primary)",
471
657
  margin: 0,
472
658
  minWidth: 0,
659
+ overflowWrap: "anywhere",
473
660
  wordBreak: "break-word"
474
661
  });
475
662
  const codeStyle = css.css({
@@ -477,14 +664,82 @@ const codeStyle = css.css({
477
664
  fontSize: "var(--omnispec-font-size-xs)"
478
665
  });
479
666
  const jsonStyle = css.css({
667
+ display: "block",
480
668
  fontFamily: "var(--omnispec-font-mono)",
481
669
  fontSize: "var(--omnispec-font-size-xs)",
482
670
  color: "var(--omnispec-fg-code)",
483
- wordBreak: "break-all"
671
+ margin: 0,
672
+ whiteSpace: "pre",
673
+ overflowX: "auto",
674
+ maxWidth: "100%",
675
+ overflowWrap: "anywhere"
484
676
  });
485
677
  const mutedStyle = css.css({
486
678
  color: "var(--omnispec-fg-muted)"
487
679
  });
680
+ const nestedStyle = css.css({
681
+ minWidth: 0,
682
+ paddingLeft: "0.5rem",
683
+ marginTop: "0.125rem",
684
+ boxShadow: "inset 2px 0 0 0 var(--omnispec-border-color)"
685
+ });
686
+ const schemaTableStyle = css.css({
687
+ display: "flex",
688
+ flexDirection: "column",
689
+ gap: "0.25rem",
690
+ minWidth: 0
691
+ });
692
+ const schemaRowStyle = css.css({
693
+ display: "flex",
694
+ flexDirection: "column",
695
+ gap: "0.125rem",
696
+ minWidth: 0
697
+ });
698
+ const schemaNameStyle$1 = css.css({
699
+ fontFamily: "var(--omnispec-font-mono)",
700
+ fontSize: "var(--omnispec-font-size-xs)",
701
+ fontWeight: 600,
702
+ color: "var(--omnispec-fg-primary)",
703
+ overflowWrap: "anywhere"
704
+ });
705
+ const schemaLeafStyle = css.css({
706
+ display: "flex",
707
+ flexWrap: "wrap",
708
+ alignItems: "baseline",
709
+ gap: "0.375rem",
710
+ minWidth: 0
711
+ });
712
+ const schemaTypeStyle = css.css({
713
+ fontFamily: "var(--omnispec-font-mono)",
714
+ fontSize: "var(--omnispec-font-size-xs)",
715
+ color: "var(--omnispec-fg-code)"
716
+ });
717
+ const schemaDescStyle = css.css({
718
+ fontSize: "var(--omnispec-font-size-xs)",
719
+ color: "var(--omnispec-fg-secondary)",
720
+ overflowWrap: "anywhere",
721
+ wordBreak: "break-word"
722
+ });
723
+ const enumWrapStyle = css.css({
724
+ display: "flex",
725
+ flexWrap: "wrap",
726
+ alignItems: "baseline",
727
+ gap: "0.25rem",
728
+ minWidth: 0
729
+ });
730
+ const enumLabelStyle = css.css({
731
+ fontSize: "var(--omnispec-font-size-xs)",
732
+ color: "var(--omnispec-fg-muted)"
733
+ });
734
+ const enumItemStyle = css.css({
735
+ fontFamily: "var(--omnispec-font-mono)",
736
+ fontSize: "var(--omnispec-font-size-xs)",
737
+ color: "var(--omnispec-fg-code)",
738
+ backgroundColor: "var(--omnispec-bg-tertiary)",
739
+ borderRadius: "var(--omnispec-border-radius)",
740
+ padding: "0.02rem 0.3rem",
741
+ overflowWrap: "anywhere"
742
+ });
488
743
 
489
744
  const HIDDEN_KEYS = /* @__PURE__ */ new Set(["bindingVersion"]);
490
745
  function BindingsSection({ bindings, title = "Bindings" }) {
@@ -535,14 +790,21 @@ const emptyStyle = css.css({
535
790
  color: "var(--omnispec-fg-muted)"
536
791
  });
537
792
 
538
- function SecurityRequirementBadges({ names, label = "Security" }) {
539
- if (!names || names.length === 0) return null;
793
+ function SecurityRequirementBadges({ requirements, label = "Security" }) {
794
+ if (!requirements || requirements.length === 0) return null;
540
795
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rowStyle, children: [
541
796
  /* @__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))
797
+ requirements.map((alternative, altIndex) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
798
+ altIndex > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: orStyle, children: "OR" }),
799
+ alternative.map((scheme) => /* @__PURE__ */ jsxRuntime.jsxs("a", { href: `#security-${scheme.name}`, className: badgeStyle, children: [
800
+ /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.Icon, { name: "lock", size: "0.625rem", strokeWidth: 2.5 }),
801
+ scheme.name,
802
+ scheme.scopes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: scopesStyle$1, children: [
803
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: scopeSepStyle, children: "\xB7" }),
804
+ scheme.scopes.join(", ")
805
+ ] })
806
+ ] }, scheme.name))
807
+ ] }, altIndex))
546
808
  ] });
547
809
  }
548
810
  const rowStyle = css.css({
@@ -554,11 +816,20 @@ const rowStyle = css.css({
554
816
  });
555
817
  const labelStyle = css.css({
556
818
  fontSize: "var(--omnispec-font-size-xxs)",
819
+ lineHeight: 1.5,
557
820
  fontWeight: 600,
558
821
  textTransform: "uppercase",
559
822
  letterSpacing: "0.05em",
560
823
  color: "var(--omnispec-fg-muted)"
561
824
  });
825
+ const orStyle = css.css({
826
+ fontSize: "var(--omnispec-font-size-xxs)",
827
+ lineHeight: 1.5,
828
+ fontWeight: 700,
829
+ textTransform: "uppercase",
830
+ letterSpacing: "0.05em",
831
+ color: "var(--omnispec-fg-muted)"
832
+ });
562
833
  const badgeStyle = css.css({
563
834
  display: "inline-flex",
564
835
  alignItems: "center",
@@ -575,6 +846,15 @@ const badgeStyle = css.css({
575
846
  textDecoration: "underline"
576
847
  }
577
848
  });
849
+ const scopesStyle$1 = css.css({
850
+ display: "inline-flex",
851
+ alignItems: "center",
852
+ gap: "0.3125rem",
853
+ color: "var(--omnispec-fg-secondary)"
854
+ });
855
+ const scopeSepStyle = css.css({
856
+ color: "var(--omnispec-fg-muted)"
857
+ });
578
858
 
579
859
  const containerStyle$2 = css.css({
580
860
  marginBottom: "1.5rem"
@@ -677,9 +957,9 @@ const varTokenStyle = css.css({
677
957
  "&::after": { content: '"}"' }
678
958
  });
679
959
  function highlightVariables(url) {
680
- const parts = url.split(/(\{[^}]+\})/g);
960
+ const parts = url.split(/(\{[^{}]+\})/g);
681
961
  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)
962
+ (part, i) => /^\{[^{}]+\}$/.test(part) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: varTokenStyle, children: part.slice(1, -1) }, i) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: part }, i)
683
963
  );
684
964
  }
685
965
  function ServerCard({ server }) {
@@ -702,7 +982,7 @@ function ServerCard({ server }) {
702
982
  ] }),
703
983
  variable.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: varDescStyle, children: variable.description })
704
984
  ] }, name)) }),
705
- /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { names: server.securityNames }),
985
+ /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { requirements: server.securityRequirements ?? [] }),
706
986
  /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: server.bindings, title: "Server Bindings" })
707
987
  ] });
708
988
  }
@@ -808,6 +1088,14 @@ function primitive(name) {
808
1088
  function MessagePayload({ message, idx }) {
809
1089
  const rawPayload = message.payload;
810
1090
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1091
+ message.tags && message.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagChipsStyle$2, children: message.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: tagChipStyle$2, title: tag.description, children: tag.name }, tag.name)) }),
1092
+ message.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: externalDocsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
1093
+ ExternalDocsLink,
1094
+ {
1095
+ externalDocs: message.externalDocs,
1096
+ context: message.name ?? message.title ?? "message"
1097
+ }
1098
+ ) }),
811
1099
  message.schemaFormat && /* @__PURE__ */ jsxRuntime.jsx("span", { className: schemaFormatBadgeStyle, children: message.schemaFormat }),
812
1100
  rawPayload && /* @__PURE__ */ jsxRuntime.jsx(PayloadBody, { rawPayload, schemaFormat: message.schemaFormat, message, idx })
813
1101
  ] });
@@ -827,7 +1115,14 @@ function PayloadBody({
827
1115
  ] })
828
1116
  ] });
829
1117
  }
830
- const schema = detectSchemaFormat(schemaFormat) === "avro" ? avroToJsonSchema(rawPayload) : rawPayload;
1118
+ const format = detectSchemaFormat(schemaFormat);
1119
+ if (format === "protobuf") {
1120
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1121
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.CodeBlock, { code: JSON.stringify(rawPayload, null, 2), language: "json" }),
1122
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: proNoteStyle, children: "Full Protobuf schema rendering is available in Pro." })
1123
+ ] });
1124
+ }
1125
+ const schema = format === "avro" ? avroToJsonSchema(rawPayload) : rawPayload;
831
1126
  return /* @__PURE__ */ jsxRuntime.jsx(
832
1127
  Collapsible.Tabs,
833
1128
  {
@@ -861,6 +1156,23 @@ function MessageExample({ message, schema }) {
861
1156
  /* @__PURE__ */ jsxRuntime.jsx(Collapsible.CodeBlock, { code, language: "json" })
862
1157
  ] });
863
1158
  }
1159
+ const tagChipsStyle$2 = css.css({
1160
+ display: "flex",
1161
+ flexWrap: "wrap",
1162
+ gap: "0.25rem",
1163
+ marginBottom: "0.5rem"
1164
+ });
1165
+ const tagChipStyle$2 = css.css({
1166
+ fontSize: "var(--omnispec-font-size-xxs)",
1167
+ fontFamily: "var(--omnispec-font-mono)",
1168
+ color: "var(--omnispec-fg-secondary)",
1169
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1170
+ padding: "1px 0.5rem",
1171
+ borderRadius: "0.625rem"
1172
+ });
1173
+ const externalDocsStyle = css.css({
1174
+ marginBottom: "0.5rem"
1175
+ });
864
1176
  const schemaFormatBadgeStyle = css.css({
865
1177
  display: "inline-block",
866
1178
  fontFamily: "var(--omnispec-font-mono)",
@@ -871,6 +1183,12 @@ const schemaFormatBadgeStyle = css.css({
871
1183
  borderRadius: "var(--omnispec-border-radius)",
872
1184
  marginBottom: "0.5rem"
873
1185
  });
1186
+ const proNoteStyle = css.css({
1187
+ margin: "0.375rem 0 0",
1188
+ fontSize: "var(--omnispec-font-size-xxs)",
1189
+ color: "var(--omnispec-fg-muted)",
1190
+ fontStyle: "italic"
1191
+ });
874
1192
  const unresolvedRefStyle = css.css({
875
1193
  display: "flex",
876
1194
  alignItems: "center",
@@ -886,22 +1204,22 @@ const unresolvedRefCodeStyle = css.css({
886
1204
  fontSize: "var(--omnispec-font-size-xs)"
887
1205
  });
888
1206
 
889
- const actionLabels = {
1207
+ const actionLabels$1 = {
890
1208
  publish: "PUB",
891
1209
  subscribe: "SUB",
892
1210
  send: "SEND",
893
1211
  receive: "RECV"
894
1212
  };
895
- const actionColors = {
1213
+ const actionColors$1 = {
896
1214
  publish: "var(--omnispec-color-publish)",
897
1215
  subscribe: "var(--omnispec-color-subscribe)",
898
1216
  send: "var(--omnispec-color-publish)",
899
1217
  receive: "var(--omnispec-color-subscribe)"
900
1218
  };
901
- function ChannelDetail({ channel, id, expandAll, expandGeneration }) {
1219
+ function ChannelDetail({ channel, id, expandAll, expandGeneration, onTagClick }) {
902
1220
  const primaryAction = channel.operations[0]?.action;
903
- const primaryLabel = actionLabels[primaryAction] ?? primaryAction?.toUpperCase() ?? "";
904
- const primaryColor = actionColors[primaryAction] ?? "var(--omnispec-fg-muted)";
1221
+ const primaryLabel = actionLabels$1[primaryAction] ?? primaryAction?.toUpperCase() ?? "";
1222
+ const primaryColor = actionColors$1[primaryAction] ?? "var(--omnispec-fg-muted)";
905
1223
  return /* @__PURE__ */ jsxRuntime.jsxs(
906
1224
  Collapsible.ExpandableCard,
907
1225
  {
@@ -913,21 +1231,22 @@ function ChannelDetail({ channel, id, expandAll, expandGeneration }) {
913
1231
  children: [
914
1232
  /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MethodBar, { label: primaryLabel, path: channel.address, color: primaryColor }),
915
1233
  /* @__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]) => {
1234
+ channel.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle$1, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: channel.description }) }),
1235
+ channel.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle$1, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalDocsLink, { externalDocs: channel.externalDocs, context: channel.address }) }),
1236
+ channel.parameters && Object.keys(channel.parameters).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle$1, children: [
1237
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle$1, children: "Parameters" }),
1238
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: paramListStyle$1, children: Object.entries(channel.parameters).map(([name, param]) => {
920
1239
  const schema = param.schema ?? {};
921
1240
  const paramType = schema.type;
922
1241
  const paramFormat = schema.format;
923
1242
  const paramEnum = schema.enum;
924
1243
  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 })
1244
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramRowStyle$1, children: [
1245
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramHeaderStyle$1, children: [
1246
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: paramNameStyle$1, children: name }),
1247
+ paramType && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: typeBadgeStyle$2, children: paramType })
929
1248
  ] }),
930
- (paramFormat || constraintBadges.length > 0 || paramEnum && paramEnum.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramConstraintsStyle, children: [
1249
+ (paramFormat || constraintBadges.length > 0 || paramEnum && paramEnum.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramConstraintsStyle$1, children: [
931
1250
  paramFormat && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: paramFormat }),
932
1251
  constraintBadges.map((c) => /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: c }, c)),
933
1252
  paramEnum && paramEnum.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Collapsible.SchemaBadge, { variant: "enum", children: [
@@ -935,31 +1254,60 @@ function ChannelDetail({ channel, id, expandAll, expandGeneration }) {
935
1254
  paramEnum.map(String).join(" | ")
936
1255
  ] })
937
1256
  ] }),
938
- param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: paramDescStyle, children: param.description })
1257
+ param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: paramDescStyle$1, children: param.description })
939
1258
  ] }, name);
940
1259
  }) })
941
1260
  ] }),
942
1261
  /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: channel.bindings, title: "Channel Bindings" }),
943
1262
  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: [
1263
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: opHeaderStyle$1, children: [
945
1264
  /* @__PURE__ */ jsxRuntime.jsx(
946
1265
  "span",
947
1266
  {
948
- className: css.cx(actionBadgeBase, css.css({
949
- backgroundColor: actionColors[op.action] ?? "var(--omnispec-fg-muted)"
1267
+ className: css.cx(actionBadgeBase$1, css.css({
1268
+ backgroundColor: actionColors$1[op.action] ?? "var(--omnispec-fg-muted)"
950
1269
  })),
951
- children: actionLabels[op.action] ?? op.action.toUpperCase()
1270
+ children: actionLabels$1[op.action] ?? op.action.toUpperCase()
952
1271
  }
953
1272
  ),
954
- op.operationId && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opIdStyle, children: op.operationId }),
955
- op.summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opSummaryStyle, children: op.summary })
1273
+ op.operationId && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opIdStyle$1, children: op.operationId }),
1274
+ op.title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opTitleStyle$1, children: op.title }),
1275
+ op.summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opSummaryStyle$1, children: op.summary })
956
1276
  ] }),
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 }),
1277
+ op.tags && op.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagChipsStyle$1, children: op.tags.map(
1278
+ (tag) => onTagClick ? /* @__PURE__ */ jsxRuntime.jsx(
1279
+ "button",
1280
+ {
1281
+ type: "button",
1282
+ className: tagChipButtonStyle$1,
1283
+ title: tag.description,
1284
+ onClick: () => onTagClick(tag.name),
1285
+ children: tag.name
1286
+ },
1287
+ tag.name
1288
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: tagChipStyle$1, title: tag.description, children: tag.name }, tag.name)
1289
+ ) }),
1290
+ op.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle$1, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: op.description }) }),
1291
+ op.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: opExternalDocsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
1292
+ ExternalDocsLink,
1293
+ {
1294
+ externalDocs: op.externalDocs,
1295
+ context: op.operationId ?? op.summary ?? "operation"
1296
+ }
1297
+ ) }),
1298
+ /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { requirements: op.securityRequirements ?? [] }),
960
1299
  /* @__PURE__ */ jsxRuntime.jsx(OperationMessages, { operation: op, idx }),
961
- op.reply && op.reply.messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyStyle, children: [
1300
+ op.reply && (op.reply.messages.length > 0 || op.reply.address || op.reply.channelName) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyStyle$1, children: [
962
1301
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: replyTitleStyle, children: "Reply" }),
1302
+ op.reply.channelName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyMetaRowStyle, children: [
1303
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: replyMetaLabelStyle, children: "channel" }),
1304
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: replyMetaValueStyle, children: op.reply.channelName })
1305
+ ] }),
1306
+ op.reply.address && (op.reply.address.location || op.reply.address.description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyMetaRowStyle, children: [
1307
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: replyMetaLabelStyle, children: "address" }),
1308
+ op.reply.address.location && /* @__PURE__ */ jsxRuntime.jsx("code", { className: replyMetaValueStyle, children: op.reply.address.location }),
1309
+ op.reply.address.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: replyMetaDescStyle, children: op.reply.address.description })
1310
+ ] }),
963
1311
  op.reply.messages.map((replyMsg, i) => /* @__PURE__ */ jsxRuntime.jsx(MessageView, { message: replyMsg, idx: `${idx}-reply-${i}` }, i))
964
1312
  ] }),
965
1313
  /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: op.bindings, title: "Operation Bindings" })
@@ -977,7 +1325,7 @@ function OperationMessages({ operation, idx }) {
977
1325
  const [selectedIndex, setSelectedIndex] = React.useState(0);
978
1326
  if (messages.length === 0) return null;
979
1327
  const active = messages[Math.min(selectedIndex, messages.length - 1)];
980
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle, children: [
1328
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle$1, children: [
981
1329
  messages.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: messageSelectorStyle, children: [
982
1330
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `msg-select-${idx}`, className: messageSelectorLabelStyle, children: "Message" }),
983
1331
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1000,23 +1348,23 @@ function OperationMessages({ operation, idx }) {
1000
1348
  }
1001
1349
  function MessageView({ message, idx }) {
1002
1350
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1003
- /* @__PURE__ */ jsxRuntime.jsxs("h4", { className: sectionTitleStyle, children: [
1351
+ /* @__PURE__ */ jsxRuntime.jsxs("h4", { className: sectionTitleStyle$1, children: [
1004
1352
  "Message",
1005
- (message.title ?? message.name) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: messageTitleStyle, children: [
1353
+ (message.title ?? message.name) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: messageTitleStyle$1, children: [
1006
1354
  " \u2014 ",
1007
1355
  message.title ?? message.name
1008
1356
  ] })
1009
1357
  ] }),
1010
1358
  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 }),
1359
+ message.contentType && /* @__PURE__ */ jsxRuntime.jsx("code", { className: contentTypeStyle$2, children: message.contentType }),
1012
1360
  /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx }),
1013
1361
  message.correlationId && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: correlationIdStyle, children: [
1014
1362
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: correlationIdLabelStyle, children: "correlationId" }),
1015
1363
  /* @__PURE__ */ jsxRuntime.jsx("code", { className: correlationIdLocationStyle, children: message.correlationId.location }),
1016
1364
  message.correlationId.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: correlationIdDescStyle, children: message.correlationId.description })
1017
1365
  ] }),
1018
- message.headers && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headersWrapStyle, children: [
1019
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle, children: "Headers" }),
1366
+ message.headers && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headersWrapStyle$1, children: [
1367
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle$1, children: "Headers" }),
1020
1368
  /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(message.headers) })
1021
1369
  ] }),
1022
1370
  /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: message.bindings, title: "Message Bindings" })
@@ -1028,46 +1376,46 @@ const bodyStyle = css.css({
1028
1376
  padding: "1rem 1.25rem"
1029
1377
  }
1030
1378
  });
1031
- const sectionStyle = css.css({
1379
+ const sectionStyle$1 = css.css({
1032
1380
  marginBottom: "1.5rem"
1033
1381
  });
1034
- const sectionTitleStyle = css.css({
1382
+ const sectionTitleStyle$1 = css.css({
1035
1383
  margin: "0 0 0.75rem",
1036
1384
  fontSize: "var(--omnispec-font-size-md)",
1037
1385
  fontWeight: 700,
1038
1386
  color: "var(--omnispec-fg-primary)",
1039
1387
  letterSpacing: "0.02em"
1040
1388
  });
1041
- const paramListStyle = css.css({
1389
+ const paramListStyle$1 = css.css({
1042
1390
  display: "flex",
1043
1391
  flexDirection: "column"
1044
1392
  });
1045
- const paramRowStyle = css.css({
1393
+ const paramRowStyle$1 = css.css({
1046
1394
  padding: "0.75rem 0"
1047
1395
  });
1048
- const paramHeaderStyle = css.css({
1396
+ const paramHeaderStyle$1 = css.css({
1049
1397
  display: "flex",
1050
1398
  alignItems: "center",
1051
1399
  gap: "0.5rem",
1052
1400
  flexWrap: "wrap"
1053
1401
  });
1054
- const paramNameStyle = css.css({
1402
+ const paramNameStyle$1 = css.css({
1055
1403
  fontSize: "var(--omnispec-font-size-sm)",
1056
1404
  fontWeight: 700,
1057
1405
  backgroundColor: "transparent",
1058
1406
  padding: 0
1059
1407
  });
1060
- const typeBadgeStyle$1 = css.css({
1408
+ const typeBadgeStyle$2 = css.css({
1061
1409
  fontSize: "var(--omnispec-font-size-xs)",
1062
1410
  fontWeight: 400
1063
1411
  });
1064
- const paramDescStyle = css.css({
1412
+ const paramDescStyle$1 = css.css({
1065
1413
  margin: "0.25rem 0 0",
1066
1414
  fontSize: "var(--omnispec-font-size-base)",
1067
1415
  color: "var(--omnispec-fg-secondary)",
1068
1416
  lineHeight: 1.5
1069
1417
  });
1070
- const paramConstraintsStyle = css.css({
1418
+ const paramConstraintsStyle$1 = css.css({
1071
1419
  display: "flex",
1072
1420
  flexWrap: "wrap",
1073
1421
  gap: "0.375rem",
@@ -1077,13 +1425,13 @@ const operationStyle = css.css({
1077
1425
  padding: "0.75rem 0",
1078
1426
  borderTop: "1px solid var(--omnispec-border-color)"
1079
1427
  });
1080
- const opHeaderStyle = css.css({
1428
+ const opHeaderStyle$1 = css.css({
1081
1429
  display: "flex",
1082
1430
  alignItems: "center",
1083
1431
  gap: "0.5rem",
1084
1432
  marginBottom: "0.5rem"
1085
1433
  });
1086
- const actionBadgeBase = css.css({
1434
+ const actionBadgeBase$1 = css.css({
1087
1435
  display: "inline-block",
1088
1436
  padding: "0.125rem 0.375rem",
1089
1437
  borderRadius: "0.1875rem",
@@ -1093,17 +1441,25 @@ const actionBadgeBase = css.css({
1093
1441
  color: "#ffffff",
1094
1442
  letterSpacing: "0.0313rem"
1095
1443
  });
1096
- const opIdStyle = css.css({
1444
+ const opIdStyle$1 = css.css({
1097
1445
  fontSize: "var(--omnispec-font-size-sm)",
1098
1446
  fontWeight: 700,
1099
1447
  backgroundColor: "transparent",
1100
1448
  padding: 0
1101
1449
  });
1102
- const opSummaryStyle = css.css({
1450
+ const opTitleStyle$1 = css.css({
1451
+ fontSize: "var(--omnispec-font-size-sm)",
1452
+ fontWeight: 600,
1453
+ color: "var(--omnispec-fg-primary)"
1454
+ });
1455
+ const opSummaryStyle$1 = css.css({
1103
1456
  fontSize: "var(--omnispec-font-size-sm)",
1104
1457
  color: "var(--omnispec-fg-secondary)"
1105
1458
  });
1106
- const messageTitleStyle = css.css({
1459
+ const opExternalDocsStyle = css.css({
1460
+ marginBottom: "0.75rem"
1461
+ });
1462
+ const messageTitleStyle$1 = css.css({
1107
1463
  fontWeight: 400,
1108
1464
  color: "var(--omnispec-fg-primary)"
1109
1465
  });
@@ -1112,7 +1468,7 @@ const messageSummaryStyle$1 = css.css({
1112
1468
  fontSize: "var(--omnispec-font-size-base)",
1113
1469
  color: "var(--omnispec-fg-secondary)"
1114
1470
  });
1115
- const contentTypeStyle$1 = css.css({
1471
+ const contentTypeStyle$2 = css.css({
1116
1472
  fontFamily: "var(--omnispec-font-mono)",
1117
1473
  fontSize: "var(--omnispec-font-size-xs)",
1118
1474
  color: "var(--omnispec-fg-muted)",
@@ -1121,7 +1477,7 @@ const contentTypeStyle$1 = css.css({
1121
1477
  backgroundColor: "transparent",
1122
1478
  padding: 0
1123
1479
  });
1124
- const headersWrapStyle = css.css({
1480
+ const headersWrapStyle$1 = css.css({
1125
1481
  marginTop: "1rem"
1126
1482
  });
1127
1483
  const messageSelectorStyle = css.css({
@@ -1177,7 +1533,7 @@ const correlationIdDescStyle = css.css({
1177
1533
  fontSize: "var(--omnispec-font-size-xs)",
1178
1534
  color: "var(--omnispec-fg-secondary)"
1179
1535
  });
1180
- const replyStyle = css.css({
1536
+ const replyStyle$1 = css.css({
1181
1537
  marginTop: "1rem",
1182
1538
  paddingLeft: "0.75rem",
1183
1539
  borderLeft: "0.125rem solid var(--omnispec-border-color)"
@@ -1189,6 +1545,320 @@ const replyTitleStyle = css.css({
1189
1545
  color: "var(--omnispec-fg-primary)",
1190
1546
  letterSpacing: "0.02em"
1191
1547
  });
1548
+ const replyMetaRowStyle = css.css({
1549
+ display: "flex",
1550
+ alignItems: "center",
1551
+ gap: "0.5rem",
1552
+ flexWrap: "wrap",
1553
+ marginBottom: "0.5rem"
1554
+ });
1555
+ const replyMetaLabelStyle = css.css({
1556
+ fontSize: "var(--omnispec-font-size-xs)",
1557
+ fontWeight: 700,
1558
+ color: "var(--omnispec-fg-primary)",
1559
+ fontFamily: "var(--omnispec-font-mono)"
1560
+ });
1561
+ const replyMetaValueStyle = css.css({
1562
+ fontFamily: "var(--omnispec-font-mono)",
1563
+ fontSize: "var(--omnispec-font-size-xs)",
1564
+ color: "var(--omnispec-fg-code)",
1565
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1566
+ padding: "1px 0.375rem",
1567
+ borderRadius: "0.1875rem"
1568
+ });
1569
+ const replyMetaDescStyle = css.css({
1570
+ fontSize: "var(--omnispec-font-size-xs)",
1571
+ color: "var(--omnispec-fg-secondary)"
1572
+ });
1573
+ const tagChipsStyle$1 = css.css({
1574
+ display: "flex",
1575
+ flexWrap: "wrap",
1576
+ gap: "0.25rem",
1577
+ marginBottom: "0.5rem"
1578
+ });
1579
+ const tagChipStyle$1 = css.css({
1580
+ fontSize: "var(--omnispec-font-size-xxs)",
1581
+ fontFamily: "var(--omnispec-font-mono)",
1582
+ color: "var(--omnispec-fg-secondary)",
1583
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1584
+ padding: "1px 0.5rem",
1585
+ borderRadius: "0.625rem"
1586
+ });
1587
+ const tagChipButtonStyle$1 = css.css({
1588
+ fontSize: "var(--omnispec-font-size-xxs)",
1589
+ fontFamily: "var(--omnispec-font-mono)",
1590
+ color: "var(--omnispec-fg-secondary)",
1591
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1592
+ padding: "1px 0.5rem",
1593
+ borderRadius: "0.625rem",
1594
+ border: "none",
1595
+ cursor: "pointer",
1596
+ "&:hover": {
1597
+ color: "var(--omnispec-fg-primary)"
1598
+ }
1599
+ });
1600
+
1601
+ const actionLabels = {
1602
+ publish: "PUB",
1603
+ subscribe: "SUB",
1604
+ send: "SEND",
1605
+ receive: "RECV"
1606
+ };
1607
+ const actionColors = {
1608
+ publish: "var(--omnispec-color-publish)",
1609
+ subscribe: "var(--omnispec-color-subscribe)",
1610
+ send: "var(--omnispec-color-publish)",
1611
+ receive: "var(--omnispec-color-subscribe)"
1612
+ };
1613
+ function ChannelReferenceDetail({ channel, id, expandAll, expandGeneration, onTagClick }) {
1614
+ const primaryAction = channel.operations[0]?.action;
1615
+ const primaryLabel = actionLabels[primaryAction] ?? primaryAction?.toUpperCase() ?? "";
1616
+ const primaryColor = actionColors[primaryAction] ?? "var(--omnispec-fg-muted)";
1617
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1618
+ Collapsible.ExpandableCard,
1619
+ {
1620
+ id,
1621
+ title: channel.address,
1622
+ rightLabel: `${channel.operations.length} ${channel.operations.length === 1 ? "operation" : "operations"}`,
1623
+ expandAll,
1624
+ expandGeneration,
1625
+ children: [
1626
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MethodBar, { label: primaryLabel, path: channel.address, color: primaryColor }),
1627
+ channel.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: channelMetaStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: channel.description }) }),
1628
+ channel.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: channelMetaStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalDocsLink, { externalDocs: channel.externalDocs, context: channel.address }) }),
1629
+ channel.operations.map((op, idx) => /* @__PURE__ */ jsxRuntime.jsx("div", { id: id ? `${id}-op-${idx}` : void 0, className: operationWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
1630
+ Collapsible.ReferenceLayout,
1631
+ {
1632
+ operationId: op.operationId ?? `${channel.name}-op-${idx}`,
1633
+ schema: /* @__PURE__ */ jsxRuntime.jsx(
1634
+ OperationSchemaColumn,
1635
+ {
1636
+ channel,
1637
+ operation: op,
1638
+ onTagClick
1639
+ }
1640
+ ),
1641
+ samples: /* @__PURE__ */ jsxRuntime.jsx(OperationSamplesColumn, { operation: op, idx }),
1642
+ tryIt: /* @__PURE__ */ jsxRuntime.jsx("div", { className: tryItNaStyle, children: "Interactive testing is not available for AsyncAPI protocols." })
1643
+ }
1644
+ ) }, idx))
1645
+ ]
1646
+ }
1647
+ );
1648
+ }
1649
+ function OperationSchemaColumn({
1650
+ channel,
1651
+ operation,
1652
+ onTagClick
1653
+ }) {
1654
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1655
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: opHeaderStyle, children: [
1656
+ /* @__PURE__ */ jsxRuntime.jsx(
1657
+ "span",
1658
+ {
1659
+ className: css.cx(actionBadgeBase, css.css({
1660
+ backgroundColor: actionColors[operation.action] ?? "var(--omnispec-fg-muted)"
1661
+ })),
1662
+ children: actionLabels[operation.action] ?? operation.action.toUpperCase()
1663
+ }
1664
+ ),
1665
+ operation.operationId && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opIdStyle, children: operation.operationId }),
1666
+ operation.title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opTitleStyle, children: operation.title }),
1667
+ operation.summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: opSummaryStyle, children: operation.summary })
1668
+ ] }),
1669
+ operation.tags && operation.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagChipsStyle, children: operation.tags.map(
1670
+ (tag) => onTagClick ? /* @__PURE__ */ jsxRuntime.jsx(
1671
+ "button",
1672
+ {
1673
+ type: "button",
1674
+ className: tagChipButtonStyle,
1675
+ title: tag.description,
1676
+ onClick: () => onTagClick(tag.name),
1677
+ children: tag.name
1678
+ },
1679
+ tag.name
1680
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: tagChipStyle, title: tag.description, children: tag.name }, tag.name)
1681
+ ) }),
1682
+ operation.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Collapsible.MarkdownRenderer, { content: operation.description }) }),
1683
+ operation.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
1684
+ ExternalDocsLink,
1685
+ {
1686
+ externalDocs: operation.externalDocs,
1687
+ context: operation.operationId ?? operation.summary ?? "operation"
1688
+ }
1689
+ ) }),
1690
+ channel.parameters && Object.keys(channel.parameters).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sectionStyle, children: [
1691
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle, children: "Parameters" }),
1692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: paramListStyle, children: Object.entries(channel.parameters).map(([name, param]) => {
1693
+ const schema = param.schema ?? {};
1694
+ const paramType = schema.type;
1695
+ const paramFormat = schema.format;
1696
+ const paramEnum = schema.enum;
1697
+ const constraintBadges = Collapsible.buildConstraints(schema);
1698
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramRowStyle, children: [
1699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramHeaderStyle, children: [
1700
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: paramNameStyle, children: name }),
1701
+ paramType && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: typeBadgeStyle$1, children: paramType })
1702
+ ] }),
1703
+ (paramFormat || constraintBadges.length > 0 || paramEnum && paramEnum.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: paramConstraintsStyle, children: [
1704
+ paramFormat && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: paramFormat }),
1705
+ constraintBadges.map((c) => /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaBadge, { variant: "constraint", children: c }, c)),
1706
+ paramEnum && paramEnum.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Collapsible.SchemaBadge, { variant: "enum", children: [
1707
+ "enum: ",
1708
+ paramEnum.map(String).join(" | ")
1709
+ ] })
1710
+ ] }),
1711
+ param.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: paramDescStyle, children: param.description })
1712
+ ] }, name);
1713
+ }) })
1714
+ ] }),
1715
+ /* @__PURE__ */ jsxRuntime.jsx(SecurityRequirementBadges, { requirements: operation.securityRequirements ?? [] }),
1716
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: operation.bindings, title: "Operation Bindings" }),
1717
+ /* @__PURE__ */ jsxRuntime.jsx(BindingsSection, { bindings: channel.bindings, title: "Channel Bindings" })
1718
+ ] });
1719
+ }
1720
+ function OperationSamplesColumn({ operation, idx }) {
1721
+ const messages = operation.messages ?? [];
1722
+ const replyMessages = operation.reply?.messages ?? [];
1723
+ if (messages.length === 0 && replyMessages.length === 0) {
1724
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: emptySamplesStyle, children: "No message payload is defined for this operation." });
1725
+ }
1726
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: samplesColumnStyle, children: [
1727
+ messages.map((message, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1728
+ /* @__PURE__ */ jsxRuntime.jsxs("h4", { className: sectionTitleStyle, children: [
1729
+ "Message",
1730
+ (message.title ?? message.name) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: messageTitleStyle, children: [
1731
+ " \u2014 ",
1732
+ message.title ?? message.name
1733
+ ] })
1734
+ ] }),
1735
+ message.contentType && /* @__PURE__ */ jsxRuntime.jsx("code", { className: contentTypeStyle$1, children: message.contentType }),
1736
+ /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx: `${idx}-msg-${i}` })
1737
+ ] }, i)),
1738
+ replyMessages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: replyStyle, children: [
1739
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: sectionTitleStyle, children: "Reply" }),
1740
+ replyMessages.map((message, i) => /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx: `${idx}-reply-${i}` }, i))
1741
+ ] })
1742
+ ] });
1743
+ }
1744
+ const channelMetaStyle = css.css({
1745
+ padding: "0.75rem 1rem 0",
1746
+ [useSpecFetcher.mq.desktop]: {
1747
+ padding: "1rem 1.25rem 0"
1748
+ }
1749
+ });
1750
+ const operationWrapStyle = css.css({
1751
+ borderTop: "1px solid var(--omnispec-border-color)"
1752
+ });
1753
+ const tryItNaStyle = css.css({
1754
+ fontSize: "var(--omnispec-font-size-sm)",
1755
+ color: "var(--omnispec-fg-muted)",
1756
+ fontStyle: "italic",
1757
+ padding: "0.5rem 0"
1758
+ });
1759
+ const samplesColumnStyle = css.css({
1760
+ display: "flex",
1761
+ flexDirection: "column",
1762
+ gap: "1.5rem"
1763
+ });
1764
+ const emptySamplesStyle = css.css({
1765
+ fontSize: "var(--omnispec-font-size-sm)",
1766
+ color: "var(--omnispec-fg-muted)",
1767
+ fontStyle: "italic"
1768
+ });
1769
+ const sectionStyle = css.css({
1770
+ marginBottom: "1.5rem"
1771
+ });
1772
+ const sectionTitleStyle = css.css({
1773
+ margin: "0 0 0.75rem",
1774
+ fontSize: "var(--omnispec-font-size-md)",
1775
+ fontWeight: 700,
1776
+ color: "var(--omnispec-fg-primary)",
1777
+ letterSpacing: "0.02em"
1778
+ });
1779
+ const paramListStyle = css.css({
1780
+ display: "flex",
1781
+ flexDirection: "column"
1782
+ });
1783
+ const paramRowStyle = css.css({
1784
+ padding: "0.75rem 0"
1785
+ });
1786
+ const paramHeaderStyle = css.css({
1787
+ display: "flex",
1788
+ alignItems: "center",
1789
+ gap: "0.5rem",
1790
+ flexWrap: "wrap"
1791
+ });
1792
+ const paramNameStyle = css.css({
1793
+ fontSize: "var(--omnispec-font-size-sm)",
1794
+ fontWeight: 700,
1795
+ backgroundColor: "transparent",
1796
+ padding: 0
1797
+ });
1798
+ const typeBadgeStyle$1 = css.css({
1799
+ fontSize: "var(--omnispec-font-size-xs)",
1800
+ fontWeight: 400
1801
+ });
1802
+ const paramDescStyle = css.css({
1803
+ margin: "0.25rem 0 0",
1804
+ fontSize: "var(--omnispec-font-size-base)",
1805
+ color: "var(--omnispec-fg-secondary)",
1806
+ lineHeight: 1.5
1807
+ });
1808
+ const paramConstraintsStyle = css.css({
1809
+ display: "flex",
1810
+ flexWrap: "wrap",
1811
+ gap: "0.375rem",
1812
+ marginTop: "0.375rem"
1813
+ });
1814
+ const opHeaderStyle = css.css({
1815
+ display: "flex",
1816
+ alignItems: "center",
1817
+ gap: "0.5rem",
1818
+ marginBottom: "0.5rem"
1819
+ });
1820
+ const actionBadgeBase = css.css({
1821
+ display: "inline-block",
1822
+ padding: "0.125rem 0.375rem",
1823
+ borderRadius: "0.1875rem",
1824
+ fontSize: "0.5625rem",
1825
+ fontWeight: 700,
1826
+ fontFamily: "var(--omnispec-font-mono)",
1827
+ color: "#ffffff",
1828
+ letterSpacing: "0.0313rem"
1829
+ });
1830
+ const opIdStyle = css.css({
1831
+ fontSize: "var(--omnispec-font-size-sm)",
1832
+ fontWeight: 700,
1833
+ backgroundColor: "transparent",
1834
+ padding: 0
1835
+ });
1836
+ const opTitleStyle = css.css({
1837
+ fontSize: "var(--omnispec-font-size-sm)",
1838
+ fontWeight: 600,
1839
+ color: "var(--omnispec-fg-primary)"
1840
+ });
1841
+ const opSummaryStyle = css.css({
1842
+ fontSize: "var(--omnispec-font-size-sm)",
1843
+ color: "var(--omnispec-fg-secondary)"
1844
+ });
1845
+ const messageTitleStyle = css.css({
1846
+ fontWeight: 400,
1847
+ color: "var(--omnispec-fg-primary)"
1848
+ });
1849
+ const contentTypeStyle$1 = css.css({
1850
+ fontFamily: "var(--omnispec-font-mono)",
1851
+ fontSize: "var(--omnispec-font-size-xs)",
1852
+ color: "var(--omnispec-fg-muted)",
1853
+ display: "block",
1854
+ marginBottom: "0.5rem",
1855
+ backgroundColor: "transparent",
1856
+ padding: 0
1857
+ });
1858
+ const replyStyle = css.css({
1859
+ paddingLeft: "0.75rem",
1860
+ borderLeft: "0.125rem solid var(--omnispec-border-color)"
1861
+ });
1192
1862
  const tagChipsStyle = css.css({
1193
1863
  display: "flex",
1194
1864
  flexWrap: "wrap",
@@ -1203,6 +1873,19 @@ const tagChipStyle = css.css({
1203
1873
  padding: "1px 0.5rem",
1204
1874
  borderRadius: "0.625rem"
1205
1875
  });
1876
+ const tagChipButtonStyle = css.css({
1877
+ fontSize: "var(--omnispec-font-size-xxs)",
1878
+ fontFamily: "var(--omnispec-font-mono)",
1879
+ color: "var(--omnispec-fg-secondary)",
1880
+ backgroundColor: "var(--omnispec-bg-tertiary)",
1881
+ padding: "1px 0.5rem",
1882
+ borderRadius: "0.625rem",
1883
+ border: "none",
1884
+ cursor: "pointer",
1885
+ "&:hover": {
1886
+ color: "var(--omnispec-fg-primary)"
1887
+ }
1888
+ });
1206
1889
 
1207
1890
  function ComponentsSection({ components }) {
1208
1891
  const schemas = Object.entries(components.schemas);
@@ -1219,9 +1902,15 @@ function ComponentsSection({ components }) {
1219
1902
  children: [
1220
1903
  message.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: messageSummaryStyle, children: message.title }),
1221
1904
  message.summary && /* @__PURE__ */ jsxRuntime.jsx("p", { className: messageSummaryStyle, children: message.summary }),
1222
- message.contentType && /* @__PURE__ */ jsxRuntime.jsx("code", { className: contentTypeStyle, children: message.contentType }),
1905
+ message.contentType && /* @__PURE__ */ jsxRuntime.jsxs("code", { className: contentTypeStyle, children: [
1906
+ message.contentType,
1907
+ message.contentTypeInherited && /* @__PURE__ */ jsxRuntime.jsx("span", { className: contentTypeHintStyle, children: " (default)" })
1908
+ ] }),
1223
1909
  /* @__PURE__ */ jsxRuntime.jsx(MessagePayload, { message, idx: `message-${name}` }),
1224
- message.headers && /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(message.headers) })
1910
+ message.headers && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: headersWrapStyle, children: [
1911
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: headersTitleStyle, children: "Headers" }),
1912
+ /* @__PURE__ */ jsxRuntime.jsx(Collapsible.SchemaTree, { nodes: Collapsible.schemaToNodes(message.headers) })
1913
+ ] })
1225
1914
  ]
1226
1915
  }
1227
1916
  ) }, name)) })
@@ -1286,6 +1975,20 @@ const contentTypeStyle = css.css({
1286
1975
  color: "var(--omnispec-fg-muted)",
1287
1976
  marginBottom: "0.5rem"
1288
1977
  });
1978
+ const contentTypeHintStyle = css.css({
1979
+ fontStyle: "italic",
1980
+ color: "var(--omnispec-fg-muted)"
1981
+ });
1982
+ const headersWrapStyle = css.css({
1983
+ marginTop: "1rem"
1984
+ });
1985
+ const headersTitleStyle = css.css({
1986
+ margin: "0 0 0.75rem",
1987
+ fontSize: "var(--omnispec-font-size-md)",
1988
+ fontWeight: 700,
1989
+ color: "var(--omnispec-fg-primary)",
1990
+ letterSpacing: "0.02em"
1991
+ });
1289
1992
 
1290
1993
  const SPECIAL_KEYS = /* @__PURE__ */ new Set(["type", "description", "flows"]);
1291
1994
  function SecuritySchemesSection({ securitySchemes }) {
@@ -1434,10 +2137,11 @@ const scopeDescStyle = css.css({
1434
2137
 
1435
2138
  const UNTAGGED_LABEL = "Untagged";
1436
2139
  function slugify(value) {
1437
- return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "tag";
2140
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "tag";
1438
2141
  }
1439
2142
  function channelTagNames(channel) {
1440
2143
  const names = /* @__PURE__ */ new Set();
2144
+ for (const tag of channel.tags ?? []) names.add(tag.name);
1441
2145
  for (const op of channel.operations) {
1442
2146
  for (const tag of op.tags ?? []) names.add(tag.name);
1443
2147
  }
@@ -1492,19 +2196,7 @@ function TagGroupHeader({ group }) {
1492
2196
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: countStyle, children: group.channels.length })
1493
2197
  ] }),
1494
2198
  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
- )
2199
+ group.tag?.externalDocs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: docsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalDocsLink, { externalDocs: group.tag.externalDocs, context: group.label }) })
1508
2200
  ] });
1509
2201
  }
1510
2202
  const headerStyle = css.css({
@@ -1537,16 +2229,7 @@ const descStyle = css.css({
1537
2229
  lineHeight: 1.6
1538
2230
  });
1539
2231
  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
- }
2232
+ marginTop: "0.5rem"
1550
2233
  });
1551
2234
 
1552
2235
  function AsyncApiSpec({
@@ -1555,6 +2238,7 @@ function AsyncApiSpec({
1555
2238
  layout = "sidebar",
1556
2239
  sidebarPosition = "left",
1557
2240
  defaultExpandOperations = false,
2241
+ displayMode,
1558
2242
  downloadLink,
1559
2243
  sidebarNav,
1560
2244
  slots = {},
@@ -1564,6 +2248,7 @@ function AsyncApiSpec({
1564
2248
  className
1565
2249
  }) {
1566
2250
  const resolvedSchemaStyle = useSpecFetcher.resolveSchemaStyle(schemaStyle, pro?.advancedSchemaStyles ?? false);
2251
+ const resolvedDisplayMode = displayMode ?? "compact";
1567
2252
  const { data: parsedSpec, state } = useAsyncApiSpec(spec);
1568
2253
  const [searchQuery, setSearchQuery] = React.useState("");
1569
2254
  const [allExpanded, setAllExpanded] = React.useState(defaultExpandOperations);
@@ -1630,12 +2315,15 @@ function AsyncApiSpec({
1630
2315
  if (!parsedSpec) return [];
1631
2316
  const actionLabel = (action) => action.toUpperCase();
1632
2317
  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
- });
2318
+ const channelNavItem = (ch, idPrefix) => {
2319
+ const uniqueActions = [...new Set(ch.operations.map((op) => actionLabel(op.action)))];
2320
+ return {
2321
+ id: `${idPrefix}channel-${ch.name}`,
2322
+ label: ch.address,
2323
+ badge: uniqueActions.join("/") || void 0,
2324
+ badgeColor: actionColor(ch.operations[0]?.action ?? "")
2325
+ };
2326
+ };
1639
2327
  const operationNavItems = () => filteredChannels.flatMap(
1640
2328
  (ch) => ch.operations.map((op, idx) => ({
1641
2329
  id: operationDomId(ch.name, idx),
@@ -1655,11 +2343,15 @@ function AsyncApiSpec({
1655
2343
  if (parsedSpec.servers.length > 0) {
1656
2344
  items.push({ id: "servers", label: "Servers" });
1657
2345
  }
1658
- items.push({
1659
- id: "channels",
1660
- label: navGrouping === "operation" ? "Operations" : "Channels",
1661
- children: channelChildren
1662
- });
2346
+ const searchedToEmpty = channelChildren.length === 0 && searchQuery.trim().length > 0;
2347
+ const channelsChildren = searchedToEmpty ? [{ id: "channels-no-results", label: "No results", className: noResultsNavStyle }] : channelChildren;
2348
+ if (channelsChildren.length > 0) {
2349
+ items.push({
2350
+ id: "channels",
2351
+ label: navGrouping === "operation" ? "Operations" : "Channels",
2352
+ children: channelsChildren
2353
+ });
2354
+ }
1663
2355
  if (Object.keys(parsedSpec.components.messages ?? {}).length > 0) {
1664
2356
  items.push({
1665
2357
  id: "messages",
@@ -1684,7 +2376,7 @@ function AsyncApiSpec({
1684
2376
  items.push({ id: "security", label: "Security Schemes" });
1685
2377
  }
1686
2378
  return items;
1687
- }, [parsedSpec, grouped, tagGroups, filteredChannels, navGrouping, operationDomId]);
2379
+ }, [parsedSpec, grouped, tagGroups, filteredChannels, navGrouping, operationDomId, searchQuery]);
1688
2380
  const { navigateTo } = Collapsible.useHashScroll(filteredChannels.length);
1689
2381
  const handleNavSelect = React.useCallback((id) => {
1690
2382
  const cardId = opToCard.get(id);
@@ -1762,7 +2454,7 @@ function AsyncApiSpec({
1762
2454
  ] });
1763
2455
  const sidebar = useSpecFetcher.buildSidebar(sidebarNav, specNav);
1764
2456
  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(
2457
+ return /* @__PURE__ */ jsxRuntime.jsx(useSpecFetcher.ConfigProvider, { config: { allowTryIt: false, layout, sidebarPosition, defaultExpandOperations, displayMode: resolvedDisplayMode, 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
2458
  useSpecFetcher.DocLayout,
1767
2459
  {
1768
2460
  layout,
@@ -1789,22 +2481,26 @@ function AsyncApiSpec({
1789
2481
  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
2482
  /* @__PURE__ */ jsxRuntime.jsx(TagGroupHeader, { group }),
1791
2483
  group.channels.map((channel) => /* @__PURE__ */ jsxRuntime.jsx(
1792
- ChannelDetail,
2484
+ ChannelCard,
1793
2485
  {
1794
2486
  id: `${group.id}-channel-${channel.name}`,
1795
2487
  channel,
2488
+ displayMode: resolvedDisplayMode,
1796
2489
  expandAll: allExpanded,
1797
- expandGeneration
2490
+ expandGeneration,
2491
+ onTagClick: setSearchQuery
1798
2492
  },
1799
2493
  `${group.id}-${channel.name}`
1800
2494
  ))
1801
2495
  ] }, group.id)) : filteredChannels.map((channel) => /* @__PURE__ */ jsxRuntime.jsx(
1802
- ChannelDetail,
2496
+ ChannelCard,
1803
2497
  {
1804
2498
  id: `channel-${channel.name}`,
1805
2499
  channel,
2500
+ displayMode: resolvedDisplayMode,
1806
2501
  expandAll: allExpanded,
1807
- expandGeneration
2502
+ expandGeneration,
2503
+ onTagClick: setSearchQuery
1808
2504
  },
1809
2505
  channel.name
1810
2506
  ))
@@ -1815,6 +2511,26 @@ function AsyncApiSpec({
1815
2511
  }
1816
2512
  ) }) }) }) }) });
1817
2513
  }
2514
+ function ChannelCard({
2515
+ channel,
2516
+ id,
2517
+ displayMode,
2518
+ expandAll,
2519
+ expandGeneration,
2520
+ onTagClick
2521
+ }) {
2522
+ const Renderer = displayMode === "reference" ? ChannelReferenceDetail : ChannelDetail;
2523
+ return /* @__PURE__ */ jsxRuntime.jsx(
2524
+ Renderer,
2525
+ {
2526
+ id,
2527
+ channel,
2528
+ expandAll,
2529
+ expandGeneration,
2530
+ onTagClick
2531
+ }
2532
+ );
2533
+ }
1818
2534
  function nestByTagGroups(groups, xTagGroups, toNav) {
1819
2535
  if (!xTagGroups?.length) return groups.map(toNav);
1820
2536
  const byTagName = /* @__PURE__ */ new Map();
@@ -1824,7 +2540,7 @@ function nestByTagGroups(groups, xTagGroups, toNav) {
1824
2540
  const children = xg.tags.map((t) => byTagName.get(t)).filter((g) => !!g);
1825
2541
  children.forEach((g) => used.add(g));
1826
2542
  return {
1827
- id: `xtaggroup-${xg.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "group"}`,
2543
+ id: `xtaggroup-${xg.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "group"}`,
1828
2544
  label: xg.name,
1829
2545
  children: children.map(toNav)
1830
2546
  };
@@ -1837,6 +2553,11 @@ const emptyStateStyle = css.css({
1837
2553
  color: "var(--omnispec-fg-muted)",
1838
2554
  fontStyle: "italic"
1839
2555
  });
2556
+ const noResultsNavStyle = css.css({
2557
+ fontStyle: "italic",
2558
+ color: "var(--omnispec-fg-muted)",
2559
+ cursor: "default"
2560
+ });
1840
2561
  const groupToggleStyle = css.css({
1841
2562
  display: "flex",
1842
2563
  alignItems: "center",
@@ -1877,4 +2598,4 @@ const tagSectionStyle = css.css({
1877
2598
  });
1878
2599
 
1879
2600
  exports.AsyncApiSpec = AsyncApiSpec;
1880
- //# sourceMappingURL=AsyncApiSpec-CHvM1swf.js.map
2601
+ //# sourceMappingURL=AsyncApiSpec-BzgUioEK.js.map