@stoplight/elements-core 7.16.6 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { IHttpOperation } from '@stoplight/types';
1
+ import { IHttpEndpointOperation } from '@stoplight/types';
2
2
  import * as React from 'react';
3
3
  import { DocsComponentProps } from '..';
4
- export declare type HttpOperationProps = DocsComponentProps<IHttpOperation>;
4
+ export declare type HttpOperationProps = DocsComponentProps<IHttpEndpointOperation>;
5
5
  export declare const HttpOperation: React.FunctionComponent<HttpOperationProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
6
6
  export declare function OperationHeader({ id, noHeading, hasBadges, name, isDeprecated, isInternal, hideServerUrl, method, path, }: {
7
7
  id: string;
@@ -1,7 +1,7 @@
1
- import { IHttpOperation } from '@stoplight/types';
1
+ import { IHttpEndpointOperation } from '@stoplight/types';
2
2
  import * as React from 'react';
3
3
  interface IRequestProps {
4
- operation: IHttpOperation;
4
+ operation: IHttpEndpointOperation;
5
5
  onChange?: (requestBodyIndex: number) => void;
6
6
  }
7
7
  export declare const Request: React.FunctionComponent<IRequestProps>;
@@ -1,6 +1,6 @@
1
- import { IHttpOperation } from '@stoplight/types';
1
+ import { IHttpEndpointOperation } from '@stoplight/types';
2
2
  export interface ResponseExamplesProps {
3
- httpOperation: IHttpOperation;
3
+ httpOperation: IHttpEndpointOperation;
4
4
  responseStatusCode?: string;
5
5
  responseMediaType?: string;
6
6
  }
@@ -2,8 +2,8 @@ import { IIconProps } from '@stoplight/mosaic';
2
2
  export declare const NODE_TYPE_TITLE_ICON: {
3
3
  [nodeType: string]: IIconProps['icon'];
4
4
  };
5
- export declare const NODE_TITLE_ICON: {
6
- [nodeTitle: string]: IIconProps['icon'];
5
+ export declare const NODE_GROUP_ICON: {
6
+ [itemType: string]: IIconProps['icon'];
7
7
  };
8
8
  export declare const NODE_TYPE_META_ICON: {
9
9
  [nodeType: string]: IIconProps['icon'];
@@ -12,9 +12,11 @@ export declare const NODE_TYPE_ICON_COLOR: {
12
12
  model: string;
13
13
  http_service: string;
14
14
  http_operation: string;
15
+ http_webhook: string;
15
16
  };
16
- export declare const NODE_TITLE_ICON_COLOR: {
17
- Schemas: string;
17
+ export declare const NODE_GROUP_ICON_COLOR: {
18
+ http_webhook: string;
19
+ model: string;
18
20
  };
19
21
  export declare const NODE_META_COLOR: {
20
22
  get: string;
@@ -20,12 +20,13 @@ export declare type TableOfContentsGroupItem = TableOfContentsGroup | TableOfCon
20
20
  export declare type TableOfContentsGroup = {
21
21
  title: string;
22
22
  items: TableOfContentsGroupItem[];
23
+ itemsType?: 'article' | 'http_operation' | 'http_webhook' | 'model';
23
24
  };
24
25
  export declare type TableOfContentsExternalLink = {
25
26
  title: string;
26
27
  url: string;
27
28
  };
28
- export declare type TableOfContentsNode<T = 'http_service' | 'http_operation' | 'model' | 'article' | 'overview'> = {
29
+ export declare type TableOfContentsNode<T = 'http_service' | 'http_operation' | 'http_webhook' | 'model' | 'article' | 'overview'> = {
29
30
  id: string;
30
31
  slug: string;
31
32
  title: string;
@@ -1,6 +1,6 @@
1
- import { IHttpOperation } from '@stoplight/types';
1
+ import { IHttpEndpointOperation } from '@stoplight/types';
2
2
  import { ParameterSpec } from './parameter-utils';
3
- export declare const useRequestParameters: (httpOperation: IHttpOperation) => {
3
+ export declare const useRequestParameters: (httpOperation: IHttpEndpointOperation) => {
4
4
  allParameters: ParameterSpec[];
5
5
  parameterValuesWithDefaults: {
6
6
  [k: string]: any;
@@ -1,8 +1,8 @@
1
- import type { IHttpOperation } from '@stoplight/types';
1
+ import type { IHttpEndpointOperation } from '@stoplight/types';
2
2
  import { Request as HarRequest } from 'har-format';
3
3
  import * as React from 'react';
4
4
  export interface TryItProps {
5
- httpOperation: IHttpOperation;
5
+ httpOperation: IHttpEndpointOperation;
6
6
  mockUrl?: string;
7
7
  onRequestChange?: (currentRequest: HarRequest) => void;
8
8
  requestBodyIndex?: number;
package/index.d.ts CHANGED
@@ -6,11 +6,11 @@ export { Logo } from './components/Logo';
6
6
  export { DefaultSMDComponents } from './components/MarkdownViewer/CustomComponents/CodeComponent';
7
7
  export { CustomComponentMapping, MarkdownComponentsProvider, } from './components/MarkdownViewer/CustomComponents/Provider';
8
8
  export { ReactRouterMarkdownLink } from './components/MarkdownViewer/CustomComponents/ReactRouterLink';
9
- export { TableOfContents } from './components/MosaicTableOfContents';
10
- export { CustomLinkComponent, TableOfContentsItem, TableOfContentsNode, TableOfContentsNodeGroup, } from './components/MosaicTableOfContents/types';
11
- export { findFirstNode } from './components/MosaicTableOfContents/utils';
12
9
  export { NonIdealState } from './components/NonIdealState';
13
10
  export { PoweredByLink } from './components/PoweredByLink';
11
+ export { TableOfContents } from './components/TableOfContents';
12
+ export { CustomLinkComponent, TableOfContentsItem, TableOfContentsNode, TableOfContentsNodeGroup, } from './components/TableOfContents/types';
13
+ export { findFirstNode } from './components/TableOfContents/utils';
14
14
  export { TryIt, TryItProps, TryItWithRequestSamples, TryItWithRequestSamplesProps } from './components/TryIt';
15
15
  export { HttpMethodColors, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName } from './constants';
16
16
  export { MockingProvider } from './containers/MockingProvider';
@@ -26,7 +26,7 @@ export { useParsedValue } from './hooks/useParsedValue';
26
26
  export { useRouter } from './hooks/useRouter';
27
27
  export { Styled, withStyles } from './styled';
28
28
  export { Divider, Group, ITableOfContentsTree, Item, ParsedNode, RoutingProps, TableOfContentItem } from './types';
29
- export { isHttpOperation, isHttpService } from './utils/guards';
29
+ export { isHttpOperation, isHttpService, isHttpWebhookOperation } from './utils/guards';
30
30
  export { ReferenceResolver } from './utils/ref-resolving/ReferenceResolver';
31
31
  export { createResolvedObject } from './utils/ref-resolving/resolvedObject';
32
32
  export { slugify } from './utils/string';
package/index.esm.js CHANGED
@@ -180,6 +180,11 @@ function isHttpService(maybeHttpService) {
180
180
  function isHttpOperation(maybeHttpOperation) {
181
181
  return isStoplightNode(maybeHttpOperation) && 'method' in maybeHttpOperation && 'path' in maybeHttpOperation;
182
182
  }
183
+ function isHttpWebhookOperation(maybeHttpWebhookOperation) {
184
+ return (isStoplightNode(maybeHttpWebhookOperation) &&
185
+ 'method' in maybeHttpWebhookOperation &&
186
+ 'name' in maybeHttpWebhookOperation);
187
+ }
183
188
  const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
184
189
  function isProperUrl(url) {
185
190
  return properUrl.test(url);
@@ -191,6 +196,7 @@ function useParsedData(nodeType, data) {
191
196
  const parserMap = {
192
197
  [NodeType.Article]: parseArticleData,
193
198
  [NodeType.HttpOperation]: parseHttpOperation,
199
+ [NodeType.HttpWebhook]: parseHttpWebhookOperation,
194
200
  [NodeType.HttpService]: parseHttpService,
195
201
  [NodeType.Model]: parseModel,
196
202
  [NodeType.HttpServer]: parseUnknown,
@@ -223,6 +229,16 @@ function parseHttpOperation(rawData) {
223
229
  }
224
230
  return undefined;
225
231
  }
232
+ function parseHttpWebhookOperation(rawData) {
233
+ const data = tryParseYamlOrObject(rawData);
234
+ if (isHttpWebhookOperation(data)) {
235
+ return {
236
+ type: NodeType.HttpWebhook,
237
+ data: data,
238
+ };
239
+ }
240
+ return undefined;
241
+ }
226
242
  function parseHttpService(rawData) {
227
243
  const data = tryParseYamlOrObject(rawData);
228
244
  if (isHttpService(data)) {
@@ -338,6 +354,16 @@ var faDatabase = {
338
354
  iconName: 'database',
339
355
  icon: [448, 512, [], "f1c0", "M448 80V128C448 172.2 347.7 208 224 208C100.3 208 0 172.2 0 128V80C0 35.82 100.3 0 224 0C347.7 0 448 35.82 448 80zM393.2 214.7C413.1 207.3 433.1 197.8 448 186.1V288C448 332.2 347.7 368 224 368C100.3 368 0 332.2 0 288V186.1C14.93 197.8 34.02 207.3 54.85 214.7C99.66 230.7 159.5 240 224 240C288.5 240 348.3 230.7 393.2 214.7V214.7zM54.85 374.7C99.66 390.7 159.5 400 224 400C288.5 400 348.3 390.7 393.2 374.7C413.1 367.3 433.1 357.8 448 346.1V432C448 476.2 347.7 512 224 512C100.3 512 0 476.2 0 432V346.1C14.93 357.8 34.02 367.3 54.85 374.7z"]
340
356
  };
357
+ var faEnvelope = {
358
+ prefix: 'fas',
359
+ iconName: 'envelope',
360
+ icon: [512, 512, [128386, 61443, 9993], "f0e0", "M464 64C490.5 64 512 85.49 512 112C512 127.1 504.9 141.3 492.8 150.4L275.2 313.6C263.8 322.1 248.2 322.1 236.8 313.6L19.2 150.4C7.113 141.3 0 127.1 0 112C0 85.49 21.49 64 48 64H464zM217.6 339.2C240.4 356.3 271.6 356.3 294.4 339.2L512 176V384C512 419.3 483.3 448 448 448H64C28.65 448 0 419.3 0 384V176L217.6 339.2z"]
361
+ };
362
+ var faEnvelopesBulk = {
363
+ prefix: 'fas',
364
+ iconName: 'envelopes-bulk',
365
+ icon: [640, 512, ["mail-bulk"], "f674", "M191.9 448.6c-9.766 0-19.48-2.969-27.78-8.891L32 340.2V480c0 17.62 14.38 32 32 32h256c17.62 0 32-14.38 32-32v-139.8L220.2 439.5C211.7 445.6 201.8 448.6 191.9 448.6zM192 192c0-35.25 28.75-64 64-64h224V32c0-17.62-14.38-32-32-32H128C110.4 0 96 14.38 96 32v192h96V192zM320 256H64C46.38 256 32 270.4 32 288v12.18l151 113.8c5.25 3.719 12.7 3.734 18.27-.25L352 300.2V288C352 270.4 337.6 256 320 256zM576 160H256C238.4 160 224 174.4 224 192v32h96c33.25 0 60.63 25.38 63.75 57.88L384 416h192c17.62 0 32-14.38 32-32V192C608 174.4 593.6 160 576 160zM544 288h-64V224h64V288z"]
366
+ };
341
367
  var faEye = {
342
368
  prefix: 'fas',
343
369
  iconName: 'eye',
@@ -356,6 +382,7 @@ var faServer = {
356
382
 
357
383
  const NodeTypeColors = {
358
384
  http_operation: '#6a6acb',
385
+ http_webhook: 'primary',
359
386
  http_service: '#e056fd',
360
387
  article: '#399da6',
361
388
  model: '#ef932b',
@@ -372,6 +399,7 @@ const NodeTypeColors = {
372
399
  };
373
400
  const NodeTypePrettyName = {
374
401
  http_operation: 'Endpoint',
402
+ http_webhook: 'Webhook',
375
403
  http_service: 'API',
376
404
  article: 'Article',
377
405
  model: 'Model',
@@ -388,6 +416,7 @@ const NodeTypePrettyName = {
388
416
  };
389
417
  const NodeTypeIconDefs = {
390
418
  http_operation: faCrosshairs,
419
+ http_webhook: faEnvelope,
391
420
  http_service: faCloud,
392
421
  article: faBookOpen,
393
422
  model: faCube,
@@ -2137,7 +2166,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2137
2166
  }, [servers, firstServer, chosenServer, setChosenServer]);
2138
2167
  React.useEffect(() => {
2139
2168
  let isMounted = true;
2140
- if (onRequestChange || embeddedInMd) {
2169
+ if (isHttpOperation(httpOperation) && (onRequestChange || embeddedInMd)) {
2141
2170
  buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, serverVariableValues,
2142
2171
  httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
2143
2172
  corsProxy })).then(request => {
@@ -2170,7 +2199,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2170
2199
  ]);
2171
2200
  const handleSendRequest = () => __awaiter(void 0, void 0, void 0, function* () {
2172
2201
  setValidateParameters(true);
2173
- if (hasRequiredButEmptyParameters)
2202
+ if (hasRequiredButEmptyParameters || !isHttpOperation(httpOperation))
2174
2203
  return;
2175
2204
  try {
2176
2205
  setLoading(true);
@@ -2218,23 +2247,33 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2218
2247
  const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
2219
2248
  const tryItPanelContents = (React.createElement(React.Fragment, null,
2220
2249
  ((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React.createElement(TryItAuth, { operationSecuritySchemes: httpOperation.security, operationAuthValue: operationAuthValue, setOperationAuthValue: setOperationAuthValue, setCurrentScheme: setCurrentScheme })) : null,
2221
- serverVariables.length > 0 && (React.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2250
+ isHttpOperation(httpOperation) && serverVariables.length > 0 && (React.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2222
2251
  allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
2223
- formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
2224
- React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2252
+ React.createElement(Box, { pb: 1 }, formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null),
2253
+ isHttpOperation(httpOperation) ? (React.createElement(Panel.Content, { className: "SendButtonHolder", pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2225
2254
  React.createElement(HStack, { alignItems: "center", spacing: 2 },
2226
2255
  React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
2227
2256
  servers.length > 1 && React.createElement(ServersDropdown, { servers: servers }),
2228
2257
  isMockingEnabled && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
2229
2258
  validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
2230
2259
  React.createElement(Icon, { icon: ['fas', 'exclamation-triangle'], className: "sl-mr-1" }),
2231
- "You didn't provide all of the required parameters!")))));
2260
+ "You didn't provide all of the required parameters!")))) : null));
2232
2261
  let tryItPanelElem;
2233
2262
  if (embeddedInMd) {
2263
+ let path;
2264
+ if (isHttpOperation(httpOperation)) {
2265
+ path = httpOperation.path;
2266
+ }
2267
+ else if (isHttpWebhookOperation(httpOperation)) {
2268
+ path = httpOperation.name;
2269
+ }
2270
+ else {
2271
+ throw new RangeError('unsupported type');
2272
+ }
2234
2273
  tryItPanelElem = (React.createElement(Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
2235
2274
  React.createElement(Panel.Titlebar, { bg: "canvas-300" },
2236
2275
  React.createElement(Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
2237
- React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
2276
+ React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${path}`)),
2238
2277
  tryItPanelContents));
2239
2278
  }
2240
2279
  else {
@@ -2712,7 +2751,17 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
2712
2751
  const [requestBodyIndex, setTextRequestBodyIndex] = React.useState(0);
2713
2752
  const prettyName = (data.summary || data.iid || '').trim();
2714
2753
  const hasBadges = isDeprecated || isInternal;
2715
- const header = (React.createElement(OperationHeader, { id: data.id, method: data.method, path: data.path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal }));
2754
+ let path;
2755
+ if (isHttpOperation(data)) {
2756
+ path = data.path;
2757
+ }
2758
+ else if (isHttpWebhookOperation(data)) {
2759
+ path = data.name;
2760
+ }
2761
+ else {
2762
+ throw new RangeError('unsupported node type');
2763
+ }
2764
+ const header = (React.createElement(OperationHeader, { id: data.id, method: data.method, path: path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal, hideServerUrl: !isHttpOperation(data) }));
2716
2765
  const tryItPanel = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryItPanel) && (React.createElement(TryItWithRequestSamples, { httpOperation: data, responseMediaType: responseMediaType, responseStatusCode: responseStatusCode, requestBodyIndex: requestBodyIndex, hideTryIt: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryIt, tryItCredentialsPolicy: tryItCredentialsPolicy, mockUrl: mocking.hideMocking ? undefined : mocking.mockUrl, corsProxy: tryItCorsProxy }));
2717
2766
  const descriptionChanged = nodeHasChanged === null || nodeHasChanged === void 0 ? void 0 : nodeHasChanged({ nodeId: data.id, attr: 'description' });
2718
2767
  const description = (React.createElement(VStack, { spacing: 10 },
@@ -3035,6 +3084,7 @@ const ParsedDocs = (_a) => {
3035
3084
  case 'article':
3036
3085
  return React.createElement(Article, Object.assign({ data: node.data }, commonProps));
3037
3086
  case 'http_operation':
3087
+ case 'http_webhook':
3038
3088
  return React.createElement(HttpOperation, Object.assign({ data: node.data }, commonProps));
3039
3089
  case 'http_service':
3040
3090
  return React.createElement(HttpService, Object.assign({ data: node.data }, commonProps));
@@ -3230,6 +3280,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
3230
3280
  return (React__default.createElement(HashLink, { to: href, title: title }, children));
3231
3281
  };
3232
3282
 
3283
+ const NonIdealState = ({ description, icon, title }) => {
3284
+ return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3285
+ React.createElement(Box, { as: Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3286
+ React.createElement(Heading, { size: 4, mb: 4 }, title),
3287
+ React.createElement(Text, null, description)));
3288
+ };
3289
+
3233
3290
  function useFirstRender() {
3234
3291
  const ref = React__default.useRef(true);
3235
3292
  const firstRender = ref.current;
@@ -3240,21 +3297,26 @@ function useFirstRender() {
3240
3297
  const NODE_TYPE_TITLE_ICON = {
3241
3298
  http_service: faCloud,
3242
3299
  http_operation: faBullseye,
3300
+ http_webhook: faEnvelope,
3243
3301
  model: faCube,
3244
3302
  };
3245
- const NODE_TITLE_ICON = {
3246
- Schemas: faCubes,
3303
+ const NODE_GROUP_ICON = {
3304
+ http_webhook: faEnvelopesBulk,
3305
+ model: faCubes,
3247
3306
  };
3248
3307
  const NODE_TYPE_META_ICON = {
3308
+ webhook: faEnvelope,
3249
3309
  model: faCube,
3250
3310
  };
3251
3311
  const NODE_TYPE_ICON_COLOR = {
3252
3312
  model: 'warning',
3253
3313
  http_service: '#D812EA',
3254
3314
  http_operation: '#9747FF',
3315
+ http_webhook: 'primary',
3255
3316
  };
3256
- const NODE_TITLE_ICON_COLOR = {
3257
- Schemas: 'warning',
3317
+ const NODE_GROUP_ICON_COLOR = {
3318
+ http_webhook: 'primary',
3319
+ model: 'warning',
3258
3320
  };
3259
3321
  const NODE_META_COLOR = {
3260
3322
  get: 'success',
@@ -3307,7 +3369,7 @@ function isDivider(item) {
3307
3369
  return Object.keys(item).length === 1 && 'title' in item;
3308
3370
  }
3309
3371
  function isGroup(item) {
3310
- return Object.keys(item).length === 2 && 'title' in item && 'items' in item;
3372
+ return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
3311
3373
  }
3312
3374
  function isNodeGroup(item) {
3313
3375
  return 'title' in item && 'items' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
@@ -3321,6 +3383,7 @@ function isExternalLink(item) {
3321
3383
 
3322
3384
  const ActiveIdContext = React.createContext(undefined);
3323
3385
  const LinkContext = React.createContext(undefined);
3386
+ LinkContext.displayName = 'LinkContext';
3324
3387
  const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
3325
3388
  const container = React.useRef(null);
3326
3389
  const child = React.useRef(null);
@@ -3349,9 +3412,11 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
3349
3412
  return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3350
3413
  }))))));
3351
3414
  });
3415
+ TableOfContents.displayName = 'TableOfContents';
3352
3416
  const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
3353
3417
  return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
3354
3418
  });
3419
+ Divider.displayName = 'Divider';
3355
3420
  const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick }) => {
3356
3421
  if (isExternalLink(item)) {
3357
3422
  return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
@@ -3367,6 +3432,7 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsi
3367
3432
  }
3368
3433
  return null;
3369
3434
  });
3435
+ GroupItem.displayName = 'GroupItem';
3370
3436
  const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick = () => { } }) => {
3371
3437
  const activeId = React.useContext(ActiveIdContext);
3372
3438
  const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
@@ -3398,7 +3464,8 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
3398
3464
  elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3399
3465
  }
3400
3466
  else {
3401
- elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: NODE_TITLE_ICON[item.title] && (React.createElement(Box, { as: Icon, color: NODE_TITLE_ICON_COLOR[item.title], icon: NODE_TITLE_ICON[item.title] })) }));
3467
+ elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
3468
+ NODE_GROUP_ICON[item.itemsType] && (React.createElement(Box, { as: Icon, color: NODE_GROUP_ICON_COLOR[item.itemsType], icon: NODE_GROUP_ICON[item.itemsType] })) }));
3402
3469
  }
3403
3470
  return (React.createElement(React.Fragment, null,
3404
3471
  elem,
@@ -3407,6 +3474,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
3407
3474
  return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3408
3475
  })));
3409
3476
  });
3477
+ Group.displayName = 'Group';
3410
3478
  const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiveMode, onClick }) => {
3411
3479
  return (React.createElement(Flex, { id: id, bg: {
3412
3480
  default: isInResponsiveMode ? 'canvas' : isActive ? 'primary-tint' : 'canvas-100',
@@ -3416,6 +3484,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
3416
3484
  React.createElement(Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate", fontSize: isInResponsiveMode ? 'lg' : 'base' }, title),
3417
3485
  React.createElement(Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
3418
3486
  });
3487
+ Item.displayName = 'Item';
3419
3488
  const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, makeSlugAbsoluteRoute, onClick, onLinkClick = () => { } }) => {
3420
3489
  const activeId = React.useContext(ActiveIdContext);
3421
3490
  const isActive = activeId === item.slug || activeId === item.id;
@@ -3435,18 +3504,12 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
3435
3504
  return (React.createElement(Box, { as: LinkComponent, to: makeSlugAbsoluteRoute && !item.slug.startsWith('/') ? `/${item.slug}` : item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
3436
3505
  React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
3437
3506
  });
3507
+ Node.displayName = 'Node';
3438
3508
  const Version = ({ value }) => {
3439
3509
  return (React.createElement(Box, { mr: 2 },
3440
3510
  React.createElement(VersionBadge, { value: value, backgroundColor: "#909DAB" })));
3441
3511
  };
3442
3512
 
3443
- const NonIdealState = ({ description, icon, title }) => {
3444
- return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3445
- React.createElement(Box, { as: Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3446
- React.createElement(Heading, { size: 4, mb: 4 }, title),
3447
- React.createElement(Text, null, description)));
3448
- };
3449
-
3450
3513
  function withMosaicProvider(WrappedComponent) {
3451
3514
  const WithMosaicProvider = (props) => {
3452
3515
  try {
@@ -3698,4 +3761,4 @@ const createElementClass = (Component, propDescriptors) => {
3698
3761
  };
3699
3762
  };
3700
3763
 
3701
- export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
3764
+ export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
package/index.js CHANGED
@@ -237,6 +237,11 @@ function isHttpService(maybeHttpService) {
237
237
  function isHttpOperation(maybeHttpOperation) {
238
238
  return isStoplightNode(maybeHttpOperation) && 'method' in maybeHttpOperation && 'path' in maybeHttpOperation;
239
239
  }
240
+ function isHttpWebhookOperation(maybeHttpWebhookOperation) {
241
+ return (isStoplightNode(maybeHttpWebhookOperation) &&
242
+ 'method' in maybeHttpWebhookOperation &&
243
+ 'name' in maybeHttpWebhookOperation);
244
+ }
240
245
  const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
241
246
  function isProperUrl(url) {
242
247
  return properUrl.test(url);
@@ -248,6 +253,7 @@ function useParsedData(nodeType, data) {
248
253
  const parserMap = {
249
254
  [types.NodeType.Article]: parseArticleData,
250
255
  [types.NodeType.HttpOperation]: parseHttpOperation,
256
+ [types.NodeType.HttpWebhook]: parseHttpWebhookOperation,
251
257
  [types.NodeType.HttpService]: parseHttpService,
252
258
  [types.NodeType.Model]: parseModel,
253
259
  [types.NodeType.HttpServer]: parseUnknown,
@@ -280,6 +286,16 @@ function parseHttpOperation(rawData) {
280
286
  }
281
287
  return undefined;
282
288
  }
289
+ function parseHttpWebhookOperation(rawData) {
290
+ const data = tryParseYamlOrObject(rawData);
291
+ if (isHttpWebhookOperation(data)) {
292
+ return {
293
+ type: types.NodeType.HttpWebhook,
294
+ data: data,
295
+ };
296
+ }
297
+ return undefined;
298
+ }
283
299
  function parseHttpService(rawData) {
284
300
  const data = tryParseYamlOrObject(rawData);
285
301
  if (isHttpService(data)) {
@@ -395,6 +411,16 @@ var faDatabase = {
395
411
  iconName: 'database',
396
412
  icon: [448, 512, [], "f1c0", "M448 80V128C448 172.2 347.7 208 224 208C100.3 208 0 172.2 0 128V80C0 35.82 100.3 0 224 0C347.7 0 448 35.82 448 80zM393.2 214.7C413.1 207.3 433.1 197.8 448 186.1V288C448 332.2 347.7 368 224 368C100.3 368 0 332.2 0 288V186.1C14.93 197.8 34.02 207.3 54.85 214.7C99.66 230.7 159.5 240 224 240C288.5 240 348.3 230.7 393.2 214.7V214.7zM54.85 374.7C99.66 390.7 159.5 400 224 400C288.5 400 348.3 390.7 393.2 374.7C413.1 367.3 433.1 357.8 448 346.1V432C448 476.2 347.7 512 224 512C100.3 512 0 476.2 0 432V346.1C14.93 357.8 34.02 367.3 54.85 374.7z"]
397
413
  };
414
+ var faEnvelope = {
415
+ prefix: 'fas',
416
+ iconName: 'envelope',
417
+ icon: [512, 512, [128386, 61443, 9993], "f0e0", "M464 64C490.5 64 512 85.49 512 112C512 127.1 504.9 141.3 492.8 150.4L275.2 313.6C263.8 322.1 248.2 322.1 236.8 313.6L19.2 150.4C7.113 141.3 0 127.1 0 112C0 85.49 21.49 64 48 64H464zM217.6 339.2C240.4 356.3 271.6 356.3 294.4 339.2L512 176V384C512 419.3 483.3 448 448 448H64C28.65 448 0 419.3 0 384V176L217.6 339.2z"]
418
+ };
419
+ var faEnvelopesBulk = {
420
+ prefix: 'fas',
421
+ iconName: 'envelopes-bulk',
422
+ icon: [640, 512, ["mail-bulk"], "f674", "M191.9 448.6c-9.766 0-19.48-2.969-27.78-8.891L32 340.2V480c0 17.62 14.38 32 32 32h256c17.62 0 32-14.38 32-32v-139.8L220.2 439.5C211.7 445.6 201.8 448.6 191.9 448.6zM192 192c0-35.25 28.75-64 64-64h224V32c0-17.62-14.38-32-32-32H128C110.4 0 96 14.38 96 32v192h96V192zM320 256H64C46.38 256 32 270.4 32 288v12.18l151 113.8c5.25 3.719 12.7 3.734 18.27-.25L352 300.2V288C352 270.4 337.6 256 320 256zM576 160H256C238.4 160 224 174.4 224 192v32h96c33.25 0 60.63 25.38 63.75 57.88L384 416h192c17.62 0 32-14.38 32-32V192C608 174.4 593.6 160 576 160zM544 288h-64V224h64V288z"]
423
+ };
398
424
  var faEye = {
399
425
  prefix: 'fas',
400
426
  iconName: 'eye',
@@ -413,6 +439,7 @@ var faServer = {
413
439
 
414
440
  const NodeTypeColors = {
415
441
  http_operation: '#6a6acb',
442
+ http_webhook: 'primary',
416
443
  http_service: '#e056fd',
417
444
  article: '#399da6',
418
445
  model: '#ef932b',
@@ -429,6 +456,7 @@ const NodeTypeColors = {
429
456
  };
430
457
  const NodeTypePrettyName = {
431
458
  http_operation: 'Endpoint',
459
+ http_webhook: 'Webhook',
432
460
  http_service: 'API',
433
461
  article: 'Article',
434
462
  model: 'Model',
@@ -445,6 +473,7 @@ const NodeTypePrettyName = {
445
473
  };
446
474
  const NodeTypeIconDefs = {
447
475
  http_operation: faCrosshairs,
476
+ http_webhook: faEnvelope,
448
477
  http_service: faCloud,
449
478
  article: faBookOpen,
450
479
  model: faCube,
@@ -2194,7 +2223,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2194
2223
  }, [servers, firstServer, chosenServer, setChosenServer]);
2195
2224
  React__namespace.useEffect(() => {
2196
2225
  let isMounted = true;
2197
- if (onRequestChange || embeddedInMd) {
2226
+ if (isHttpOperation(httpOperation) && (onRequestChange || embeddedInMd)) {
2198
2227
  buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, serverVariableValues,
2199
2228
  httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
2200
2229
  corsProxy })).then(request => {
@@ -2227,7 +2256,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2227
2256
  ]);
2228
2257
  const handleSendRequest = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
2229
2258
  setValidateParameters(true);
2230
- if (hasRequiredButEmptyParameters)
2259
+ if (hasRequiredButEmptyParameters || !isHttpOperation(httpOperation))
2231
2260
  return;
2232
2261
  try {
2233
2262
  setLoading(true);
@@ -2275,23 +2304,33 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2275
2304
  const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
2276
2305
  const tryItPanelContents = (React__namespace.createElement(React__namespace.Fragment, null,
2277
2306
  ((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React__namespace.createElement(TryItAuth, { operationSecuritySchemes: httpOperation.security, operationAuthValue: operationAuthValue, setOperationAuthValue: setOperationAuthValue, setCurrentScheme: setCurrentScheme })) : null,
2278
- serverVariables.length > 0 && (React__namespace.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2307
+ isHttpOperation(httpOperation) && serverVariables.length > 0 && (React__namespace.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2279
2308
  allParameters.length > 0 && (React__namespace.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
2280
- formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
2281
- React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2309
+ React__namespace.createElement(mosaic.Box, { pb: 1 }, formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null),
2310
+ isHttpOperation(httpOperation) ? (React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2282
2311
  React__namespace.createElement(mosaic.HStack, { alignItems: "center", spacing: 2 },
2283
2312
  React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
2284
2313
  servers.length > 1 && React__namespace.createElement(ServersDropdown, { servers: servers }),
2285
2314
  isMockingEnabled && (React__namespace.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
2286
2315
  validateParameters && hasRequiredButEmptyParameters && (React__namespace.createElement(mosaic.Box, { mt: 4, color: "danger-light", fontSize: "sm" },
2287
2316
  React__namespace.createElement(mosaic.Icon, { icon: ['fas', 'exclamation-triangle'], className: "sl-mr-1" }),
2288
- "You didn't provide all of the required parameters!")))));
2317
+ "You didn't provide all of the required parameters!")))) : null));
2289
2318
  let tryItPanelElem;
2290
2319
  if (embeddedInMd) {
2320
+ let path;
2321
+ if (isHttpOperation(httpOperation)) {
2322
+ path = httpOperation.path;
2323
+ }
2324
+ else if (isHttpWebhookOperation(httpOperation)) {
2325
+ path = httpOperation.name;
2326
+ }
2327
+ else {
2328
+ throw new RangeError('unsupported type');
2329
+ }
2291
2330
  tryItPanelElem = (React__namespace.createElement(mosaic.Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
2292
2331
  React__namespace.createElement(mosaic.Panel.Titlebar, { bg: "canvas-300" },
2293
2332
  React__namespace.createElement(mosaic.Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
2294
- React__namespace.createElement(mosaic.Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
2333
+ React__namespace.createElement(mosaic.Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${path}`)),
2295
2334
  tryItPanelContents));
2296
2335
  }
2297
2336
  else {
@@ -2769,7 +2808,17 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2769
2808
  const [requestBodyIndex, setTextRequestBodyIndex] = React__namespace.useState(0);
2770
2809
  const prettyName = (data.summary || data.iid || '').trim();
2771
2810
  const hasBadges = isDeprecated || isInternal;
2772
- const header = (React__namespace.createElement(OperationHeader, { id: data.id, method: data.method, path: data.path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal }));
2811
+ let path;
2812
+ if (isHttpOperation(data)) {
2813
+ path = data.path;
2814
+ }
2815
+ else if (isHttpWebhookOperation(data)) {
2816
+ path = data.name;
2817
+ }
2818
+ else {
2819
+ throw new RangeError('unsupported node type');
2820
+ }
2821
+ const header = (React__namespace.createElement(OperationHeader, { id: data.id, method: data.method, path: path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal, hideServerUrl: !isHttpOperation(data) }));
2773
2822
  const tryItPanel = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryItPanel) && (React__namespace.createElement(TryItWithRequestSamples, { httpOperation: data, responseMediaType: responseMediaType, responseStatusCode: responseStatusCode, requestBodyIndex: requestBodyIndex, hideTryIt: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryIt, tryItCredentialsPolicy: tryItCredentialsPolicy, mockUrl: mocking.hideMocking ? undefined : mocking.mockUrl, corsProxy: tryItCorsProxy }));
2774
2823
  const descriptionChanged = nodeHasChanged === null || nodeHasChanged === void 0 ? void 0 : nodeHasChanged({ nodeId: data.id, attr: 'description' });
2775
2824
  const description = (React__namespace.createElement(mosaic.VStack, { spacing: 10 },
@@ -3092,6 +3141,7 @@ const ParsedDocs = (_a) => {
3092
3141
  case 'article':
3093
3142
  return React__namespace.createElement(Article, Object.assign({ data: node.data }, commonProps));
3094
3143
  case 'http_operation':
3144
+ case 'http_webhook':
3095
3145
  return React__namespace.createElement(HttpOperation, Object.assign({ data: node.data }, commonProps));
3096
3146
  case 'http_service':
3097
3147
  return React__namespace.createElement(HttpService, Object.assign({ data: node.data }, commonProps));
@@ -3287,6 +3337,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
3287
3337
  return (React__default["default"].createElement(reactRouterHashLink.HashLink, { to: href, title: title }, children));
3288
3338
  };
3289
3339
 
3340
+ const NonIdealState = ({ description, icon, title }) => {
3341
+ return (React__namespace.createElement(mosaic.Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3342
+ React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3343
+ React__namespace.createElement(mosaic.Heading, { size: 4, mb: 4 }, title),
3344
+ React__namespace.createElement(mosaic.Text, null, description)));
3345
+ };
3346
+
3290
3347
  function useFirstRender() {
3291
3348
  const ref = React__default["default"].useRef(true);
3292
3349
  const firstRender = ref.current;
@@ -3297,21 +3354,26 @@ function useFirstRender() {
3297
3354
  const NODE_TYPE_TITLE_ICON = {
3298
3355
  http_service: faCloud,
3299
3356
  http_operation: faBullseye,
3357
+ http_webhook: faEnvelope,
3300
3358
  model: faCube,
3301
3359
  };
3302
- const NODE_TITLE_ICON = {
3303
- Schemas: faCubes,
3360
+ const NODE_GROUP_ICON = {
3361
+ http_webhook: faEnvelopesBulk,
3362
+ model: faCubes,
3304
3363
  };
3305
3364
  const NODE_TYPE_META_ICON = {
3365
+ webhook: faEnvelope,
3306
3366
  model: faCube,
3307
3367
  };
3308
3368
  const NODE_TYPE_ICON_COLOR = {
3309
3369
  model: 'warning',
3310
3370
  http_service: '#D812EA',
3311
3371
  http_operation: '#9747FF',
3372
+ http_webhook: 'primary',
3312
3373
  };
3313
- const NODE_TITLE_ICON_COLOR = {
3314
- Schemas: 'warning',
3374
+ const NODE_GROUP_ICON_COLOR = {
3375
+ http_webhook: 'primary',
3376
+ model: 'warning',
3315
3377
  };
3316
3378
  const NODE_META_COLOR = {
3317
3379
  get: 'success',
@@ -3364,7 +3426,7 @@ function isDivider(item) {
3364
3426
  return Object.keys(item).length === 1 && 'title' in item;
3365
3427
  }
3366
3428
  function isGroup(item) {
3367
- return Object.keys(item).length === 2 && 'title' in item && 'items' in item;
3429
+ return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
3368
3430
  }
3369
3431
  function isNodeGroup(item) {
3370
3432
  return 'title' in item && 'items' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
@@ -3378,6 +3440,7 @@ function isExternalLink(item) {
3378
3440
 
3379
3441
  const ActiveIdContext = React__namespace.createContext(undefined);
3380
3442
  const LinkContext = React__namespace.createContext(undefined);
3443
+ LinkContext.displayName = 'LinkContext';
3381
3444
  const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
3382
3445
  const container = React__namespace.useRef(null);
3383
3446
  const child = React__namespace.useRef(null);
@@ -3406,9 +3469,11 @@ const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthO
3406
3469
  return (React__namespace.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3407
3470
  }))))));
3408
3471
  });
3472
+ TableOfContents.displayName = 'TableOfContents';
3409
3473
  const Divider = React__namespace.memo(({ item, isInResponsiveMode = false }) => {
3410
3474
  return (React__namespace.createElement(mosaic.Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
3411
3475
  });
3476
+ Divider.displayName = 'Divider';
3412
3477
  const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick }) => {
3413
3478
  if (isExternalLink(item)) {
3414
3479
  return (React__namespace.createElement(mosaic.Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
@@ -3424,6 +3489,7 @@ const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, i
3424
3489
  }
3425
3490
  return null;
3426
3491
  });
3492
+ GroupItem.displayName = 'GroupItem';
3427
3493
  const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick = () => { } }) => {
3428
3494
  const activeId = React__namespace.useContext(ActiveIdContext);
3429
3495
  const [isOpen, setIsOpen] = React__namespace.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
@@ -3455,7 +3521,8 @@ const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInR
3455
3521
  elem = (React__namespace.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3456
3522
  }
3457
3523
  else {
3458
- elem = (React__namespace.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: NODE_TITLE_ICON[item.title] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TITLE_ICON_COLOR[item.title], icon: NODE_TITLE_ICON[item.title] })) }));
3524
+ elem = (React__namespace.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
3525
+ NODE_GROUP_ICON[item.itemsType] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_GROUP_ICON_COLOR[item.itemsType], icon: NODE_GROUP_ICON[item.itemsType] })) }));
3459
3526
  }
3460
3527
  return (React__namespace.createElement(React__namespace.Fragment, null,
3461
3528
  elem,
@@ -3464,6 +3531,7 @@ const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInR
3464
3531
  return (React__namespace.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3465
3532
  })));
3466
3533
  });
3534
+ Group.displayName = 'Group';
3467
3535
  const Item = React__namespace.memo(({ depth, isActive, id, title, meta, icon, isInResponsiveMode, onClick }) => {
3468
3536
  return (React__namespace.createElement(mosaic.Flex, { id: id, bg: {
3469
3537
  default: isInResponsiveMode ? 'canvas' : isActive ? 'primary-tint' : 'canvas-100',
@@ -3473,6 +3541,7 @@ const Item = React__namespace.memo(({ depth, isActive, id, title, meta, icon, is
3473
3541
  React__namespace.createElement(mosaic.Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate", fontSize: isInResponsiveMode ? 'lg' : 'base' }, title),
3474
3542
  React__namespace.createElement(mosaic.Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
3475
3543
  });
3544
+ Item.displayName = 'Item';
3476
3545
  const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, makeSlugAbsoluteRoute, onClick, onLinkClick = () => { } }) => {
3477
3546
  const activeId = React__namespace.useContext(ActiveIdContext);
3478
3547
  const isActive = activeId === item.slug || activeId === item.id;
@@ -3492,18 +3561,12 @@ const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInRespo
3492
3561
  return (React__namespace.createElement(mosaic.Box, { as: LinkComponent, to: makeSlugAbsoluteRoute && !item.slug.startsWith('/') ? `/${item.slug}` : item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
3493
3562
  React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
3494
3563
  });
3564
+ Node.displayName = 'Node';
3495
3565
  const Version = ({ value }) => {
3496
3566
  return (React__namespace.createElement(mosaic.Box, { mr: 2 },
3497
3567
  React__namespace.createElement(VersionBadge, { value: value, backgroundColor: "#909DAB" })));
3498
3568
  };
3499
3569
 
3500
- const NonIdealState = ({ description, icon, title }) => {
3501
- return (React__namespace.createElement(mosaic.Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3502
- React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3503
- React__namespace.createElement(mosaic.Heading, { size: 4, mb: 4 }, title),
3504
- React__namespace.createElement(mosaic.Text, null, description)));
3505
- };
3506
-
3507
3570
  function withMosaicProvider(WrappedComponent) {
3508
3571
  const WithMosaicProvider = (props) => {
3509
3572
  try {
@@ -3786,6 +3849,7 @@ exports.createResolvedObject = createResolvedObject;
3786
3849
  exports.findFirstNode = findFirstNode;
3787
3850
  exports.isHttpOperation = isHttpOperation;
3788
3851
  exports.isHttpService = isHttpService;
3852
+ exports.isHttpWebhookOperation = isHttpWebhookOperation;
3789
3853
  exports.slugify = slugify;
3790
3854
  exports.useBundleRefsIntoDocument = useBundleRefsIntoDocument;
3791
3855
  exports.useParsedData = useParsedData;
package/index.mjs CHANGED
@@ -180,6 +180,11 @@ function isHttpService(maybeHttpService) {
180
180
  function isHttpOperation(maybeHttpOperation) {
181
181
  return isStoplightNode(maybeHttpOperation) && 'method' in maybeHttpOperation && 'path' in maybeHttpOperation;
182
182
  }
183
+ function isHttpWebhookOperation(maybeHttpWebhookOperation) {
184
+ return (isStoplightNode(maybeHttpWebhookOperation) &&
185
+ 'method' in maybeHttpWebhookOperation &&
186
+ 'name' in maybeHttpWebhookOperation);
187
+ }
183
188
  const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
184
189
  function isProperUrl(url) {
185
190
  return properUrl.test(url);
@@ -191,6 +196,7 @@ function useParsedData(nodeType, data) {
191
196
  const parserMap = {
192
197
  [NodeType.Article]: parseArticleData,
193
198
  [NodeType.HttpOperation]: parseHttpOperation,
199
+ [NodeType.HttpWebhook]: parseHttpWebhookOperation,
194
200
  [NodeType.HttpService]: parseHttpService,
195
201
  [NodeType.Model]: parseModel,
196
202
  [NodeType.HttpServer]: parseUnknown,
@@ -223,6 +229,16 @@ function parseHttpOperation(rawData) {
223
229
  }
224
230
  return undefined;
225
231
  }
232
+ function parseHttpWebhookOperation(rawData) {
233
+ const data = tryParseYamlOrObject(rawData);
234
+ if (isHttpWebhookOperation(data)) {
235
+ return {
236
+ type: NodeType.HttpWebhook,
237
+ data: data,
238
+ };
239
+ }
240
+ return undefined;
241
+ }
226
242
  function parseHttpService(rawData) {
227
243
  const data = tryParseYamlOrObject(rawData);
228
244
  if (isHttpService(data)) {
@@ -338,6 +354,16 @@ var faDatabase = {
338
354
  iconName: 'database',
339
355
  icon: [448, 512, [], "f1c0", "M448 80V128C448 172.2 347.7 208 224 208C100.3 208 0 172.2 0 128V80C0 35.82 100.3 0 224 0C347.7 0 448 35.82 448 80zM393.2 214.7C413.1 207.3 433.1 197.8 448 186.1V288C448 332.2 347.7 368 224 368C100.3 368 0 332.2 0 288V186.1C14.93 197.8 34.02 207.3 54.85 214.7C99.66 230.7 159.5 240 224 240C288.5 240 348.3 230.7 393.2 214.7V214.7zM54.85 374.7C99.66 390.7 159.5 400 224 400C288.5 400 348.3 390.7 393.2 374.7C413.1 367.3 433.1 357.8 448 346.1V432C448 476.2 347.7 512 224 512C100.3 512 0 476.2 0 432V346.1C14.93 357.8 34.02 367.3 54.85 374.7z"]
340
356
  };
357
+ var faEnvelope = {
358
+ prefix: 'fas',
359
+ iconName: 'envelope',
360
+ icon: [512, 512, [128386, 61443, 9993], "f0e0", "M464 64C490.5 64 512 85.49 512 112C512 127.1 504.9 141.3 492.8 150.4L275.2 313.6C263.8 322.1 248.2 322.1 236.8 313.6L19.2 150.4C7.113 141.3 0 127.1 0 112C0 85.49 21.49 64 48 64H464zM217.6 339.2C240.4 356.3 271.6 356.3 294.4 339.2L512 176V384C512 419.3 483.3 448 448 448H64C28.65 448 0 419.3 0 384V176L217.6 339.2z"]
361
+ };
362
+ var faEnvelopesBulk = {
363
+ prefix: 'fas',
364
+ iconName: 'envelopes-bulk',
365
+ icon: [640, 512, ["mail-bulk"], "f674", "M191.9 448.6c-9.766 0-19.48-2.969-27.78-8.891L32 340.2V480c0 17.62 14.38 32 32 32h256c17.62 0 32-14.38 32-32v-139.8L220.2 439.5C211.7 445.6 201.8 448.6 191.9 448.6zM192 192c0-35.25 28.75-64 64-64h224V32c0-17.62-14.38-32-32-32H128C110.4 0 96 14.38 96 32v192h96V192zM320 256H64C46.38 256 32 270.4 32 288v12.18l151 113.8c5.25 3.719 12.7 3.734 18.27-.25L352 300.2V288C352 270.4 337.6 256 320 256zM576 160H256C238.4 160 224 174.4 224 192v32h96c33.25 0 60.63 25.38 63.75 57.88L384 416h192c17.62 0 32-14.38 32-32V192C608 174.4 593.6 160 576 160zM544 288h-64V224h64V288z"]
366
+ };
341
367
  var faEye = {
342
368
  prefix: 'fas',
343
369
  iconName: 'eye',
@@ -356,6 +382,7 @@ var faServer = {
356
382
 
357
383
  const NodeTypeColors = {
358
384
  http_operation: '#6a6acb',
385
+ http_webhook: 'primary',
359
386
  http_service: '#e056fd',
360
387
  article: '#399da6',
361
388
  model: '#ef932b',
@@ -372,6 +399,7 @@ const NodeTypeColors = {
372
399
  };
373
400
  const NodeTypePrettyName = {
374
401
  http_operation: 'Endpoint',
402
+ http_webhook: 'Webhook',
375
403
  http_service: 'API',
376
404
  article: 'Article',
377
405
  model: 'Model',
@@ -388,6 +416,7 @@ const NodeTypePrettyName = {
388
416
  };
389
417
  const NodeTypeIconDefs = {
390
418
  http_operation: faCrosshairs,
419
+ http_webhook: faEnvelope,
391
420
  http_service: faCloud,
392
421
  article: faBookOpen,
393
422
  model: faCube,
@@ -2137,7 +2166,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2137
2166
  }, [servers, firstServer, chosenServer, setChosenServer]);
2138
2167
  React.useEffect(() => {
2139
2168
  let isMounted = true;
2140
- if (onRequestChange || embeddedInMd) {
2169
+ if (isHttpOperation(httpOperation) && (onRequestChange || embeddedInMd)) {
2141
2170
  buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, serverVariableValues,
2142
2171
  httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
2143
2172
  corsProxy })).then(request => {
@@ -2170,7 +2199,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2170
2199
  ]);
2171
2200
  const handleSendRequest = () => __awaiter(void 0, void 0, void 0, function* () {
2172
2201
  setValidateParameters(true);
2173
- if (hasRequiredButEmptyParameters)
2202
+ if (hasRequiredButEmptyParameters || !isHttpOperation(httpOperation))
2174
2203
  return;
2175
2204
  try {
2176
2205
  setLoading(true);
@@ -2218,23 +2247,33 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2218
2247
  const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
2219
2248
  const tryItPanelContents = (React.createElement(React.Fragment, null,
2220
2249
  ((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React.createElement(TryItAuth, { operationSecuritySchemes: httpOperation.security, operationAuthValue: operationAuthValue, setOperationAuthValue: setOperationAuthValue, setCurrentScheme: setCurrentScheme })) : null,
2221
- serverVariables.length > 0 && (React.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2250
+ isHttpOperation(httpOperation) && serverVariables.length > 0 && (React.createElement(ServerVariables, { variables: serverVariables, values: serverVariableValues, onChangeValue: updateServerVariableValue })),
2222
2251
  allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
2223
- formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
2224
- React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2252
+ React.createElement(Box, { pb: 1 }, formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_f = mediaTypeContent.examples) !== null && _f !== void 0 ? _f : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null),
2253
+ isHttpOperation(httpOperation) ? (React.createElement(Panel.Content, { className: "SendButtonHolder", pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
2225
2254
  React.createElement(HStack, { alignItems: "center", spacing: 2 },
2226
2255
  React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
2227
2256
  servers.length > 1 && React.createElement(ServersDropdown, { servers: servers }),
2228
2257
  isMockingEnabled && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
2229
2258
  validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
2230
2259
  React.createElement(Icon, { icon: ['fas', 'exclamation-triangle'], className: "sl-mr-1" }),
2231
- "You didn't provide all of the required parameters!")))));
2260
+ "You didn't provide all of the required parameters!")))) : null));
2232
2261
  let tryItPanelElem;
2233
2262
  if (embeddedInMd) {
2263
+ let path;
2264
+ if (isHttpOperation(httpOperation)) {
2265
+ path = httpOperation.path;
2266
+ }
2267
+ else if (isHttpWebhookOperation(httpOperation)) {
2268
+ path = httpOperation.name;
2269
+ }
2270
+ else {
2271
+ throw new RangeError('unsupported type');
2272
+ }
2234
2273
  tryItPanelElem = (React.createElement(Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
2235
2274
  React.createElement(Panel.Titlebar, { bg: "canvas-300" },
2236
2275
  React.createElement(Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
2237
- React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
2276
+ React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${path}`)),
2238
2277
  tryItPanelContents));
2239
2278
  }
2240
2279
  else {
@@ -2712,7 +2751,17 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
2712
2751
  const [requestBodyIndex, setTextRequestBodyIndex] = React.useState(0);
2713
2752
  const prettyName = (data.summary || data.iid || '').trim();
2714
2753
  const hasBadges = isDeprecated || isInternal;
2715
- const header = (React.createElement(OperationHeader, { id: data.id, method: data.method, path: data.path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal }));
2754
+ let path;
2755
+ if (isHttpOperation(data)) {
2756
+ path = data.path;
2757
+ }
2758
+ else if (isHttpWebhookOperation(data)) {
2759
+ path = data.name;
2760
+ }
2761
+ else {
2762
+ throw new RangeError('unsupported node type');
2763
+ }
2764
+ const header = (React.createElement(OperationHeader, { id: data.id, method: data.method, path: path, noHeading: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading, hasBadges: hasBadges, name: prettyName, isDeprecated: isDeprecated, isInternal: isInternal, hideServerUrl: !isHttpOperation(data) }));
2716
2765
  const tryItPanel = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryItPanel) && (React.createElement(TryItWithRequestSamples, { httpOperation: data, responseMediaType: responseMediaType, responseStatusCode: responseStatusCode, requestBodyIndex: requestBodyIndex, hideTryIt: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryIt, tryItCredentialsPolicy: tryItCredentialsPolicy, mockUrl: mocking.hideMocking ? undefined : mocking.mockUrl, corsProxy: tryItCorsProxy }));
2717
2766
  const descriptionChanged = nodeHasChanged === null || nodeHasChanged === void 0 ? void 0 : nodeHasChanged({ nodeId: data.id, attr: 'description' });
2718
2767
  const description = (React.createElement(VStack, { spacing: 10 },
@@ -3035,6 +3084,7 @@ const ParsedDocs = (_a) => {
3035
3084
  case 'article':
3036
3085
  return React.createElement(Article, Object.assign({ data: node.data }, commonProps));
3037
3086
  case 'http_operation':
3087
+ case 'http_webhook':
3038
3088
  return React.createElement(HttpOperation, Object.assign({ data: node.data }, commonProps));
3039
3089
  case 'http_service':
3040
3090
  return React.createElement(HttpService, Object.assign({ data: node.data }, commonProps));
@@ -3230,6 +3280,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
3230
3280
  return (React__default.createElement(HashLink, { to: href, title: title }, children));
3231
3281
  };
3232
3282
 
3283
+ const NonIdealState = ({ description, icon, title }) => {
3284
+ return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3285
+ React.createElement(Box, { as: Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3286
+ React.createElement(Heading, { size: 4, mb: 4 }, title),
3287
+ React.createElement(Text, null, description)));
3288
+ };
3289
+
3233
3290
  function useFirstRender() {
3234
3291
  const ref = React__default.useRef(true);
3235
3292
  const firstRender = ref.current;
@@ -3240,21 +3297,26 @@ function useFirstRender() {
3240
3297
  const NODE_TYPE_TITLE_ICON = {
3241
3298
  http_service: faCloud,
3242
3299
  http_operation: faBullseye,
3300
+ http_webhook: faEnvelope,
3243
3301
  model: faCube,
3244
3302
  };
3245
- const NODE_TITLE_ICON = {
3246
- Schemas: faCubes,
3303
+ const NODE_GROUP_ICON = {
3304
+ http_webhook: faEnvelopesBulk,
3305
+ model: faCubes,
3247
3306
  };
3248
3307
  const NODE_TYPE_META_ICON = {
3308
+ webhook: faEnvelope,
3249
3309
  model: faCube,
3250
3310
  };
3251
3311
  const NODE_TYPE_ICON_COLOR = {
3252
3312
  model: 'warning',
3253
3313
  http_service: '#D812EA',
3254
3314
  http_operation: '#9747FF',
3315
+ http_webhook: 'primary',
3255
3316
  };
3256
- const NODE_TITLE_ICON_COLOR = {
3257
- Schemas: 'warning',
3317
+ const NODE_GROUP_ICON_COLOR = {
3318
+ http_webhook: 'primary',
3319
+ model: 'warning',
3258
3320
  };
3259
3321
  const NODE_META_COLOR = {
3260
3322
  get: 'success',
@@ -3307,7 +3369,7 @@ function isDivider(item) {
3307
3369
  return Object.keys(item).length === 1 && 'title' in item;
3308
3370
  }
3309
3371
  function isGroup(item) {
3310
- return Object.keys(item).length === 2 && 'title' in item && 'items' in item;
3372
+ return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
3311
3373
  }
3312
3374
  function isNodeGroup(item) {
3313
3375
  return 'title' in item && 'items' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
@@ -3321,6 +3383,7 @@ function isExternalLink(item) {
3321
3383
 
3322
3384
  const ActiveIdContext = React.createContext(undefined);
3323
3385
  const LinkContext = React.createContext(undefined);
3386
+ LinkContext.displayName = 'LinkContext';
3324
3387
  const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
3325
3388
  const container = React.useRef(null);
3326
3389
  const child = React.useRef(null);
@@ -3349,9 +3412,11 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
3349
3412
  return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3350
3413
  }))))));
3351
3414
  });
3415
+ TableOfContents.displayName = 'TableOfContents';
3352
3416
  const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
3353
3417
  return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
3354
3418
  });
3419
+ Divider.displayName = 'Divider';
3355
3420
  const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick }) => {
3356
3421
  if (isExternalLink(item)) {
3357
3422
  return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
@@ -3367,6 +3432,7 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsi
3367
3432
  }
3368
3433
  return null;
3369
3434
  });
3435
+ GroupItem.displayName = 'GroupItem';
3370
3436
  const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, makeSlugAbsoluteRoute, onLinkClick = () => { } }) => {
3371
3437
  const activeId = React.useContext(ActiveIdContext);
3372
3438
  const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
@@ -3398,7 +3464,8 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
3398
3464
  elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3399
3465
  }
3400
3466
  else {
3401
- elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: NODE_TITLE_ICON[item.title] && (React.createElement(Box, { as: Icon, color: NODE_TITLE_ICON_COLOR[item.title], icon: NODE_TITLE_ICON[item.title] })) }));
3467
+ elem = (React.createElement(Item, { isInResponsiveMode: isInResponsiveMode, title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive, icon: item.itemsType &&
3468
+ NODE_GROUP_ICON[item.itemsType] && (React.createElement(Box, { as: Icon, color: NODE_GROUP_ICON_COLOR[item.itemsType], icon: NODE_GROUP_ICON[item.itemsType] })) }));
3402
3469
  }
3403
3470
  return (React.createElement(React.Fragment, null,
3404
3471
  elem,
@@ -3407,6 +3474,7 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMo
3407
3474
  return (React.createElement(GroupItem, { key: key, item: groupItem, depth: depth + 1, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode, makeSlugAbsoluteRoute: makeSlugAbsoluteRoute }));
3408
3475
  })));
3409
3476
  });
3477
+ Group.displayName = 'Group';
3410
3478
  const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiveMode, onClick }) => {
3411
3479
  return (React.createElement(Flex, { id: id, bg: {
3412
3480
  default: isInResponsiveMode ? 'canvas' : isActive ? 'primary-tint' : 'canvas-100',
@@ -3416,6 +3484,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
3416
3484
  React.createElement(Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate", fontSize: isInResponsiveMode ? 'lg' : 'base' }, title),
3417
3485
  React.createElement(Flex, { alignItems: "center", fontSize: isInResponsiveMode ? 'base' : 'xs' }, meta)));
3418
3486
  });
3487
+ Item.displayName = 'Item';
3419
3488
  const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, makeSlugAbsoluteRoute, onClick, onLinkClick = () => { } }) => {
3420
3489
  const activeId = React.useContext(ActiveIdContext);
3421
3490
  const isActive = activeId === item.slug || activeId === item.id;
@@ -3435,18 +3504,12 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
3435
3504
  return (React.createElement(Box, { as: LinkComponent, to: makeSlugAbsoluteRoute && !item.slug.startsWith('/') ? `/${item.slug}` : item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
3436
3505
  React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
3437
3506
  });
3507
+ Node.displayName = 'Node';
3438
3508
  const Version = ({ value }) => {
3439
3509
  return (React.createElement(Box, { mr: 2 },
3440
3510
  React.createElement(VersionBadge, { value: value, backgroundColor: "#909DAB" })));
3441
3511
  };
3442
3512
 
3443
- const NonIdealState = ({ description, icon, title }) => {
3444
- return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
3445
- React.createElement(Box, { as: Icon, icon: icon || ['fas', 'exclamation-triangle'], color: "light", fontSize: "6xl", mb: 4 }),
3446
- React.createElement(Heading, { size: 4, mb: 4 }, title),
3447
- React.createElement(Text, null, description)));
3448
- };
3449
-
3450
3513
  function withMosaicProvider(WrappedComponent) {
3451
3514
  const WithMosaicProvider = (props) => {
3452
3515
  try {
@@ -3698,4 +3761,4 @@ const createElementClass = (Component, propDescriptors) => {
3698
3761
  };
3699
3762
  };
3700
3763
 
3701
- export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
3764
+ export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, RouterTypeContext, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, isHttpWebhookOperation, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoplight/elements-core",
3
- "version": "7.16.6",
3
+ "version": "8.0.0",
4
4
  "main": "./index.js",
5
5
  "sideEffects": [
6
6
  "web-components.min.js",
@@ -24,7 +24,7 @@
24
24
  "react-dom": ">=16.8"
25
25
  },
26
26
  "dependencies": {
27
- "@stoplight/http-spec": "^6.0.0",
27
+ "@stoplight/http-spec": "^7.0.1",
28
28
  "@stoplight/json": "^3.18.1",
29
29
  "@stoplight/json-schema-ref-parser": "^9.0.5",
30
30
  "@stoplight/json-schema-sampler": "0.2.3",
@@ -36,7 +36,7 @@
36
36
  "@stoplight/mosaic-code-viewer": "^1.46.1",
37
37
  "@stoplight/path": "^1.3.2",
38
38
  "@stoplight/react-error-boundary": "^3.0.0",
39
- "@stoplight/types": "^14.0.0",
39
+ "@stoplight/types": "^14.1.1",
40
40
  "@stoplight/yaml": "^4.2.3",
41
41
  "classnames": "^2.2.6",
42
42
  "httpsnippet-lite": "^3.0.5",
package/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
2
- import { IHttpOperation, IHttpService, NodeType } from '@stoplight/types';
2
+ import { IHttpOperation, IHttpService, IHttpWebhookOperation, NodeType } from '@stoplight/types';
3
3
  import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
4
4
  export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
5
5
  export declare type ParsedNode = {
@@ -8,6 +8,9 @@ export declare type ParsedNode = {
8
8
  } | {
9
9
  type: NodeType.HttpOperation;
10
10
  data: IHttpOperation;
11
+ } | {
12
+ type: NodeType.HttpWebhook;
13
+ data: IHttpWebhookOperation;
11
14
  } | {
12
15
  type: NodeType.HttpService;
13
16
  data: IHttpService;
package/utils/guards.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
2
- import { IHttpOperation, IHttpService } from '@stoplight/types';
2
+ import { IHttpOperation, IHttpService, IHttpWebhookOperation } from '@stoplight/types';
3
3
  import { JSONSchema7 } from 'json-schema';
4
4
  export declare function isSMDASTRoot(maybeAst: unknown): maybeAst is IMarkdownViewerProps['markdown'];
5
5
  export declare function isJSONSchema(maybeSchema: unknown): maybeSchema is JSONSchema7;
6
6
  export declare function isHttpService(maybeHttpService: unknown): maybeHttpService is IHttpService;
7
7
  export declare function isHttpOperation(maybeHttpOperation: unknown): maybeHttpOperation is IHttpOperation;
8
+ export declare function isHttpWebhookOperation(maybeHttpWebhookOperation: unknown): maybeHttpWebhookOperation is IHttpWebhookOperation;
8
9
  export declare function isProperUrl(url: string): boolean;