openapi-explorer 2.1.656 → 2.1.658
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.
- package/dist/browser/openapi-explorer.min.js +2 -2
- package/dist/es/components/api-request.js +58 -140
- package/dist/es/components/api-response.js +9 -34
- package/dist/es/components/json-tree.js +4 -18
- package/dist/es/components/request-form-table.js +13 -36
- package/dist/es/components/schema-table.js +28 -42
- package/dist/es/components/schema-tree.js +31 -61
- package/dist/es/components/syntax-highlighter.js +7 -26
- package/dist/es/components/tag-input.js +2 -14
- package/dist/es/openapi-explorer-oauth-handler.js +0 -2
- package/dist/es/openapi-explorer.js +62 -174
- package/dist/es/react.js +4 -4
- package/dist/es/styles/input-styles.js +1 -1
- package/dist/es/styles/schema-styles.js +1 -1
- package/dist/es/templates/advance-search-template.js +1 -5
- package/dist/es/templates/callback-template.js +2 -2
- package/dist/es/templates/code-samples-template.js +1 -3
- package/dist/es/templates/components-template.js +41 -4
- package/dist/es/templates/endpoint-template.js +6 -17
- package/dist/es/templates/expanded-endpoint-template.js +4 -7
- package/dist/es/templates/focused-endpoint-template.js +0 -10
- package/dist/es/templates/mainBodyTemplate.js +3 -2
- package/dist/es/templates/navbar-template.js +9 -12
- package/dist/es/templates/overview-template.js +1 -1
- package/dist/es/templates/security-scheme-template.js +12 -73
- package/dist/es/templates/server-template.js +1 -8
- package/dist/es/utils/color-utils.js +2 -21
- package/dist/es/utils/common-utils.js +3 -20
- package/dist/es/utils/schema-utils.js +35 -132
- package/dist/es/utils/spec-parser.js +35 -120
- package/dist/es/utils/theme.js +3 -6
- package/dist/es/utils/xml/xml.js +1 -40
- package/dist/lib/components/api-request.js +58 -157
- package/dist/lib/components/api-response.js +9 -54
- package/dist/lib/components/json-tree.js +4 -27
- package/dist/lib/components/request-form-table.js +14 -42
- package/dist/lib/components/schema-table.js +28 -52
- package/dist/lib/components/schema-tree.js +31 -72
- package/dist/lib/components/syntax-highlighter.js +6 -49
- package/dist/lib/components/tag-input.js +2 -18
- package/dist/lib/languages/en.js +2 -3
- package/dist/lib/languages/fr.js +2 -3
- package/dist/lib/languages/index.js +0 -6
- package/dist/lib/openapi-explorer-oauth-handler.js +0 -6
- package/dist/lib/openapi-explorer.js +61 -197
- package/dist/lib/react.js +4 -5
- package/dist/lib/styles/advanced-search-styles.js +1 -5
- package/dist/lib/styles/api-request-styles.js +1 -5
- package/dist/lib/styles/border-styles.js +1 -5
- package/dist/lib/styles/endpoint-styles.js +1 -5
- package/dist/lib/styles/flex-styles.js +1 -5
- package/dist/lib/styles/font-styles.js +1 -5
- package/dist/lib/styles/info-styles.js +1 -5
- package/dist/lib/styles/input-styles.js +1 -5
- package/dist/lib/styles/key-frame-styles.js +1 -5
- package/dist/lib/styles/nav-styles.js +1 -5
- package/dist/lib/styles/prism-styles.js +1 -5
- package/dist/lib/styles/schema-styles.js +1 -5
- package/dist/lib/styles/tab-styles.js +1 -5
- package/dist/lib/styles/table-styles.js +1 -5
- package/dist/lib/styles/tag-input-styles.js +1 -5
- package/dist/lib/templates/advance-search-template.js +0 -6
- package/dist/lib/templates/callback-template.js +1 -3
- package/dist/lib/templates/code-samples-template.js +0 -4
- package/dist/lib/templates/components-template.js +43 -9
- package/dist/lib/templates/endpoint-template.js +6 -29
- package/dist/lib/templates/expanded-endpoint-template.js +3 -17
- package/dist/lib/templates/focused-endpoint-template.js +0 -19
- package/dist/lib/templates/mainBodyTemplate.js +2 -13
- package/dist/lib/templates/navbar-template.js +9 -20
- package/dist/lib/templates/overview-template.js +0 -5
- package/dist/lib/templates/security-scheme-template.js +12 -79
- package/dist/lib/templates/server-template.js +1 -12
- package/dist/lib/utils/color-utils.js +4 -25
- package/dist/lib/utils/common-utils.js +3 -33
- package/dist/lib/utils/schema-utils.js +33 -141
- package/dist/lib/utils/spec-parser.js +35 -128
- package/dist/lib/utils/theme.js +3 -16
- package/dist/lib/utils/xml/xml.js +1 -42
- package/package.json +2 -2
@@ -3,39 +3,31 @@ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
3
3
|
import { marked } from 'marked';
|
4
4
|
import base64url from 'base64url';
|
5
5
|
import { getI18nText } from '../languages/index.js';
|
6
|
-
|
7
6
|
function onApiKeyChange(apiKeyId, e) {
|
8
7
|
e.preventDefault();
|
9
8
|
let apiKeyValue = '';
|
10
9
|
const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
|
11
|
-
|
12
10
|
if (!securityObj) {
|
13
11
|
return;
|
14
12
|
}
|
15
|
-
|
16
13
|
const trEl = e.target.closest('tr');
|
17
|
-
|
18
14
|
if (securityObj.type && securityObj.type === 'http' && securityObj.scheme && securityObj.scheme.toLowerCase() === 'basic') {
|
19
15
|
const userVal = trEl.querySelector('.api-key-user').value.trim();
|
20
16
|
const passwordVal = trEl.querySelector('.api-key-password').value.trim();
|
21
|
-
|
22
17
|
if (passwordVal) {
|
23
18
|
apiKeyValue = `Basic ${btoa(`${userVal}:${passwordVal}`)}`;
|
24
19
|
}
|
25
20
|
} else {
|
26
21
|
apiKeyValue = trEl.querySelector('.api-key-input').value.trim();
|
27
|
-
|
28
22
|
if (apiKeyValue) {
|
29
23
|
if (securityObj.scheme && securityObj.scheme.toLowerCase() === 'bearer') {
|
30
24
|
apiKeyValue = `Bearer ${apiKeyValue.replace(/^Bearer\s+/i, '')}`;
|
31
25
|
}
|
32
26
|
}
|
33
27
|
}
|
34
|
-
|
35
28
|
securityObj.finalKeyValue = apiKeyValue;
|
36
29
|
this.requestUpdate();
|
37
30
|
}
|
38
|
-
|
39
31
|
function onClearAllApiKeys() {
|
40
32
|
this.resolvedSpec.securitySchemes.forEach(v => {
|
41
33
|
v.user = '';
|
@@ -44,17 +36,17 @@ function onClearAllApiKeys() {
|
|
44
36
|
v.finalKeyValue = '';
|
45
37
|
});
|
46
38
|
this.requestUpdate();
|
47
|
-
}
|
48
|
-
|
39
|
+
}
|
49
40
|
|
41
|
+
// Updates the OAuth Access Token (API key), so it reflects in UI and gets used in TRY calls
|
50
42
|
function updateOAuthKey(apiKeyId, tokenType = 'Bearer', accessToken) {
|
51
43
|
const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
|
52
44
|
const tokenPrefix = tokenType && tokenType.toLowerCase() === 'bearer' ? 'Bearer' : tokenType;
|
53
45
|
securityObj.finalKeyValue = `${tokenPrefix}${tokenPrefix ? ' ' : ''}${accessToken}`;
|
54
46
|
this.requestUpdate();
|
55
|
-
}
|
56
|
-
|
47
|
+
}
|
57
48
|
|
49
|
+
// Gets Access-Token in exchange of Authorization Code
|
58
50
|
async function fetchAccessToken(tokenUrl, suggestedClientId, clientSecret, redirectUrl, grantType, authCode, sendClientSecretIn = 'header', apiKeyId, authFlowDivEl, scopes = null) {
|
59
51
|
const respDisplayEl = authFlowDivEl ? authFlowDivEl.querySelector('.oauth-resp-display') : undefined;
|
60
52
|
const {
|
@@ -66,33 +58,26 @@ async function fetchAccessToken(tokenUrl, suggestedClientId, clientSecret, redir
|
|
66
58
|
const urlFormParams = new URLSearchParams();
|
67
59
|
const headers = new Headers();
|
68
60
|
urlFormParams.append('grant_type', grantType);
|
69
|
-
|
70
61
|
if (redirectUrl) {
|
71
62
|
urlFormParams.append('redirect_uri', redirectUrl);
|
72
63
|
}
|
73
|
-
|
74
64
|
if (authCode) {
|
75
65
|
urlFormParams.append('code', authCode);
|
76
66
|
}
|
77
|
-
|
78
67
|
if (sendClientSecretIn === 'header') {
|
79
68
|
headers.set('Authorization', `Basic ${btoa(`${clientId}:${clientSecret}`)}`);
|
80
69
|
} else {
|
81
70
|
urlFormParams.append('client_id', clientId);
|
82
|
-
|
83
71
|
if (clientSecret) {
|
84
72
|
urlFormParams.append('client_secret', clientSecret);
|
85
73
|
}
|
86
74
|
}
|
87
|
-
|
88
75
|
if (scopes) {
|
89
76
|
urlFormParams.append('scope', scopes);
|
90
77
|
}
|
91
|
-
|
92
78
|
if (codeVerifier) {
|
93
79
|
urlFormParams.append('code_verifier', codeVerifier);
|
94
80
|
}
|
95
|
-
|
96
81
|
try {
|
97
82
|
const resp = await fetch(tokenUrl, {
|
98
83
|
method: 'POST',
|
@@ -100,18 +85,14 @@ async function fetchAccessToken(tokenUrl, suggestedClientId, clientSecret, redir
|
|
100
85
|
body: urlFormParams
|
101
86
|
});
|
102
87
|
const tokenResp = await resp.json();
|
103
|
-
|
104
88
|
if (!resp.ok) {
|
105
89
|
if (respDisplayEl) {
|
106
90
|
respDisplayEl.innerHTML = `<span style="color:var(--red)">${tokenResp.error_description || tokenResp.error_description || 'Unable to get access token'}</span>`;
|
107
91
|
}
|
108
|
-
|
109
92
|
return;
|
110
93
|
}
|
111
|
-
|
112
94
|
if (tokenResp.token_type && tokenResp.access_token) {
|
113
95
|
updateOAuthKey.call(this, apiKeyId, tokenResp.token_type, tokenResp.access_token);
|
114
|
-
|
115
96
|
if (respDisplayEl) {
|
116
97
|
respDisplayEl.innerHTML = '<span style="color:var(--green)">Access Token Received</span>';
|
117
98
|
}
|
@@ -122,24 +103,20 @@ async function fetchAccessToken(tokenUrl, suggestedClientId, clientSecret, redir
|
|
122
103
|
}
|
123
104
|
}
|
124
105
|
}
|
125
|
-
|
126
106
|
function getCookieValue(keyId) {
|
127
107
|
const foundCookie = (document.cookie || '').split(';').find(c => c.split('=')[0] === keyId);
|
128
108
|
return foundCookie && foundCookie.split('=')[1] || '';
|
129
109
|
}
|
130
|
-
|
131
110
|
function toObject(urlSearchParams) {
|
132
111
|
const result = {};
|
133
112
|
const entries = urlSearchParams && urlSearchParams.entries() || [];
|
134
|
-
|
135
113
|
for (const [key, value] of entries) {
|
136
114
|
result[key] = value;
|
137
115
|
}
|
138
|
-
|
139
116
|
return result;
|
140
|
-
}
|
141
|
-
|
117
|
+
}
|
142
118
|
|
119
|
+
// Gets invoked when it receives the Authorization Code from the other window via message-event
|
143
120
|
export async function checkForAuthToken(redirectToApiLocation) {
|
144
121
|
const parameters = toObject(new URLSearchParams(window.location.search));
|
145
122
|
const hashQuery = toObject(new URLSearchParams(window.location.hash.slice(1)));
|
@@ -158,15 +135,12 @@ export async function checkForAuthToken(redirectToApiLocation) {
|
|
158
135
|
newUrl.searchParams.delete('hd');
|
159
136
|
newUrl.searchParams.delete('authuser');
|
160
137
|
newUrl.searchParams.delete('redirect_auth');
|
161
|
-
|
162
138
|
if (!parameters.state) {
|
163
139
|
return;
|
164
140
|
}
|
165
|
-
|
166
141
|
const sanitizedUrlWithHash = newUrl.toString().replace(/#((code|state|access_token|id_token|authuser|expires_in|hd|prompt|scope|token_type)=[^&]+&?)*$/ig, '');
|
167
142
|
history.replaceState({}, undefined, sanitizedUrlWithHash);
|
168
143
|
let parsedState;
|
169
|
-
|
170
144
|
try {
|
171
145
|
// If somehow the state contains a question mark, just remove it, a ? is not a valid here
|
172
146
|
parsedState = JSON.parse(base64url.decode(parameters.state.replace(/\?.*$/, '')));
|
@@ -175,13 +149,11 @@ export async function checkForAuthToken(redirectToApiLocation) {
|
|
175
149
|
console.error('The state parameter in the OAuth response is invalid', error, parameters.state);
|
176
150
|
return;
|
177
151
|
}
|
178
|
-
|
179
152
|
const {
|
180
153
|
apiKeyId,
|
181
154
|
flowId,
|
182
155
|
url
|
183
156
|
} = parsedState;
|
184
|
-
|
185
157
|
if (redirectToApiLocation && url && !parameters.redirect_auth) {
|
186
158
|
const apiExplorerLocation = new URL(url);
|
187
159
|
Object.keys(parameters).forEach(key => apiExplorerLocation.searchParams.append(key, parameters[key]));
|
@@ -189,19 +161,15 @@ export async function checkForAuthToken(redirectToApiLocation) {
|
|
189
161
|
window.location.replace(apiExplorerLocation.toString());
|
190
162
|
return;
|
191
163
|
}
|
192
|
-
|
193
164
|
if (parameters.code) {
|
194
165
|
var _this$selectedServer;
|
195
|
-
|
196
166
|
const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
|
197
167
|
const tokenUrl = securityObj && securityObj.flows[flowId] && new URL(securityObj.flows[flowId].tokenUrl || '', (_this$selectedServer = this.selectedServer) === null || _this$selectedServer === void 0 ? void 0 : _this$selectedServer.computedUrl);
|
198
168
|
await fetchAccessToken.call(this, tokenUrl, securityObj.clientId, securityObj.clientSecret, securityObj.redirectUri || window.location.href, 'authorization_code', parameters.code, null, apiKeyId);
|
199
169
|
return;
|
200
170
|
}
|
201
|
-
|
202
171
|
updateOAuthKey.call(this, apiKeyId, parameters.token_type, parameters.access_token);
|
203
172
|
}
|
204
|
-
|
205
173
|
async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
|
206
174
|
const authFlowDivEl = e.target.closest('.oauth-flow');
|
207
175
|
const clientId = authFlowDivEl.querySelector('#oauth-client-id') ? authFlowDivEl.querySelector('#oauth-client-id').value.trim() : '';
|
@@ -210,18 +178,17 @@ async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
|
|
210
178
|
const checkedScopeEls = [...authFlowDivEl.querySelectorAll('input[type="checkbox"]:checked')];
|
211
179
|
const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
|
212
180
|
let grantType = '';
|
213
|
-
let responseType = '';
|
181
|
+
let responseType = '';
|
214
182
|
|
183
|
+
// clear previous error messages
|
215
184
|
const errEls = [...authFlowDivEl.parentNode.querySelectorAll('.oauth-resp-display')];
|
216
185
|
errEls.forEach(v => {
|
217
186
|
v.innerHTML = '';
|
218
187
|
});
|
219
|
-
|
220
188
|
if (flowType === 'authorizationCode' || flowType === 'implicit') {
|
221
189
|
const authUrlObj = new URL(authUrl);
|
222
190
|
const authCodeParams = new URLSearchParams(authUrlObj.search);
|
223
191
|
let codeVerifier;
|
224
|
-
|
225
192
|
if (flowType === 'authorizationCode') {
|
226
193
|
const randomBytes = new Uint32Array(12);
|
227
194
|
(window.crypto || window.msCrypto).getRandomValues(randomBytes);
|
@@ -236,7 +203,6 @@ async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
|
|
236
203
|
} else if (flowType === 'implicit') {
|
237
204
|
responseType = 'token';
|
238
205
|
}
|
239
|
-
|
240
206
|
localStorage.setItem('openapi-explorer-oauth', JSON.stringify({
|
241
207
|
codeVerifier,
|
242
208
|
clientId,
|
@@ -244,11 +210,9 @@ async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
|
|
244
210
|
flowId: flowType
|
245
211
|
}));
|
246
212
|
const selectedScopes = checkedScopeEls.map(v => v.value).join(' ');
|
247
|
-
|
248
213
|
if (selectedScopes) {
|
249
214
|
authCodeParams.set('scope', selectedScopes);
|
250
215
|
}
|
251
|
-
|
252
216
|
authCodeParams.set('client_id', clientId);
|
253
217
|
authCodeParams.set('redirect_uri', securityObj.redirectUri || window.location.href);
|
254
218
|
authCodeParams.set('response_type', responseType);
|
@@ -265,25 +229,20 @@ async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
|
|
265
229
|
fetchAccessToken.call(this, tokenUrl, clientId, clientSecret, '', grantType, '', sendClientSecretIn, apiKeyId, authFlowDivEl, selectedScopes);
|
266
230
|
}
|
267
231
|
}
|
268
|
-
/* eslint-disable indent */
|
269
232
|
|
233
|
+
/* eslint-disable indent */
|
270
234
|
|
271
235
|
function oAuthFlowTemplate(flowName, securityObj, authFlow) {
|
272
236
|
var _this$selectedServer3, _this$selectedServer4, _this$selectedServer5;
|
273
|
-
|
274
237
|
const apiKeyId = securityObj.apiKeyId;
|
275
|
-
|
276
238
|
const getFullUrl = url => {
|
277
239
|
var _this$selectedServer2;
|
278
|
-
|
279
240
|
return url ? new URL(url, (_this$selectedServer2 = this.selectedServer) === null || _this$selectedServer2 === void 0 ? void 0 : _this$selectedServer2.computedUrl) : undefined;
|
280
241
|
};
|
281
|
-
|
282
242
|
const authorizationUrl = getFullUrl(authFlow.authorizationUrl, (_this$selectedServer3 = this.selectedServer) === null || _this$selectedServer3 === void 0 ? void 0 : _this$selectedServer3.computedUrl);
|
283
243
|
const tokenUrl = getFullUrl(authFlow.tokenUrl, (_this$selectedServer4 = this.selectedServer) === null || _this$selectedServer4 === void 0 ? void 0 : _this$selectedServer4.computedUrl);
|
284
244
|
const refreshUrl = getFullUrl(authFlow.refreshUrl, (_this$selectedServer5 = this.selectedServer) === null || _this$selectedServer5 === void 0 ? void 0 : _this$selectedServer5.computedUrl);
|
285
245
|
let flowNameDisplay;
|
286
|
-
|
287
246
|
if (flowName === 'authorizationCode') {
|
288
247
|
flowNameDisplay = 'Authorization Code Flow';
|
289
248
|
} else if (flowName === 'clientCredentials') {
|
@@ -293,20 +252,16 @@ function oAuthFlowTemplate(flowName, securityObj, authFlow) {
|
|
293
252
|
} else {
|
294
253
|
flowNameDisplay = flowName;
|
295
254
|
}
|
296
|
-
|
297
255
|
return html` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? html`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? html`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? html`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` ${authFlow.scopes ? html` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => html` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <div> <input id="oauth-client-id" type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-input"> ${flowName === 'clientCredentials' ? html` <input id="oauth-client-secret" type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-input"> <select id="oauth-send-client-secret-in" aria-label="oauth client secret location" style="margin-right:5px" class="oauth-client-input"> <option value="header" selected="selected"> Authorization Header </option> <option value="request-body"> Request Body </option> </select> ` : html`<div style="width:5px"></div>`} </div> ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` <div class="oauth-client-input" style="margin-left:1rem"> <button class="m-btn thin-border" part="btn btn-outline" @click="${e => {
|
298
256
|
onInvokeOAuthFlow.call(this, apiKeyId, flowName, authorizationUrl, tokenUrl, e);
|
299
257
|
}}">GET TOKEN</button> </div>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `;
|
300
258
|
}
|
301
|
-
|
302
259
|
function renderSecurityScheme(v) {
|
303
260
|
if (!v.type) {
|
304
261
|
return '';
|
305
262
|
}
|
306
|
-
|
307
263
|
if (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') {
|
308
264
|
var _v$bearerFormat, _v$bearerFormat2;
|
309
|
-
|
310
265
|
return html` <div style="padding-top:1rem"> ${v.type.toLowerCase() === 'apikey' ? html`Send <code>${v.name || 'API key'}</code> in <code>${v.in || 'the request'}</code> with the given value:` : html`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and then the ${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token String'}.`} </div> <form style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> ${v.in === 'cookie' ? html` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong> are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : !v.finalKeyValue ? html` <input type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
|
311
266
|
onApiKeyChange.call(this, v.apiKeyId, e);
|
312
267
|
}}"> ${getI18nText('authentication.set')} </button>` : html`<span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
|
@@ -314,7 +269,6 @@ function renderSecurityScheme(v) {
|
|
314
269
|
this.requestUpdate();
|
315
270
|
}}">REMOVE</button>`} </form>`;
|
316
271
|
}
|
317
|
-
|
318
272
|
if (v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic') {
|
319
273
|
if (v.finalKeyValue) {
|
320
274
|
return html` <div style="padding-top:1rem">${getI18nText('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
|
@@ -322,61 +276,46 @@ function renderSecurityScheme(v) {
|
|
322
276
|
this.requestUpdate();
|
323
277
|
}}">REMOVE</button> </div>`;
|
324
278
|
}
|
325
|
-
|
326
279
|
return html` <div style="padding-top:1rem">${getI18nText('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${getI18nText('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input class="api-key-password fs-exclude" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${getI18nText('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
|
327
280
|
onApiKeyChange.call(this, v.apiKeyId, e);
|
328
281
|
}}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : getI18nText('authentication.set')} </button> </form> </div>`;
|
329
282
|
}
|
330
|
-
|
331
283
|
if (v.type.toLowerCase() === 'oauth2' && Object.keys(v.flows).length) {
|
332
284
|
return html`${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))}`;
|
333
285
|
}
|
334
|
-
|
335
286
|
return '';
|
336
287
|
}
|
337
|
-
|
338
288
|
export default function securitySchemeTemplate() {
|
339
289
|
const schemes = this.resolvedSpec && this.resolvedSpec.securitySchemes;
|
340
|
-
|
341
290
|
if (!schemes) {
|
342
291
|
return undefined;
|
343
292
|
}
|
344
|
-
|
345
293
|
const providedApiKeys = schemes.filter(v => v.finalKeyValue);
|
346
294
|
return html` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font">${getI18nText('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:40px"> ${providedApiKeys.length > 0 ? html` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => {
|
347
295
|
onClearAllApiKeys.call(this);
|
348
296
|
}}">CLEAR ALL API KEYS</button>` : html`<div class="red-text">${getI18nText('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? html` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => html` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px;display:flex;flex-direction:column;justify-content:center;align-items:center"> <div style="display:flex;justify-content:center"> <span style="font-weight:700">${getTypeDisplayHeader(v)}</span> </div> </div> ${v.description ? html` <div class="m-markdown"> ${unsafeHTML(marked(v.description || ''))} </div>` : ''} </td> <td colspan="3">${renderSecurityScheme.call(this, v)}</td> </tr>`)} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `;
|
349
297
|
}
|
350
|
-
|
351
298
|
function getOauthScopeTemplate(rawScopes) {
|
352
299
|
const scopes = Array.isArray(rawScopes) ? rawScopes.map(s => s === null || s === void 0 ? void 0 : s.trim()).filter(s => s) : [];
|
353
|
-
|
354
300
|
if (!scopes.length) {
|
355
301
|
return '';
|
356
302
|
}
|
357
|
-
|
358
303
|
return html` <div> <b>Required scopes:</b> <br> <div style="margin-left:8px"> ${scopes.map(scope => html`<span>${scope}</span> `)} </div> </div>`;
|
359
304
|
}
|
360
|
-
|
361
305
|
function getTypeDisplayHeader(securityScheme) {
|
362
306
|
if (securityScheme.type === 'apiKey') {
|
363
307
|
return `API Key (${securityScheme.name})`;
|
364
308
|
}
|
365
|
-
|
366
309
|
if (securityScheme.type === 'oauth2') {
|
367
310
|
return 'OAuth2.0';
|
368
311
|
}
|
369
|
-
|
370
312
|
if (securityScheme.type === 'http') {
|
371
313
|
return securityScheme.scheme === 'basic' ? getI18nText('authentication.http-basic') : 'HTTP Bearer';
|
372
314
|
}
|
373
|
-
|
374
315
|
return securityScheme.type;
|
375
316
|
}
|
376
|
-
|
377
317
|
export function pathSecurityTemplate(pathSecurityOptions) {
|
378
318
|
const requiredSecurityOptions = (pathSecurityOptions === null || pathSecurityOptions === void 0 ? void 0 : pathSecurityOptions.filter(o => o && Object.keys(o).length)) || [];
|
379
|
-
|
380
319
|
if (this.resolvedSpec.securitySchemes && requiredSecurityOptions.length) {
|
381
320
|
const orSecurityKeys1 = [];
|
382
321
|
requiredSecurityOptions.forEach(pSecurity => {
|
@@ -384,10 +323,10 @@ export function pathSecurityTemplate(pathSecurityOptions) {
|
|
384
323
|
const andKeyTypes = [];
|
385
324
|
Object.keys(pSecurity).forEach(pathSecurityKey => {
|
386
325
|
const s = this.resolvedSpec.securitySchemes.find(ss => ss.apiKeyId === pathSecurityKey);
|
387
|
-
|
388
326
|
if (s) {
|
389
327
|
andKeyTypes.push(getTypeDisplayHeader(s));
|
390
|
-
andSecurityKeys1.push({
|
328
|
+
andSecurityKeys1.push({
|
329
|
+
...s,
|
391
330
|
scopes: pSecurity[pathSecurityKey]
|
392
331
|
});
|
393
332
|
}
|
@@ -399,7 +338,7 @@ export function pathSecurityTemplate(pathSecurityOptions) {
|
|
399
338
|
});
|
400
339
|
return html`<div class="security-info-button" data-content-id="auth" @click="${e => this.scrollToEventTarget(e, false)}"> <div style="position:relative;display:flex;min-width:350px;max-width:700px;justify-content:flex-end"> <svg width="16" height="24" style="cursor:pointer"> <g> <path style="fill:var(--fg3)" d="m13.8,8.5l0,-2.6l0,0c0,-3.2 -2.6,-5.8 -5.8,-5.8s-5.8,2.6 -5.8,5.8l0,0l0,2.6l-2.1,0l0,11.2l16,0l0,-11.2l-2.1,0l-0,0l0,0l0,0l-0,0zm-9.8,-2.6c0,0 0,0 0,0c0,-2.2 1.8,-4 4,-4c2.2,0 4,1.8 4,4c0,0 0,0 0,0l0,2.6l-8.03,0l0,-2.6l0,0l0,0z"/> </g> </svg> ${orSecurityKeys1.map((orSecurityItem1, i) => html` ${i !== 0 ? html`<div style="padding:3px 4px"> OR </div>` : ''} <div class="security-tooltip tooltip" style="cursor:pointer"> <div style="padding:2px 4px;white-space:nowrap;text-overflow:ellipsis;max-width:150px;overflow:hidden"> <span part="anchor anchor-operation-security"> ${orSecurityItem1.securityTypes} </span> </div> <div class="tooltip-text" style="position:absolute;color:var(--fg);top:26px;right:0;border:1px solid var(--border-color);padding:2px 4px;display:block"> ${orSecurityItem1.securityDefs.length > 1 ? html`<div>Requires <b>all</b> of the following </div>` : ''} <div style="padding-left:8px"> ${orSecurityItem1.securityDefs.map((andSecurityItem, j) => html` ${andSecurityItem.type === 'oauth2' ? html` <div> ${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> ` : html`Requires`} OAuth token (${andSecurityItem.apiKeyId}) in <b>Authorization header</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>` : andSecurityItem.type === 'http' ? html` <div> ${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> ` : html`${getI18nText('authentication.requires')}`} ${andSecurityItem.scheme === 'basic' ? getI18nText('authentication.http-basic-note') : 'Bearer Token'} ${getI18nText('authentication.in-auth-header')} ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>` : html` <div> ${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> ` : html`Requires`} Token in <b>${andSecurityItem.name} ${andSecurityItem.in}</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>`} `)} </div> </div> </div> `)} </div> </div>`;
|
401
340
|
}
|
402
|
-
|
403
341
|
return '';
|
404
342
|
}
|
343
|
+
|
405
344
|
/* eslint-enable indent */
|
@@ -2,14 +2,12 @@ import { html } from 'lit';
|
|
2
2
|
import { marked } from 'marked';
|
3
3
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
4
4
|
import { getI18nText } from '../languages/index.js';
|
5
|
-
|
6
5
|
function onApiServerChange(e, server) {
|
7
6
|
if (e && e.target.checked) {
|
8
7
|
this.selectedServer = server;
|
9
8
|
this.requestUpdate();
|
10
9
|
}
|
11
10
|
}
|
12
|
-
|
13
11
|
function onApiServerVarChange(e, serverObj) {
|
14
12
|
const inputEls = [...e.currentTarget.closest('table').querySelectorAll('input, select')];
|
15
13
|
let tempUrl = serverObj.url;
|
@@ -20,26 +18,21 @@ function onApiServerVarChange(e, serverObj) {
|
|
20
18
|
serverObj.computedUrl = tempUrl;
|
21
19
|
this.requestUpdate();
|
22
20
|
}
|
23
|
-
/* eslint-disable indent */
|
24
|
-
|
25
21
|
|
22
|
+
/* eslint-disable indent */
|
26
23
|
function serverVarsTemplate() {
|
27
24
|
var _this$selectedServer;
|
28
|
-
|
29
25
|
return Object.keys(((_this$selectedServer = this.selectedServer) === null || _this$selectedServer === void 0 ? void 0 : _this$selectedServer.variables) || {}).length ? html` <div class="table-title">${getI18nText('api-servers.server-variables')}</div> <table role="presentation" class="m-table"> ${Object.entries(this.selectedServer.variables).map(kv => html` <tr> <td colspan="1" style="vertical-align:middle">${kv[0]}</td> <td colspan="2"> ${kv[1].enum ? html` <select data-var="${kv[0]}" @input="${e => {
|
30
26
|
onApiServerVarChange.call(this, e, this.selectedServer);
|
31
27
|
}}"> ${Object.entries(kv[1].enum).map(e => kv[1].default === e[1] ? html` <option selected="selected" label="${e[1]}" value="${e[1]}">` : html` <option label="${e[1]}" value="${e[1]}">`)} </select>` : html` <input type="text" part="textbox textbox-server-var" spellcheck="false" data-var="${kv[0]}" value="${kv[1].default}" @input="${e => {
|
32
28
|
onApiServerVarChange.call(this, e, this.selectedServer);
|
33
29
|
}}">`} </td> </tr> ${kv[1].description ? html`<tr><td colspan="2" style="border:none"><span class="m-markdown-small"> ${unsafeHTML(marked(kv[1].description))} </span></td></tr>` : ''} `)} </table> ` : '';
|
34
30
|
}
|
35
|
-
|
36
31
|
export default function serverTemplate() {
|
37
32
|
var _this$selectedServer2;
|
38
|
-
|
39
33
|
if (!this.resolvedSpec) {
|
40
34
|
return undefined;
|
41
35
|
}
|
42
|
-
|
43
36
|
return html` <section id="servers" part="section-servers" style="margin-top:24px;margin-bottom:24px" class="regular-font observe-me section-padding ${this.renderStyle === 'read' ? 'section-gap--read-mode' : this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <div class="sub-title">${getI18nText('headers.api-servers')}</div> <div class="mono-font" style="margin:12px 0;font-size:calc(var(--font-size-small) + 1px)"> ${!this.resolvedSpec.servers || !this.resolvedSpec.servers.length ? '' : html` ${this.resolvedSpec.servers.map((server, i) => html` <input type="radio" name="api_server" id="srvr-opt-${i}" value="${server.url}" @change="${e => {
|
44
37
|
onApiServerChange.call(this, e, server);
|
45
38
|
}}" .checked="${this.selectedServer.url === server.url}" style="margin:4px 0;cursor:pointer"> <label style="cursor:pointer" for="srvr-opt-${i}"> ${server.url} ${server.description ? html`- <span class="regular-font">${server.description} </span>` : ''} </label> <br> `)} `} <div class="table-title primary-text" part="label-selected-server"> ${getI18nText('api-servers.selected')}: ${((_this$selectedServer2 = this.selectedServer) === null || _this$selectedServer2 === void 0 ? void 0 : _this$selectedServer2.computedUrl) || 'none'}</div> </div> <slot name="servers"></slot> ${serverVarsTemplate.call(this)} </section>`;
|
@@ -1,24 +1,19 @@
|
|
1
1
|
/* eslint-disable no-mixed-operators */
|
2
|
-
|
3
2
|
/* eslint-disable no-bitwise */
|
4
3
|
export default {
|
5
4
|
color: {
|
6
5
|
inputReverseFg: '#fff',
|
7
6
|
inputReverseBg: '#333',
|
8
7
|
headerBg: '#444',
|
9
|
-
|
10
8
|
getRgb(hexStr) {
|
11
9
|
let hex = (hexStr || '').trim();
|
12
|
-
|
13
10
|
if (hex.indexOf('#') === 0) {
|
14
11
|
hex = hex.slice(1, 7);
|
15
|
-
}
|
16
|
-
|
17
|
-
|
12
|
+
}
|
13
|
+
// convert 3-digit hex to 6-digits.
|
18
14
|
if (hex.length === 3 || hex.length === 4) {
|
19
15
|
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
20
16
|
}
|
21
|
-
|
22
17
|
if (hex.length !== 6) {
|
23
18
|
// eslint-disable-next-line no-console
|
24
19
|
console.error(`Invalid HEX color: '${hexStr}'`);
|
@@ -28,24 +23,20 @@ export default {
|
|
28
23
|
b: 0
|
29
24
|
};
|
30
25
|
}
|
31
|
-
|
32
26
|
return {
|
33
27
|
r: parseInt(hex.slice(0, 2), 16),
|
34
28
|
g: parseInt(hex.slice(2, 4), 16),
|
35
29
|
b: parseInt(hex.slice(4, 6), 16)
|
36
30
|
};
|
37
31
|
},
|
38
|
-
|
39
32
|
luminanace(hexColorCode) {
|
40
33
|
const rgb = this.getRgb(hexColorCode);
|
41
34
|
return rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114;
|
42
35
|
},
|
43
|
-
|
44
36
|
invert(hexColorCode) {
|
45
37
|
// compare with `>=128`, but giving little more preference to white over black
|
46
38
|
return this.luminanace(hexColorCode) > 149 ? '#000000' : '#ffffff';
|
47
39
|
},
|
48
|
-
|
49
40
|
// https://stackoverflow.com/a/41491220/5091874
|
50
41
|
selectTextColorFromBackground(bcHexColor) {
|
51
42
|
const {
|
@@ -58,49 +49,39 @@ export default {
|
|
58
49
|
if (col <= 0.03928) {
|
59
50
|
return col / 12.92;
|
60
51
|
}
|
61
|
-
|
62
52
|
return ((col + 0.055) / 1.055) ** 2.4;
|
63
53
|
});
|
64
54
|
const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
65
55
|
return L > 0.179 ? '#000000' : '#FFFFFF';
|
66
56
|
},
|
67
|
-
|
68
57
|
opacity(hex, opacity) {
|
69
58
|
const rgb = this.getRgb(hex);
|
70
59
|
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;
|
71
60
|
},
|
72
|
-
|
73
61
|
brightness(hex, amt) {
|
74
62
|
const rgb = this.getRgb(hex);
|
75
63
|
rgb.r += amt;
|
76
64
|
rgb.g += amt;
|
77
65
|
rgb.b += amt;
|
78
|
-
|
79
66
|
if (rgb.r > 255) {
|
80
67
|
rgb.r = 255;
|
81
68
|
} else if (rgb.r < 0) {
|
82
69
|
rgb.r = 0;
|
83
70
|
}
|
84
|
-
|
85
71
|
if (rgb.g > 255) {
|
86
72
|
rgb.g = 255;
|
87
73
|
} else if (rgb.g < 0) {
|
88
74
|
rgb.g = 0;
|
89
75
|
}
|
90
|
-
|
91
76
|
if (rgb.b > 255) {
|
92
77
|
rgb.b = 255;
|
93
78
|
} else if (rgb.b < 0) {
|
94
79
|
rgb.b = 0;
|
95
80
|
}
|
96
|
-
|
97
81
|
return `#${rgb.r.toString(16).padStart(2, '0')}${rgb.g.toString(16).padStart(2, '0')}${rgb.b.toString(16).padStart(2, '0')}`;
|
98
82
|
}
|
99
|
-
|
100
83
|
},
|
101
|
-
|
102
84
|
isValidHexColor(colorCode) {
|
103
85
|
return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/i.test(colorCode);
|
104
86
|
}
|
105
|
-
|
106
87
|
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { getI18nText } from '../languages/index.js';
|
2
|
-
/* For Delayed Event Handler Execution */
|
3
2
|
|
3
|
+
/* For Delayed Event Handler Execution */
|
4
4
|
export function debounce(fn, delay) {
|
5
5
|
let timeoutID = null;
|
6
6
|
return (...args) => {
|
@@ -19,28 +19,24 @@ export function sleep(ms) {
|
|
19
19
|
export function copyToClipboard(copyData, eventTarget) {
|
20
20
|
// In lots of places we have more than a couple of spaces for <pre> display purposes, we remove those extra spaces here.
|
21
21
|
let data = copyData === null || copyData === void 0 ? void 0 : copyData.trim().replace(/\s{8}/g, ' ');
|
22
|
-
|
23
22
|
try {
|
24
23
|
// If the parsed type is a number, then leave it alone
|
25
24
|
if (typeof JSON.parse(data) === 'object') {
|
26
25
|
// Convert to 2 spaces in all JSON text
|
27
26
|
data = JSON.stringify(JSON.parse(data), null, 2).trim();
|
28
27
|
}
|
29
|
-
} catch (error) {
|
28
|
+
} catch (error) {
|
29
|
+
// Ignore non JSON text;
|
30
30
|
}
|
31
|
-
|
32
31
|
const textArea = document.createElement('textarea');
|
33
32
|
textArea.value = data;
|
34
33
|
textArea.style.position = 'fixed'; // avoid scrolling to bottom
|
35
|
-
|
36
34
|
document.body.appendChild(textArea);
|
37
35
|
textArea.focus();
|
38
36
|
textArea.select();
|
39
|
-
|
40
37
|
try {
|
41
38
|
document.execCommand('copy');
|
42
39
|
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
43
|
-
|
44
40
|
if (btnEl) {
|
45
41
|
btnEl.innerText = getI18nText('operations.copied');
|
46
42
|
setTimeout(() => {
|
@@ -50,7 +46,6 @@ export function copyToClipboard(copyData, eventTarget) {
|
|
50
46
|
} catch (err) {
|
51
47
|
console.error('Unable to copy', err); // eslint-disable-line no-console
|
52
48
|
}
|
53
|
-
|
54
49
|
document.body.removeChild(textArea);
|
55
50
|
}
|
56
51
|
export function getBaseUrlFromUrl(url) {
|
@@ -64,7 +59,6 @@ export function pathIsInSearch(searchVal, path) {
|
|
64
59
|
if (!searchVal) {
|
65
60
|
return true;
|
66
61
|
}
|
67
|
-
|
68
62
|
const stringToSearch = `${path.method} ${path.path} ${path.summary || ''} ${path.description || ''} ${path.operationId || ''}`;
|
69
63
|
return stringToSearch.includes(searchVal) || stringToSearch.toLowerCase().includes(searchVal) || stringToSearch.normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchVal) || stringToSearch.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchVal);
|
70
64
|
}
|
@@ -72,10 +66,8 @@ export function schemaKeys(schemaProps, result = new Set()) {
|
|
72
66
|
if (!schemaProps) {
|
73
67
|
return result;
|
74
68
|
}
|
75
|
-
|
76
69
|
Object.keys(schemaProps).forEach(key => {
|
77
70
|
result.add(key);
|
78
|
-
|
79
71
|
if (schemaProps[key].properties) {
|
80
72
|
schemaKeys(schemaProps[key].properties, result);
|
81
73
|
} else if (schemaProps[key].items && schemaProps[key].items.properties) {
|
@@ -88,40 +80,31 @@ export function advancedSearch(searchVal, allSpecTags, searchOptions = []) {
|
|
88
80
|
if (!searchVal.trim() || searchOptions.length === 0) {
|
89
81
|
return undefined;
|
90
82
|
}
|
91
|
-
|
92
83
|
const pathsMatched = [];
|
93
84
|
allSpecTags.forEach(tag => {
|
94
85
|
tag.paths.forEach(path => {
|
95
86
|
let stringToSearch = '';
|
96
|
-
|
97
87
|
if (searchOptions.includes('search-api-path')) {
|
98
88
|
stringToSearch = path.path;
|
99
89
|
}
|
100
|
-
|
101
90
|
if (searchOptions.includes('search-api-descr')) {
|
102
91
|
stringToSearch = `${stringToSearch} ${path.summary || path.description || ''}`;
|
103
92
|
}
|
104
|
-
|
105
93
|
if (searchOptions.includes('search-api-params')) {
|
106
94
|
stringToSearch = `${stringToSearch} ${path.parameters && path.parameters.map(v => v.name).join(' ') || ''}`;
|
107
95
|
}
|
108
|
-
|
109
96
|
if (searchOptions.includes('search-api-request-body') && path.requestBody) {
|
110
97
|
let schemaKeySet = new Set();
|
111
|
-
|
112
98
|
for (const contentType in path.requestBody && path.requestBody.content) {
|
113
99
|
if (path.requestBody.content[contentType].schema && path.requestBody.content[contentType].schema.properties) {
|
114
100
|
schemaKeySet = schemaKeys(path.requestBody.content[contentType].schema.properties);
|
115
101
|
}
|
116
|
-
|
117
102
|
stringToSearch = `${stringToSearch} ${[...schemaKeySet].join(' ')}`;
|
118
103
|
}
|
119
104
|
}
|
120
|
-
|
121
105
|
if (searchOptions.includes('search-api-resp-descr')) {
|
122
106
|
stringToSearch = `${stringToSearch} ${Object.values(path.responses).map(v => v.description || '').join(' ')}`;
|
123
107
|
}
|
124
|
-
|
125
108
|
if (stringToSearch.toLowerCase().includes(searchVal.trim().toLowerCase())) {
|
126
109
|
pathsMatched.push({
|
127
110
|
elementId: path.elementId,
|