@jpmorganchase/elemental-dev-portal 1.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/components/BranchSelector/BranchSelector.d.ts +7 -0
- package/components/BranchSelector/BranchSelector.spec.d.ts +15 -0
- package/components/BranchSelector/BranchSelector.stories.d.ts +29 -0
- package/components/DevPortalProvider/index.d.ts +7 -0
- package/components/Forbidden.d.ts +1 -0
- package/components/Loading.d.ts +1 -0
- package/components/NodeContent/NodeContent.d.ts +17 -0
- package/components/NodeContent/NodeContent.spec.d.ts +1 -0
- package/components/NodeContent/NodeContent.stories.d.ts +43 -0
- package/components/NotFound.d.ts +1 -0
- package/components/Search/Search.d.ts +13 -0
- package/components/Search/Search.stories.d.ts +33 -0
- package/components/TableOfContents/TableOfContents.d.ts +12 -0
- package/components/TableOfContents/TableOfContents.stories.d.ts +36 -0
- package/components/UpgradeToStarter.d.ts +1 -0
- package/consts.d.ts +28 -0
- package/containers/StoplightProject.d.ts +13 -0
- package/containers/StoplightProject.spec.d.ts +1 -0
- package/containers/StoplightProject.stories.d.ts +45 -0
- package/handlers/getBranches.d.ts +6 -0
- package/handlers/getNodeContent.d.ts +12 -0
- package/handlers/getNodes.d.ts +9 -0
- package/handlers/getTableOfContents.d.ts +7 -0
- package/handlers/getWorkspace.d.ts +6 -0
- package/hooks/useGetBranches.d.ts +3 -0
- package/hooks/useGetNodeContent.d.ts +5 -0
- package/hooks/useGetNodes.d.ts +7 -0
- package/hooks/useGetTableOfContents.d.ts +4 -0
- package/hooks/useGetWorkspace.d.ts +3 -0
- package/index.esm.js +682 -0
- package/index.js +726 -0
- package/index.mjs +682 -0
- package/package.json +17 -70
- package/styles.min.css +1 -0
- package/types.d.ts +65 -0
- package/version.d.ts +1 -0
- package/web-components/components.d.ts +1 -0
- package/web-components/index.d.ts +1 -0
- package/web-components.min.js +2 -0
- package/web-components.min.js.LICENSE.txt +187 -0
- package/.storybook/main.js +0 -1
- package/.storybook/manager.js +0 -1
- package/.storybook/preview.jsx +0 -46
- package/jest.config.js +0 -10
- package/src/__fixtures__/branches.json +0 -26
- package/src/__fixtures__/node-content.json +0 -257
- package/src/__fixtures__/table-of-contents.json +0 -144
- package/src/components/BranchSelector/BranchSelector.spec.tsx +0 -63
- package/src/components/BranchSelector/BranchSelector.stories.tsx +0 -41
- package/src/components/BranchSelector/BranchSelector.tsx +0 -50
- package/src/components/DevPortalProvider/index.tsx +0 -19
- package/src/components/Forbidden.tsx +0 -11
- package/src/components/Loading.tsx +0 -9
- package/src/components/NodeContent/NodeContent.spec.tsx +0 -54
- package/src/components/NodeContent/NodeContent.stories.tsx +0 -60
- package/src/components/NodeContent/NodeContent.tsx +0 -171
- package/src/components/NotFound.tsx +0 -11
- package/src/components/Search/Search.stories.tsx +0 -73
- package/src/components/Search/Search.tsx +0 -133
- package/src/components/TableOfContents/TableOfContents.stories.tsx +0 -54
- package/src/components/TableOfContents/TableOfContents.tsx +0 -51
- package/src/components/UpgradeToStarter.tsx +0 -22
- package/src/consts.ts +0 -32
- package/src/containers/StoplightProject.spec.tsx +0 -78
- package/src/containers/StoplightProject.stories.tsx +0 -28
- package/src/containers/StoplightProject.tsx +0 -213
- package/src/handlers/__tests__/getBranches.test.ts +0 -30
- package/src/handlers/__tests__/getNodeContent.test.ts +0 -35
- package/src/handlers/__tests__/getNodes.test.ts +0 -38
- package/src/handlers/__tests__/getTableOfContents.test.ts +0 -34
- package/src/handlers/__tests__/getWorkspace.test.ts +0 -30
- package/src/handlers/getBranches.ts +0 -27
- package/src/handlers/getNodeContent.ts +0 -53
- package/src/handlers/getNodes.ts +0 -69
- package/src/handlers/getTableOfContents.ts +0 -30
- package/src/handlers/getWorkspace.ts +0 -27
- package/src/hooks/__tests__/dataFetching.spec.tsx +0 -42
- package/src/hooks/useGetBranches.ts +0 -17
- package/src/hooks/useGetNodeContent.ts +0 -24
- package/src/hooks/useGetNodes.ts +0 -34
- package/src/hooks/useGetTableOfContents.ts +0 -15
- package/src/hooks/useGetWorkspace.tsx +0 -13
- package/src/styles.css +0 -1
- package/src/types.ts +0 -81
- package/src/version.ts +0 -2
- package/src/web-components/__stories__/StoplightProject.stories.tsx +0 -33
- package/src/web-components/components.ts +0 -17
- package/src/web-components/index.ts +0 -3
- package/tsconfig.build.json +0 -18
- package/tsconfig.json +0 -7
- package/web-components.config.js +0 -1
- /package/{src/components/BranchSelector/index.tsx → components/BranchSelector/index.d.ts} +0 -0
- /package/{src/components/NodeContent/index.tsx → components/NodeContent/index.d.ts} +0 -0
- /package/{src/components/Search/index.tsx → components/Search/index.d.ts} +0 -0
- /package/{src/components/TableOfContents/index.tsx → components/TableOfContents/index.d.ts} +0 -0
- /package/{src/index.ts → index.d.ts} +0 -0
package/index.js
ADDED
@@ -0,0 +1,726 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
4
|
+
|
5
|
+
var mosaic = require('@stoplight/mosaic');
|
6
|
+
var React = require('react');
|
7
|
+
var elementalCore = require('@jpmorganchase/elemental-core');
|
8
|
+
var path = require('@stoplight/path');
|
9
|
+
var types = require('@stoplight/types');
|
10
|
+
var flow = require('lodash/flow.js');
|
11
|
+
var reactRouterDom = require('react-router-dom');
|
12
|
+
var reactQuery = require('react-query');
|
13
|
+
|
14
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
15
|
+
|
16
|
+
function _interopNamespace(e) {
|
17
|
+
if (e && e.__esModule) return e;
|
18
|
+
var n = Object.create(null);
|
19
|
+
if (e) {
|
20
|
+
Object.keys(e).forEach(function (k) {
|
21
|
+
if (k !== 'default') {
|
22
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
23
|
+
Object.defineProperty(n, k, d.get ? d : {
|
24
|
+
enumerable: true,
|
25
|
+
get: function () { return e[k]; }
|
26
|
+
});
|
27
|
+
}
|
28
|
+
});
|
29
|
+
}
|
30
|
+
n["default"] = e;
|
31
|
+
return Object.freeze(n);
|
32
|
+
}
|
33
|
+
|
34
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
35
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
36
|
+
var flow__default = /*#__PURE__*/_interopDefaultLegacy(flow);
|
37
|
+
|
38
|
+
const BranchSelector = ({ branchSlug, branches, onChange }) => {
|
39
|
+
const currentBranch = branches.find(branch => (!branchSlug ? branch.is_default : branch.slug === branchSlug));
|
40
|
+
const handleChange = React__namespace.useCallback((selectedSlug) => {
|
41
|
+
const selectedBranch = branches.find(branch => branch.slug === selectedSlug);
|
42
|
+
if (selectedBranch) {
|
43
|
+
onChange(selectedBranch);
|
44
|
+
}
|
45
|
+
}, [onChange, branches]);
|
46
|
+
return (React__namespace.createElement(mosaic.Menu, { "aria-label": "Versions", placement: "bottom left", closeOnPress: true, matchTriggerWidth: true, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.FieldButton, { w: "full", icon: "layer-group", px: 4, h: "md", active: isOpen, borderR: 0, roundedR: "none" }, (currentBranch === null || currentBranch === void 0 ? void 0 : currentBranch.name) || (currentBranch === null || currentBranch === void 0 ? void 0 : currentBranch.slug) || 'Choose a version')), items: [
|
47
|
+
{
|
48
|
+
type: 'option_group',
|
49
|
+
title: 'Versions',
|
50
|
+
onChange: handleChange,
|
51
|
+
value: (currentBranch === null || currentBranch === void 0 ? void 0 : currentBranch.slug) || '',
|
52
|
+
children: branches.map(branch => ({
|
53
|
+
label: branch.name || branch.slug,
|
54
|
+
value: branch.slug,
|
55
|
+
meta: branch.is_default ? 'Default' : undefined,
|
56
|
+
})),
|
57
|
+
},
|
58
|
+
] }));
|
59
|
+
};
|
60
|
+
|
61
|
+
const PlatformContext = React__namespace.createContext({ platformUrl: 'https://stoplight.io' });
|
62
|
+
const PlatformProvider = ({ platformUrl = 'https://stoplight.io', platformAuthToken, children, }) => {
|
63
|
+
return React__namespace.createElement(PlatformContext.Provider, { value: { platformUrl, platformAuthToken } }, children);
|
64
|
+
};
|
65
|
+
const DevPortalProvider = elementalCore.withPersistenceBoundary(elementalCore.withQueryClientProvider(elementalCore.withMosaicProvider(PlatformProvider)));
|
66
|
+
|
67
|
+
const NodeContent = ({ node, Link, hideMocking, refResolver, tryItCorsProxy, tryItCredentialsPolicy, nodeHasChanged, compact, hideTryIt, hideTryItPanel, hideExport, onExportRequest, }) => {
|
68
|
+
var _a, _b, _c, _d;
|
69
|
+
return (React__namespace.createElement(NodeLinkContext.Provider, { value: [node, Link] },
|
70
|
+
React__namespace.createElement(elementalCore.MarkdownComponentsProvider, { value: { a: LinkComponent } },
|
71
|
+
React__namespace.createElement(elementalCore.MockingProvider, { mockUrl: node.links.mock_url, hideMocking: hideMocking },
|
72
|
+
React__namespace.createElement(elementalCore.Docs, { nodeType: node.type, nodeData: node.data, nodeTitle: node.title, layoutOptions: {
|
73
|
+
compact,
|
74
|
+
hideTryIt: hideTryIt,
|
75
|
+
hideTryItPanel: hideTryItPanel,
|
76
|
+
hideExport: hideExport ||
|
77
|
+
((_b = (_a = node.links.export_url) !== null && _a !== void 0 ? _a : node.links.export_original_file_url) !== null && _b !== void 0 ? _b : node.links.export_bundled_file_url) ===
|
78
|
+
undefined,
|
79
|
+
}, useNodeForRefResolving: true, refResolver: refResolver, tryItCorsProxy: tryItCorsProxy, exportProps: [types.NodeType.HttpService, types.NodeType.Model].includes(node.type)
|
80
|
+
? {
|
81
|
+
original: onExportRequest
|
82
|
+
? { onPress: () => onExportRequest('original') }
|
83
|
+
: { href: (_c = node.links.export_original_file_url) !== null && _c !== void 0 ? _c : node.links.export_url },
|
84
|
+
bundled: onExportRequest
|
85
|
+
? { onPress: () => onExportRequest('bundled') }
|
86
|
+
: { href: (_d = node.links.export_bundled_file_url) !== null && _d !== void 0 ? _d : getBundledUrl(node.links.export_url) },
|
87
|
+
}
|
88
|
+
: undefined, tryItCredentialsPolicy: tryItCredentialsPolicy, nodeHasChanged: nodeHasChanged })))));
|
89
|
+
};
|
90
|
+
const NodeLinkContext = React__namespace.createContext(undefined);
|
91
|
+
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
92
|
+
const LinkComponent = ({ children, href, title }) => {
|
93
|
+
const ctx = React__namespace.useContext(NodeLinkContext);
|
94
|
+
if (href && externalRegex.test(href)) {
|
95
|
+
return (React__namespace.createElement("a", { href: href, target: "_blank", rel: "noreferrer", title: title ? title : undefined }, children));
|
96
|
+
}
|
97
|
+
if (href && ctx) {
|
98
|
+
const [node, Link] = ctx;
|
99
|
+
const { fileUri } = getNodeUriParts(node.uri);
|
100
|
+
const { fileUri: hrefFileUri } = getNodeUriParts(href);
|
101
|
+
let resolvedUri;
|
102
|
+
if (hrefFileUri) {
|
103
|
+
resolvedUri = path.resolve(path.dirname(fileUri), href);
|
104
|
+
}
|
105
|
+
else {
|
106
|
+
resolvedUri = path.resolve(fileUri, href);
|
107
|
+
}
|
108
|
+
const [resolvedUriWithoutAnchor, hash] = resolvedUri.split('#');
|
109
|
+
const decodedUrl = decodeURIComponent(href);
|
110
|
+
const decodedResolvedUriWithoutAnchor = decodeURIComponent(resolvedUriWithoutAnchor);
|
111
|
+
const edge = node.outbound_edges.find(edge => edge.uri === decodedUrl || edge.uri === decodedResolvedUriWithoutAnchor);
|
112
|
+
if (edge) {
|
113
|
+
return React__namespace.createElement(Link, { to: `${edge.slug}${hash ? `#${hash}` : ''}` }, children);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
return React__namespace.createElement("a", { href: href }, children);
|
117
|
+
};
|
118
|
+
function getBundledUrl(url) {
|
119
|
+
if (url === undefined)
|
120
|
+
return undefined;
|
121
|
+
const bundledUrl = new URL(url);
|
122
|
+
const searchParams = new URLSearchParams(bundledUrl.search);
|
123
|
+
searchParams.append('deref', 'optimizedBundle');
|
124
|
+
bundledUrl.search = searchParams.toString();
|
125
|
+
return bundledUrl.toString();
|
126
|
+
}
|
127
|
+
const getNodeUriParts = (uri) => {
|
128
|
+
const parts = uri.split(/(\.yaml|\.yml|\.json|\.md)/);
|
129
|
+
if (parts.length === 1) {
|
130
|
+
return { fileUri: '', pointer: parts[0] || '' };
|
131
|
+
}
|
132
|
+
const fileUri = `${parts[0] || ''}${parts[1] || ''}`;
|
133
|
+
return { fileUri, pointer: parts[2] || '' };
|
134
|
+
};
|
135
|
+
|
136
|
+
/*!
|
137
|
+
* Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com
|
138
|
+
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
139
|
+
* Copyright 2022 Fonticons, Inc.
|
140
|
+
*/
|
141
|
+
var faCircleNotch = {
|
142
|
+
prefix: 'fas',
|
143
|
+
iconName: 'circle-notch',
|
144
|
+
icon: [512, 512, [], "f1ce", "M222.7 32.15C227.7 49.08 218.1 66.9 201.1 71.94C121.8 95.55 64 169.1 64 255.1C64 362 149.1 447.1 256 447.1C362 447.1 448 362 448 255.1C448 169.1 390.2 95.55 310.9 71.94C293.9 66.9 284.3 49.08 289.3 32.15C294.4 15.21 312.2 5.562 329.1 10.6C434.9 42.07 512 139.1 512 255.1C512 397.4 397.4 511.1 256 511.1C114.6 511.1 0 397.4 0 255.1C0 139.1 77.15 42.07 182.9 10.6C199.8 5.562 217.6 15.21 222.7 32.15V32.15z"]
|
145
|
+
};
|
146
|
+
var faMagnifyingGlass = {
|
147
|
+
prefix: 'fas',
|
148
|
+
iconName: 'magnifying-glass',
|
149
|
+
icon: [512, 512, [128269, "search"], "f002", "M500.3 443.7l-119.7-119.7c27.22-40.41 40.65-90.9 33.46-144.7C401.8 87.79 326.8 13.32 235.2 1.723C99.01-15.51-15.51 99.01 1.724 235.2c11.6 91.64 86.08 166.7 177.6 178.9c53.8 7.189 104.3-6.236 144.7-33.46l119.7 119.7c15.62 15.62 40.95 15.62 56.57 0C515.9 484.7 515.9 459.3 500.3 443.7zM79.1 208c0-70.58 57.42-128 128-128s128 57.42 128 128c0 70.58-57.42 128-128 128S79.1 278.6 79.1 208z"]
|
150
|
+
};
|
151
|
+
var faSearch = faMagnifyingGlass;
|
152
|
+
var faSpinner = {
|
153
|
+
prefix: 'fas',
|
154
|
+
iconName: 'spinner',
|
155
|
+
icon: [512, 512, [], "f110", "M304 48C304 74.51 282.5 96 256 96C229.5 96 208 74.51 208 48C208 21.49 229.5 0 256 0C282.5 0 304 21.49 304 48zM304 464C304 490.5 282.5 512 256 512C229.5 512 208 490.5 208 464C208 437.5 229.5 416 256 416C282.5 416 304 437.5 304 464zM0 256C0 229.5 21.49 208 48 208C74.51 208 96 229.5 96 256C96 282.5 74.51 304 48 304C21.49 304 0 282.5 0 256zM512 256C512 282.5 490.5 304 464 304C437.5 304 416 282.5 416 256C416 229.5 437.5 208 464 208C490.5 208 512 229.5 512 256zM74.98 437C56.23 418.3 56.23 387.9 74.98 369.1C93.73 350.4 124.1 350.4 142.9 369.1C161.6 387.9 161.6 418.3 142.9 437C124.1 455.8 93.73 455.8 74.98 437V437zM142.9 142.9C124.1 161.6 93.73 161.6 74.98 142.9C56.24 124.1 56.24 93.73 74.98 74.98C93.73 56.23 124.1 56.23 142.9 74.98C161.6 93.73 161.6 124.1 142.9 142.9zM369.1 369.1C387.9 350.4 418.3 350.4 437 369.1C455.8 387.9 455.8 418.3 437 437C418.3 455.8 387.9 455.8 369.1 437C350.4 418.3 350.4 387.9 369.1 369.1V369.1z"]
|
156
|
+
};
|
157
|
+
|
158
|
+
const SearchImpl = ({ isLoading, search, searchResults, isOpen, onClose, onClick, onSearch }) => {
|
159
|
+
const listBoxRef = React__namespace.useRef(null);
|
160
|
+
const onChange = React__namespace.useCallback(e => onSearch(e.currentTarget.value), [onSearch]);
|
161
|
+
const onKeyDown = React__namespace.useCallback(e => {
|
162
|
+
var _a;
|
163
|
+
if (e.key === 'ArrowDown') {
|
164
|
+
e.preventDefault();
|
165
|
+
(_a = listBoxRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
166
|
+
}
|
167
|
+
}, []);
|
168
|
+
const onSelectionChange = React__namespace.useCallback(keys => {
|
169
|
+
const selectedId = keys.values().next().value;
|
170
|
+
const selectedResult = searchResults === null || searchResults === void 0 ? void 0 : searchResults.find(searchResult => `${searchResult.id}-${searchResult.project_id}` === selectedId);
|
171
|
+
if (selectedResult) {
|
172
|
+
onClick(selectedResult);
|
173
|
+
}
|
174
|
+
}, [searchResults, onClick]);
|
175
|
+
return (React__namespace.createElement(mosaic.Modal, { renderHeader: () => (React__namespace.createElement(mosaic.Input, { appearance: "minimal", borderB: true, size: "lg", icon: React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, ml: 1, icon: isLoading ? faSpinner : faSearch, spin: isLoading }), autoFocus: true, placeholder: "Search...", value: search, onChange: onChange, onKeyDown: onKeyDown })), isOpen: !!isOpen, onClose: onClose }, searchResults && searchResults.length > 0 ? (React__namespace.createElement(mosaic.ListBox, { ref: listBoxRef, "aria-label": "Search", overflowY: "auto", h: 80, m: -5, items: searchResults, selectionMode: "single", onSelectionChange: onSelectionChange }, (searchResult) => {
|
176
|
+
var _a, _b;
|
177
|
+
return (React__namespace.createElement(mosaic.ListBoxItem, { key: `${searchResult.id}-${searchResult.project_id}`, textValue: searchResult.title },
|
178
|
+
React__namespace.createElement(mosaic.Box, { p: 3, borderB: true },
|
179
|
+
React__namespace.createElement(mosaic.Flex, { align: "center" },
|
180
|
+
React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, w: 4, icon: elementalCore.NodeTypeIconDefs[searchResult.type], style: { color: elementalCore.NodeTypeColors[searchResult.type] } }),
|
181
|
+
React__namespace.createElement(mosaic.Box, { flex: 1, fontSize: "lg", dangerouslySetInnerHTML: { __html: (_a = searchResult.highlighted.name) !== null && _a !== void 0 ? _a : '' }, fontWeight: "medium", textOverflow: "overflow-ellipsis", mx: 2 }),
|
182
|
+
React__namespace.createElement(mosaic.Box, { fontSize: "sm", color: "muted" }, searchResult.project_name)),
|
183
|
+
React__namespace.createElement(mosaic.Box, { dangerouslySetInnerHTML: { __html: (_b = searchResult.highlighted.summary) !== null && _b !== void 0 ? _b : '' }, color: "muted", fontSize: "sm", mt: 1, ml: 6 }))));
|
184
|
+
})) : (React__namespace.createElement(mosaic.Flex, { w: "full", h: 80, align: "center", justify: "center", m: -5 }, "No search results"))));
|
185
|
+
};
|
186
|
+
const Search = flow__default["default"](elementalCore.withStyles, elementalCore.withPersistenceBoundary, elementalCore.withMosaicProvider, elementalCore.withQueryClientProvider)(SearchImpl);
|
187
|
+
|
188
|
+
/*! *****************************************************************************
|
189
|
+
Copyright (c) Microsoft Corporation.
|
190
|
+
|
191
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
192
|
+
purpose with or without fee is hereby granted.
|
193
|
+
|
194
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
195
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
196
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
197
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
198
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
199
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
200
|
+
PERFORMANCE OF THIS SOFTWARE.
|
201
|
+
***************************************************************************** */
|
202
|
+
|
203
|
+
function __rest(s, e) {
|
204
|
+
var t = {};
|
205
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
206
|
+
t[p] = s[p];
|
207
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
208
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
209
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
210
|
+
t[p[i]] = s[p[i]];
|
211
|
+
}
|
212
|
+
return t;
|
213
|
+
}
|
214
|
+
|
215
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
216
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
217
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
218
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
219
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
220
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
221
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
222
|
+
});
|
223
|
+
}
|
224
|
+
|
225
|
+
const TableOfContents = (_a) => {
|
226
|
+
var { tableOfContents, activeId, Link, collapseTableOfContents = false, externalScrollbar, onLinkClick } = _a, boxProps = __rest(_a, ["tableOfContents", "activeId", "Link", "collapseTableOfContents", "externalScrollbar", "onLinkClick"]);
|
227
|
+
return (React__namespace.createElement(mosaic.Flex, Object.assign({ bg: "canvas-100" }, boxProps, { flexDirection: "col", maxH: "full" }),
|
228
|
+
React__namespace.createElement(mosaic.Flex, { flexGrow: true, flexShrink: true, overflowY: "auto" },
|
229
|
+
React__namespace.createElement(elementalCore.TableOfContents, { tree: tableOfContents.items, activeId: activeId, Link: Link, maxDepthOpenByDefault: collapseTableOfContents ? 0 : 1, externalScrollbar: externalScrollbar, onLinkClick: onLinkClick })),
|
230
|
+
tableOfContents.hide_powered_by ? null : (React__namespace.createElement(elementalCore.PoweredByLink, { source: activeId, pathname: typeof window !== 'undefined' ? window.location.pathname : '', packageType: "elements-dev-portal" }))));
|
231
|
+
};
|
232
|
+
|
233
|
+
const ROOT_CACHE_KEY = '@stoplight/elements-dev-portal/client-query';
|
234
|
+
const devPortalCacheKeys = {
|
235
|
+
all: [ROOT_CACHE_KEY],
|
236
|
+
projects: () => [ROOT_CACHE_KEY, 'projects'],
|
237
|
+
project: (projectId) => [...devPortalCacheKeys.projects(), projectId],
|
238
|
+
projectsList: () => [...devPortalCacheKeys.projects(), 'list'],
|
239
|
+
projectDetails: (projectId) => [...devPortalCacheKeys.project(projectId), 'details'],
|
240
|
+
branches: (projectId) => [...devPortalCacheKeys.project(projectId), 'branches'],
|
241
|
+
branch: (projectId, branch) => [...devPortalCacheKeys.branches(projectId), branch],
|
242
|
+
branchesList: (projectId) => [...devPortalCacheKeys.branches(projectId), 'list'],
|
243
|
+
branchDetails: (projectId, branch) => [...devPortalCacheKeys.branch(projectId, branch), 'details'],
|
244
|
+
branchTOC: (projectId, branch) => [...devPortalCacheKeys.branch(projectId, branch), 'toc'],
|
245
|
+
branchNodes: (projectId, branch) => [...devPortalCacheKeys.branch(projectId, branch), 'nodes'],
|
246
|
+
branchNode: (projectId, branch, node) => [...devPortalCacheKeys.branchNodes(projectId, branch), node],
|
247
|
+
branchNodesList: (projectId, branch) => [...devPortalCacheKeys.branchNodes(projectId, branch), 'list'],
|
248
|
+
branchNodeDetails: (projectId, branch, node) => [...devPortalCacheKeys.branchNode(projectId, branch, node), 'details'],
|
249
|
+
search: () => [...devPortalCacheKeys.all, 'search'],
|
250
|
+
searchNodes: (filters) => [
|
251
|
+
...devPortalCacheKeys.search(),
|
252
|
+
filters,
|
253
|
+
],
|
254
|
+
};
|
255
|
+
|
256
|
+
const Forbidden = () => (React__default["default"].createElement(mosaic.Flex, { align: "center", justify: "center", flexGrow: true },
|
257
|
+
React__default["default"].createElement(mosaic.VStack, { spacing: 4, align: "center" },
|
258
|
+
React__default["default"].createElement(mosaic.Heading, { size: 1 }, "Forbidden"),
|
259
|
+
React__default["default"].createElement(mosaic.Box, { as: "p" }, "You don't have permission to access this resource"))));
|
260
|
+
|
261
|
+
const Loading = () => (React__default["default"].createElement(mosaic.Flex, { justify: "center", alignItems: "center", w: "full", minH: "screen", color: "muted" },
|
262
|
+
React__default["default"].createElement(mosaic.Icon, { icon: faCircleNotch, size: "3x", spin: true })));
|
263
|
+
|
264
|
+
const NotFound = () => (React__default["default"].createElement(mosaic.Flex, { align: "center", justify: "center", flexGrow: true },
|
265
|
+
React__default["default"].createElement(mosaic.VStack, { spacing: 4, align: "center" },
|
266
|
+
React__default["default"].createElement(mosaic.Heading, { size: 1 }, "Not Found"),
|
267
|
+
React__default["default"].createElement(mosaic.Box, { as: "p" }, "Could not find what you are looking for"))));
|
268
|
+
|
269
|
+
const UpgradeToStarter = () => (React__default["default"].createElement(mosaic.Flex, { as: "a", href: "https://stoplight.io/pricing/", target: "_blank", rel: "noreferrer noopener", justify: "center", alignItems: "center", w: "full", minH: "screen", color: "muted", flexDirection: "col" },
|
270
|
+
React__default["default"].createElement(mosaic.Icon, { icon: ['fas', 'exclamation-triangle'], size: "4x" }),
|
271
|
+
React__default["default"].createElement(mosaic.Box, { pt: 3 }, "Please upgrade your Stoplight Workspace to the Starter Plan to use Elements Dev Portal in production.")));
|
272
|
+
|
273
|
+
const appVersion = '2.1.0';
|
274
|
+
|
275
|
+
class ResponseError extends Error {
|
276
|
+
constructor(message, responseCode) {
|
277
|
+
super(message);
|
278
|
+
this.name = 'ResponseError';
|
279
|
+
this.code = responseCode;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
const getNodeContent = ({ nodeSlug, projectId, branchSlug, platformUrl = 'https://stoplight.io', platformAuthToken, }) => __awaiter(void 0, void 0, void 0, function* () {
|
283
|
+
const encodedNodeSlug = encodeURIComponent(nodeSlug);
|
284
|
+
const encodedProjectId = encodeURIComponent(projectId);
|
285
|
+
const encodedBranchSlug = branchSlug ? encodeURIComponent(branchSlug) : '';
|
286
|
+
const branchQuery = encodedBranchSlug ? `?branch=${encodedBranchSlug}` : '';
|
287
|
+
const response = yield fetch(`${platformUrl}/api/v1/projects/${encodedProjectId}/nodes/${encodedNodeSlug}${branchQuery}`, {
|
288
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
289
|
+
});
|
290
|
+
const data = yield response.json();
|
291
|
+
if (!response.ok) {
|
292
|
+
if (response.status === 402) {
|
293
|
+
throw new ResponseError('Payment Required', response.status);
|
294
|
+
}
|
295
|
+
else if (response.status === 403) {
|
296
|
+
throw new ResponseError('Forbidden', response.status);
|
297
|
+
}
|
298
|
+
else {
|
299
|
+
throw new ResponseError('Something went wrong', response.status);
|
300
|
+
}
|
301
|
+
}
|
302
|
+
return data;
|
303
|
+
});
|
304
|
+
|
305
|
+
const getBranches = ({ projectId, platformUrl = 'https://stoplight.io', platformAuthToken, }) => __awaiter(void 0, void 0, void 0, function* () {
|
306
|
+
const encodedProjectId = encodeURIComponent(projectId);
|
307
|
+
const response = yield fetch(`${platformUrl}/api/v1/projects/${encodedProjectId}/branches`, {
|
308
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
309
|
+
});
|
310
|
+
const data = yield response.json();
|
311
|
+
if (!response.ok) {
|
312
|
+
throw new Error(data);
|
313
|
+
}
|
314
|
+
return data;
|
315
|
+
});
|
316
|
+
|
317
|
+
function useGetBranches({ projectId }) {
|
318
|
+
const { platformUrl, platformAuthToken } = React__namespace.useContext(PlatformContext);
|
319
|
+
return reactQuery.useQuery([...devPortalCacheKeys.branchesList(projectId), platformUrl, platformAuthToken], () => getBranches({ projectId, platformUrl, platformAuthToken }), {
|
320
|
+
enabled: projectId ? true : false,
|
321
|
+
});
|
322
|
+
}
|
323
|
+
|
324
|
+
function useGetNodeContent({ nodeSlug, projectId, branchSlug, }) {
|
325
|
+
const { platformUrl, platformAuthToken } = React__namespace.useContext(PlatformContext);
|
326
|
+
return reactQuery.useQuery([...devPortalCacheKeys.branchNodeDetails(projectId, branchSlug !== null && branchSlug !== void 0 ? branchSlug : '', nodeSlug), platformUrl, platformAuthToken], () => getNodeContent({ nodeSlug, projectId, branchSlug, platformUrl, platformAuthToken }), { enabled: nodeSlug && projectId ? true : false });
|
327
|
+
}
|
328
|
+
|
329
|
+
const getTableOfContents = ({ projectId, branchSlug, platformUrl = 'https://stoplight.io', platformAuthToken, }) => __awaiter(void 0, void 0, void 0, function* () {
|
330
|
+
const encodedProjectId = encodeURIComponent(projectId);
|
331
|
+
const encodedBranchSlug = branchSlug ? encodeURIComponent(branchSlug) : '';
|
332
|
+
const branchQuery = encodedBranchSlug ? `?branch=${encodedBranchSlug}` : '';
|
333
|
+
const response = yield fetch(`${platformUrl}/api/v1/projects/${encodedProjectId}/table-of-contents${branchQuery}`, {
|
334
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
335
|
+
});
|
336
|
+
const data = yield response.json();
|
337
|
+
if (!response.ok) {
|
338
|
+
throw new Error(data);
|
339
|
+
}
|
340
|
+
return data;
|
341
|
+
});
|
342
|
+
|
343
|
+
function useGetTableOfContents({ projectId, branchSlug }) {
|
344
|
+
const { platformUrl, platformAuthToken } = React__namespace.useContext(PlatformContext);
|
345
|
+
return reactQuery.useQuery([...devPortalCacheKeys.branchTOC(projectId, branchSlug !== null && branchSlug !== void 0 ? branchSlug : ''), platformUrl, platformAuthToken], () => getTableOfContents({ projectId, branchSlug, platformUrl, platformAuthToken }), { enabled: projectId ? true : false });
|
346
|
+
}
|
347
|
+
|
348
|
+
const StoplightProjectImpl = ({ projectId, hideTryIt, hideMocking, hideExport, collapseTableOfContents = false, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
349
|
+
const { branchSlug = '', nodeSlug = '' } = reactRouterDom.useParams();
|
350
|
+
const history = reactRouterDom.useHistory();
|
351
|
+
const { data: tableOfContents, isFetched: isTocFetched } = useGetTableOfContents({ projectId, branchSlug });
|
352
|
+
const { data: branches } = useGetBranches({ projectId });
|
353
|
+
const { data: node, isLoading: isLoadingNode, isError, error: nodeError, } = useGetNodeContent({
|
354
|
+
nodeSlug,
|
355
|
+
projectId,
|
356
|
+
branchSlug,
|
357
|
+
});
|
358
|
+
const container = React__namespace.useRef(null);
|
359
|
+
if (!nodeSlug && isTocFetched && (tableOfContents === null || tableOfContents === void 0 ? void 0 : tableOfContents.items)) {
|
360
|
+
const firstNode = elementalCore.findFirstNode(tableOfContents.items);
|
361
|
+
if (firstNode) {
|
362
|
+
return React__namespace.createElement(reactRouterDom.Redirect, { to: branchSlug ? `/branches/${branchSlug}/${firstNode.slug}` : `/${firstNode.slug}` });
|
363
|
+
}
|
364
|
+
}
|
365
|
+
let elem;
|
366
|
+
if (isLoadingNode || !isTocFetched) {
|
367
|
+
elem = React__namespace.createElement(Loading, null);
|
368
|
+
}
|
369
|
+
else if (isError) {
|
370
|
+
if (nodeError instanceof ResponseError) {
|
371
|
+
if (nodeError.code === 402) {
|
372
|
+
elem = React__namespace.createElement(UpgradeToStarter, null);
|
373
|
+
}
|
374
|
+
else if (nodeError.code === 403) {
|
375
|
+
elem = React__namespace.createElement(Forbidden, null);
|
376
|
+
}
|
377
|
+
else {
|
378
|
+
elem = React__namespace.createElement(NotFound, null);
|
379
|
+
}
|
380
|
+
}
|
381
|
+
else {
|
382
|
+
elem = React__namespace.createElement(NotFound, null);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
else if (!node) {
|
386
|
+
elem = React__namespace.createElement(NotFound, null);
|
387
|
+
}
|
388
|
+
else if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
389
|
+
return React__namespace.createElement(reactRouterDom.Redirect, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}` });
|
390
|
+
}
|
391
|
+
else {
|
392
|
+
elem = (React__namespace.createElement(NodeContent, { node: node, Link: elementalCore.ReactRouterMarkdownLink, hideTryIt: hideTryIt, hideMocking: hideMocking, hideExport: hideExport, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }));
|
393
|
+
}
|
394
|
+
const handleTocClick = () => {
|
395
|
+
if (container.current) {
|
396
|
+
container.current.scrollIntoView();
|
397
|
+
}
|
398
|
+
};
|
399
|
+
return (React__namespace.createElement(elementalCore.SidebarLayout, { ref: container, sidebar: React__namespace.createElement(React__namespace.Fragment, null,
|
400
|
+
branches && branches.length > 1 ? (React__namespace.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches, onChange: branch => history.push(branch.is_default ? `/${nodeSlug}` : `/branches/${branch.slug}/${nodeSlug}`) })) : null,
|
401
|
+
tableOfContents ? (React__namespace.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: reactRouterDom.Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) }, elem));
|
402
|
+
};
|
403
|
+
const StoplightProjectRouter = (_a) => {
|
404
|
+
var { platformUrl, basePath = '/', staticRouterPath = '', router = 'history' } = _a, props = __rest(_a, ["platformUrl", "basePath", "staticRouterPath", "router"]);
|
405
|
+
const { Router, routerProps } = elementalCore.useRouter(router, basePath, staticRouterPath);
|
406
|
+
return (React__namespace.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
407
|
+
React__namespace.createElement(elementalCore.RouterTypeContext.Provider, { value: router },
|
408
|
+
React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
409
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/branches/:branchSlug/:nodeSlug", exact: true },
|
410
|
+
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
411
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/:nodeSlug", exact: true },
|
412
|
+
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
413
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/", exact: true },
|
414
|
+
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props)))))));
|
415
|
+
};
|
416
|
+
const StoplightProject = elementalCore.withStyles(StoplightProjectRouter);
|
417
|
+
|
418
|
+
const getNodes = ({ workspaceId, branchSlug, projectIds, search, platformUrl = 'https://stoplight.io', platformAuthToken, }) => __awaiter(void 0, void 0, void 0, function* () {
|
419
|
+
const queryParams = [];
|
420
|
+
let fetchedWorkspaceId = workspaceId || '';
|
421
|
+
if (!workspaceId && (projectIds === null || projectIds === void 0 ? void 0 : projectIds.length)) {
|
422
|
+
const encodedProjectId = encodeURIComponent(projectIds[0]);
|
423
|
+
const response = yield fetch(`${platformUrl}/api/v1/projects/${encodedProjectId}`, {
|
424
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
425
|
+
});
|
426
|
+
const data = yield response.json();
|
427
|
+
fetchedWorkspaceId = data.workspace.id;
|
428
|
+
}
|
429
|
+
if (projectIds && projectIds.length) {
|
430
|
+
queryParams.push(...projectIds.map((projectId, index) => {
|
431
|
+
const encodedProjectId = encodeURIComponent(projectId);
|
432
|
+
return `project_ids[${index}]=${encodedProjectId}`;
|
433
|
+
}));
|
434
|
+
}
|
435
|
+
if (search) {
|
436
|
+
const encodedSearch = encodeURIComponent(search);
|
437
|
+
queryParams.push(`search=${encodedSearch}`);
|
438
|
+
}
|
439
|
+
if (branchSlug) {
|
440
|
+
const encodedBranchSlug = encodeURIComponent(branchSlug);
|
441
|
+
queryParams.push(`branch=${encodedBranchSlug}`);
|
442
|
+
}
|
443
|
+
const query = queryParams.length ? `?${queryParams.join('&')}` : '';
|
444
|
+
const encodedWorkspaceId = encodeURIComponent(fetchedWorkspaceId);
|
445
|
+
const response = yield fetch(`${platformUrl}/api/v1/workspaces/${encodedWorkspaceId}/nodes${query}`, {
|
446
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
447
|
+
});
|
448
|
+
const data = yield response.json();
|
449
|
+
if (!response.ok) {
|
450
|
+
throw new Error(data);
|
451
|
+
}
|
452
|
+
return data;
|
453
|
+
});
|
454
|
+
|
455
|
+
const getWorkspace = ({ projectIds, platformUrl = 'https://stoplight.io', platformAuthToken, }) => __awaiter(void 0, void 0, void 0, function* () {
|
456
|
+
const encodedProjectId = encodeURIComponent(projectIds[0]);
|
457
|
+
const response = yield fetch(`${platformUrl}/api/v1/projects/${encodedProjectId}`, {
|
458
|
+
headers: Object.assign({ 'Stoplight-Elements-Version': appVersion }, (platformAuthToken && { Authorization: `Bearer ${platformAuthToken}` })),
|
459
|
+
});
|
460
|
+
const data = yield response.json();
|
461
|
+
if (!response.ok) {
|
462
|
+
throw new Error(data);
|
463
|
+
}
|
464
|
+
return data;
|
465
|
+
});
|
466
|
+
|
467
|
+
/**
|
468
|
+
* Creates a debounced function that delays invoking `func` until after `wait`
|
469
|
+
* milliseconds have elapsed since the last time the debounced function was
|
470
|
+
* invoked, or until the next browser frame is drawn. The debounced function
|
471
|
+
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
472
|
+
* `flush` method to immediately invoke them. Provide `options` to indicate
|
473
|
+
* whether `func` should be invoked on the leading and/or trailing edge of the
|
474
|
+
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
475
|
+
* debounced function. Subsequent calls to the debounced function return the
|
476
|
+
* result of the last `func` invocation.
|
477
|
+
*
|
478
|
+
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
479
|
+
* invoked on the trailing edge of the timeout only if the debounced function
|
480
|
+
* is invoked more than once during the `wait` timeout.
|
481
|
+
*
|
482
|
+
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
483
|
+
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
484
|
+
*
|
485
|
+
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
|
486
|
+
* invocation will be deferred until the next frame is drawn (typically about
|
487
|
+
* 16ms).
|
488
|
+
*
|
489
|
+
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
490
|
+
* for details over the differences between `debounce` and `throttle`.
|
491
|
+
*
|
492
|
+
* @category Function
|
493
|
+
* @param {Function} func The function to debounce.
|
494
|
+
* @param {number} [wait=0]
|
495
|
+
* The number of milliseconds to delay; if omitted, `requestAnimationFrame` is
|
496
|
+
* used (if available, otherwise it will be setTimeout(...,0)).
|
497
|
+
* @param {Object} [options={}] The options object.
|
498
|
+
* Specify invoking on the leading edge of the timeout.
|
499
|
+
* @param {boolean} [options.leading=false]
|
500
|
+
* The maximum time `func` is allowed to be delayed before it's invoked.
|
501
|
+
* @param {number} [options.maxWait]
|
502
|
+
* Specify invoking on the trailing edge of the timeout.
|
503
|
+
* @param {boolean} [options.trailing=true]
|
504
|
+
* @returns {Function} Returns the new debounced function.
|
505
|
+
* @example
|
506
|
+
*
|
507
|
+
* // Avoid costly calculations while the window size is in flux.
|
508
|
+
* const resizeHandler = useDebouncedCallback(calculateLayout, 150);
|
509
|
+
* window.addEventListener('resize', resizeHandler)
|
510
|
+
*
|
511
|
+
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
512
|
+
* const clickHandler = useDebouncedCallback(sendMail, 300, {
|
513
|
+
* leading: true,
|
514
|
+
* trailing: false,
|
515
|
+
* })
|
516
|
+
* <button onClick={clickHandler}>click me</button>
|
517
|
+
*
|
518
|
+
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
519
|
+
* const debounced = useDebouncedCallback(batchLog, 250, { 'maxWait': 1000 })
|
520
|
+
* const source = new EventSource('/stream')
|
521
|
+
* source.addEventListener('message', debounced)
|
522
|
+
*
|
523
|
+
* // Cancel the trailing debounced invocation.
|
524
|
+
* window.addEventListener('popstate', debounced.cancel)
|
525
|
+
*
|
526
|
+
* // Check for pending invocations.
|
527
|
+
* const status = debounced.pending() ? "Pending..." : "Ready"
|
528
|
+
*/
|
529
|
+
function useDebouncedCallback(func, wait, options) {
|
530
|
+
var _this = this;
|
531
|
+
var lastCallTime = React.useRef(null);
|
532
|
+
var lastInvokeTime = React.useRef(0);
|
533
|
+
var timerId = React.useRef(null);
|
534
|
+
var lastArgs = React.useRef([]);
|
535
|
+
var lastThis = React.useRef();
|
536
|
+
var result = React.useRef();
|
537
|
+
var funcRef = React.useRef(func);
|
538
|
+
var mounted = React.useRef(true);
|
539
|
+
funcRef.current = func;
|
540
|
+
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
|
541
|
+
var useRAF = !wait && wait !== 0 && typeof window !== 'undefined';
|
542
|
+
if (typeof func !== 'function') {
|
543
|
+
throw new TypeError('Expected a function');
|
544
|
+
}
|
545
|
+
wait = +wait || 0;
|
546
|
+
options = options || {};
|
547
|
+
var leading = !!options.leading;
|
548
|
+
var trailing = 'trailing' in options ? !!options.trailing : true; // `true` by default
|
549
|
+
var maxing = 'maxWait' in options;
|
550
|
+
var maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : null;
|
551
|
+
React.useEffect(function () {
|
552
|
+
mounted.current = true;
|
553
|
+
return function () {
|
554
|
+
mounted.current = false;
|
555
|
+
};
|
556
|
+
}, []);
|
557
|
+
// You may have a question, why we have so many code under the useMemo definition.
|
558
|
+
//
|
559
|
+
// This was made as we want to escape from useCallback hell and
|
560
|
+
// not to initialize a number of functions each time useDebouncedCallback is called.
|
561
|
+
//
|
562
|
+
// It means that we have less garbage for our GC calls which improves performance.
|
563
|
+
// Also, it makes this library smaller.
|
564
|
+
//
|
565
|
+
// And the last reason, that the code without lots of useCallback with deps is easier to read.
|
566
|
+
// You have only one place for that.
|
567
|
+
var debounced = React.useMemo(function () {
|
568
|
+
var invokeFunc = function (time) {
|
569
|
+
var args = lastArgs.current;
|
570
|
+
var thisArg = lastThis.current;
|
571
|
+
lastArgs.current = lastThis.current = null;
|
572
|
+
lastInvokeTime.current = time;
|
573
|
+
return (result.current = funcRef.current.apply(thisArg, args));
|
574
|
+
};
|
575
|
+
var startTimer = function (pendingFunc, wait) {
|
576
|
+
if (useRAF)
|
577
|
+
cancelAnimationFrame(timerId.current);
|
578
|
+
timerId.current = useRAF ? requestAnimationFrame(pendingFunc) : setTimeout(pendingFunc, wait);
|
579
|
+
};
|
580
|
+
var shouldInvoke = function (time) {
|
581
|
+
if (!mounted.current)
|
582
|
+
return false;
|
583
|
+
var timeSinceLastCall = time - lastCallTime.current;
|
584
|
+
var timeSinceLastInvoke = time - lastInvokeTime.current;
|
585
|
+
// Either this is the first call, activity has stopped and we're at the
|
586
|
+
// trailing edge, the system time has gone backwards and we're treating
|
587
|
+
// it as the trailing edge, or we've hit the `maxWait` limit.
|
588
|
+
return (!lastCallTime.current ||
|
589
|
+
timeSinceLastCall >= wait ||
|
590
|
+
timeSinceLastCall < 0 ||
|
591
|
+
(maxing && timeSinceLastInvoke >= maxWait));
|
592
|
+
};
|
593
|
+
var trailingEdge = function (time) {
|
594
|
+
timerId.current = null;
|
595
|
+
// Only invoke if we have `lastArgs` which means `func` has been
|
596
|
+
// debounced at least once.
|
597
|
+
if (trailing && lastArgs.current) {
|
598
|
+
return invokeFunc(time);
|
599
|
+
}
|
600
|
+
lastArgs.current = lastThis.current = null;
|
601
|
+
return result.current;
|
602
|
+
};
|
603
|
+
var timerExpired = function () {
|
604
|
+
var time = Date.now();
|
605
|
+
if (shouldInvoke(time)) {
|
606
|
+
return trailingEdge(time);
|
607
|
+
}
|
608
|
+
// https://github.com/xnimorz/use-debounce/issues/97
|
609
|
+
if (!mounted.current) {
|
610
|
+
return;
|
611
|
+
}
|
612
|
+
// Remaining wait calculation
|
613
|
+
var timeSinceLastCall = time - lastCallTime.current;
|
614
|
+
var timeSinceLastInvoke = time - lastInvokeTime.current;
|
615
|
+
var timeWaiting = wait - timeSinceLastCall;
|
616
|
+
var remainingWait = maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
|
617
|
+
// Restart the timer
|
618
|
+
startTimer(timerExpired, remainingWait);
|
619
|
+
};
|
620
|
+
var func = function () {
|
621
|
+
var args = [];
|
622
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
623
|
+
args[_i] = arguments[_i];
|
624
|
+
}
|
625
|
+
var time = Date.now();
|
626
|
+
var isInvoking = shouldInvoke(time);
|
627
|
+
lastArgs.current = args;
|
628
|
+
lastThis.current = _this;
|
629
|
+
lastCallTime.current = time;
|
630
|
+
if (isInvoking) {
|
631
|
+
if (!timerId.current && mounted.current) {
|
632
|
+
// Reset any `maxWait` timer.
|
633
|
+
lastInvokeTime.current = lastCallTime.current;
|
634
|
+
// Start the timer for the trailing edge.
|
635
|
+
startTimer(timerExpired, wait);
|
636
|
+
// Invoke the leading edge.
|
637
|
+
return leading ? invokeFunc(lastCallTime.current) : result.current;
|
638
|
+
}
|
639
|
+
if (maxing) {
|
640
|
+
// Handle invocations in a tight loop.
|
641
|
+
startTimer(timerExpired, wait);
|
642
|
+
return invokeFunc(lastCallTime.current);
|
643
|
+
}
|
644
|
+
}
|
645
|
+
if (!timerId.current) {
|
646
|
+
startTimer(timerExpired, wait);
|
647
|
+
}
|
648
|
+
return result.current;
|
649
|
+
};
|
650
|
+
func.cancel = function () {
|
651
|
+
if (timerId.current) {
|
652
|
+
useRAF ? cancelAnimationFrame(timerId.current) : clearTimeout(timerId.current);
|
653
|
+
}
|
654
|
+
lastInvokeTime.current = 0;
|
655
|
+
lastArgs.current = lastCallTime.current = lastThis.current = timerId.current = null;
|
656
|
+
};
|
657
|
+
func.isPending = function () {
|
658
|
+
return !!timerId.current;
|
659
|
+
};
|
660
|
+
func.flush = function () {
|
661
|
+
return !timerId.current ? result.current : trailingEdge(Date.now());
|
662
|
+
};
|
663
|
+
return func;
|
664
|
+
}, [leading, maxing, wait, maxWait, trailing, useRAF]);
|
665
|
+
return debounced;
|
666
|
+
}
|
667
|
+
|
668
|
+
function valueEquality(left, right) {
|
669
|
+
return left === right;
|
670
|
+
}
|
671
|
+
function adjustFunctionValueOfSetState(value) {
|
672
|
+
return typeof value === 'function' ? function () { return value; } : value;
|
673
|
+
}
|
674
|
+
function useStateIgnoreCallback(initialState) {
|
675
|
+
var _a = React.useState(adjustFunctionValueOfSetState(initialState)), state = _a[0], setState = _a[1];
|
676
|
+
var setStateIgnoreCallback = React.useCallback(function (value) { return setState(adjustFunctionValueOfSetState(value)); }, []);
|
677
|
+
return [state, setStateIgnoreCallback];
|
678
|
+
}
|
679
|
+
function useDebounce(value, delay, options) {
|
680
|
+
var eq = (options && options.equalityFn) || valueEquality;
|
681
|
+
var _a = useStateIgnoreCallback(value), state = _a[0], dispatch = _a[1];
|
682
|
+
var debounced = useDebouncedCallback(React.useCallback(function (value) { return dispatch(value); }, [dispatch]), delay, options);
|
683
|
+
var previousValue = React.useRef(value);
|
684
|
+
React.useEffect(function () {
|
685
|
+
// We need to use this condition otherwise we will run debounce timer for the first render (including maxWait option)
|
686
|
+
if (!eq(previousValue.current, value)) {
|
687
|
+
debounced(value);
|
688
|
+
previousValue.current = value;
|
689
|
+
}
|
690
|
+
}, [value, debounced, eq]);
|
691
|
+
return [state, { cancel: debounced.cancel, isPending: debounced.isPending, flush: debounced.flush }];
|
692
|
+
}
|
693
|
+
|
694
|
+
function useGetNodes({ search, workspaceId, projectIds, branch, pause, }) {
|
695
|
+
const { platformUrl, platformAuthToken } = React__namespace.useContext(PlatformContext);
|
696
|
+
const [debounceSearch] = useDebounce(search, 500);
|
697
|
+
return reactQuery.useQuery([
|
698
|
+
...devPortalCacheKeys.searchNodes({ projectIds, branchSlug: branch, workspaceId, search: debounceSearch }),
|
699
|
+
platformUrl,
|
700
|
+
platformAuthToken,
|
701
|
+
], () => getNodes({ workspaceId, projectIds, branchSlug: branch, search: debounceSearch, platformUrl, platformAuthToken }), { enabled: !pause, keepPreviousData: true });
|
702
|
+
}
|
703
|
+
|
704
|
+
function useGetWorkspace({ projectIds }) {
|
705
|
+
const { platformUrl, platformAuthToken } = React__namespace.useContext(PlatformContext);
|
706
|
+
return reactQuery.useQuery([...devPortalCacheKeys.searchNodes({ projectIds }), platformUrl, platformAuthToken], () => getWorkspace({ projectIds, platformUrl, platformAuthToken }));
|
707
|
+
}
|
708
|
+
|
709
|
+
exports.BranchSelector = BranchSelector;
|
710
|
+
exports.DevPortalProvider = DevPortalProvider;
|
711
|
+
exports.NodeContent = NodeContent;
|
712
|
+
exports.ResponseError = ResponseError;
|
713
|
+
exports.Search = Search;
|
714
|
+
exports.StoplightProject = StoplightProject;
|
715
|
+
exports.TableOfContents = TableOfContents;
|
716
|
+
exports.devPortalCacheKeys = devPortalCacheKeys;
|
717
|
+
exports.getBranches = getBranches;
|
718
|
+
exports.getNodeContent = getNodeContent;
|
719
|
+
exports.getNodes = getNodes;
|
720
|
+
exports.getTableOfContents = getTableOfContents;
|
721
|
+
exports.getWorkspace = getWorkspace;
|
722
|
+
exports.useGetBranches = useGetBranches;
|
723
|
+
exports.useGetNodeContent = useGetNodeContent;
|
724
|
+
exports.useGetNodes = useGetNodes;
|
725
|
+
exports.useGetTableOfContents = useGetTableOfContents;
|
726
|
+
exports.useGetWorkspace = useGetWorkspace;
|