openapi-explorer 0.9.385 → 0.9.392

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +3 -2
  3. package/dist/browser/openapi-explorer.min.js +7 -5
  4. package/dist/browser/openapi-explorer.min.js.map +1 -1
  5. package/dist/es/components/api-request.js +51 -18
  6. package/dist/es/components/api-response.js +17 -5
  7. package/dist/es/components/json-tree.js +3 -2
  8. package/dist/es/components/mime-types.js +5 -5
  9. package/dist/es/components/schema-table.js +1 -1
  10. package/dist/es/components/schema-tree.js +4 -3
  11. package/dist/es/languages/en.js +59 -0
  12. package/dist/es/languages/fr.js +59 -0
  13. package/dist/es/languages/index.js +20 -0
  14. package/dist/es/openapi-explorer.js +8 -3
  15. package/dist/es/styles/input-styles.js +1 -1
  16. package/dist/es/styles/schema-styles.js +1 -1
  17. package/dist/es/templates/callback-template.js +1 -1
  18. package/dist/es/templates/code-samples-template.js +2 -1
  19. package/dist/es/templates/components-template.js +4 -2
  20. package/dist/es/templates/endpoint-template.js +1 -1
  21. package/dist/es/templates/expanded-endpoint-template.js +1 -1
  22. package/dist/es/templates/navbar-template.js +3 -2
  23. package/dist/es/templates/overview-template.js +2 -1
  24. package/dist/es/templates/security-scheme-template.js +6 -5
  25. package/dist/es/templates/server-template.js +4 -3
  26. package/dist/es/utils/common-utils.js +4 -2
  27. package/dist/es/utils/schema-utils.js +51 -44
  28. package/dist/es/utils/spec-parser.js +3 -2
  29. package/dist/lib/components/api-request.js +52 -18
  30. package/dist/lib/components/api-response.js +18 -5
  31. package/dist/lib/components/json-tree.js +4 -2
  32. package/dist/lib/components/mime-types.js +8 -9
  33. package/dist/lib/components/schema-table.js +1 -1
  34. package/dist/lib/components/schema-tree.js +5 -3
  35. package/dist/lib/languages/en.js +64 -0
  36. package/dist/lib/languages/fr.js +64 -0
  37. package/dist/lib/languages/index.js +32 -0
  38. package/dist/lib/openapi-explorer.js +9 -3
  39. package/dist/lib/styles/input-styles.js +1 -1
  40. package/dist/lib/styles/schema-styles.js +1 -1
  41. package/dist/lib/templates/callback-template.js +1 -1
  42. package/dist/lib/templates/code-samples-template.js +3 -1
  43. package/dist/lib/templates/components-template.js +4 -2
  44. package/dist/lib/templates/endpoint-template.js +1 -1
  45. package/dist/lib/templates/expanded-endpoint-template.js +1 -1
  46. package/dist/lib/templates/navbar-template.js +4 -2
  47. package/dist/lib/templates/overview-template.js +3 -1
  48. package/dist/lib/templates/security-scheme-template.js +7 -5
  49. package/dist/lib/templates/server-template.js +5 -3
  50. package/dist/lib/utils/common-utils.js +4 -2
  51. package/dist/lib/utils/schema-utils.js +51 -44
  52. package/dist/lib/utils/spec-parser.js +4 -2
  53. package/package.json +7 -4
@@ -2,6 +2,7 @@ import { html } from 'lit-element';
2
2
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
3
  import { marked } from 'marked';
4
4
  import base64url from 'base64url';
5
+ import { getI18nText } from '../languages';
5
6
 
6
7
  function onApiKeyChange(apiKeyId, e) {
7
8
  let apiKeyValue = '';
@@ -281,16 +282,16 @@ export default function securitySchemeTemplate() {
281
282
  }
282
283
 
283
284
  const providedApiKeys = schemes.filter(v => v.finalKeyValue);
284
- 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"> <div class="sub-title regular-font">AUTHENTICATION</div> <div class="small-font-size" style="display:flex;align-items:center;min-height:30px"> ${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="${() => {
285
+ 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"> <div class="sub-title regular-font">${getI18nText('headers.authentication')}</div> <div class="small-font-size" style="display:flex;align-items:center;min-height:30px"> ${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="${() => {
285
286
  onClearAllApiKeys.call(this);
286
- }}">CLEAR ALL API KEYS</button>` : html`<div class="red-text">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 style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px"> <span style="font-weight:700">${v.typeDisplay}</span> ${v.finalKeyValue ? html` <span class="blue-text"> ${v.finalKeyValue ? 'Key Applied' : ''} </span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
287
+ }}">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 style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px"> <span style="font-weight:700">${v.typeDisplay}</span> ${v.finalKeyValue ? html` <span class="blue-text"> ${v.finalKeyValue ? 'Key Applied' : ''} </span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
287
288
  v.finalKeyValue = '';
288
289
  this.requestUpdate();
289
290
  }}">REMOVE</button> ` : ''} </div> ${v.description ? html` <div class="m-markdown"> ${unsafeHTML(marked(v.description || ''))} </div>` : ''} </td> <td> ${v.type && (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') ? html` ${v.type.toLowerCase() === 'apikey' ? html`Send <code>${v.name}</code> in <code>${v.in}</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 a Token String.`} <form style="display:flex"> ${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>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : html` <input type="text" value="${v.value}" class="api-key-input" placeholder="api-token" spellcheck="false"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
290
291
  onApiKeyChange.call(this, v.apiKeyId, e);
291
- }}"> ${v.finalKeyValue ? 'UPDATE' : 'SET'} </button>`} </form>` : ''} ${v.type && v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic' ? html` Send the <code>Authorization</code> header containing the type <code>Basic</code> followed by a space and a base64 encoded string of <code>username:password</code>. <form style="display:flex"> <input type="text" value="${v.user}" placeholder="username" spellcheck="false" class="api-key-user" style="width:100px"> <input type="password" value="${v.password}" placeholder="password" spellcheck="false" class="api-key-password" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
292
+ }}"> ${v.finalKeyValue ? 'UPDATE' : 'SET'} </button>`} </form>` : ''} ${v.type && v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic' ? html` ${getI18nText('authentication.http-basic-desc')} <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${getI18nText('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input type="password" value="${v.password}" placeholder="${getI18nText('authentication.password')}" spellcheck="false" class="api-key-password" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
292
293
  onApiKeyChange.call(this, v.apiKeyId, e);
293
- }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : 'SET'} </button> </form>` : ''} </td> </tr> ${v.type.toLowerCase() === 'oauth2' ? html` <tr> <td colspan="2" style="border:none;padding-left:48px"> ${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))} </td> </tr> ` : ''} `)} </table>` : ''} </div> </slot> </section> `;
294
+ }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : getI18nText('authentication.set')} </button> </form>` : ''} </td> </tr> ${v.type.toLowerCase() === 'oauth2' ? html` <tr> <td colspan="2" style="border:none;padding-left:48px"> ${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))} </td> </tr> ` : ''} `)} </table>` : ''} </div> </slot> </section> `;
294
295
  }
295
296
 
296
297
  function getOauthScopeTemplate(scopes) {
@@ -322,7 +323,7 @@ export function pathSecurityTemplate(pathSecurity) {
322
323
  securityDefs: andSecurityKeys1
323
324
  });
324
325
  });
325
- 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="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> &nbsp;` : 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> &nbsp;` : html`Requires`} ${andSecurityItem.scheme === 'basic' ? 'Base 64 encoded username:password' : 'Bearer Token'} in <b>Authorization header</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>` : html` <div> ${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> &nbsp;` : html`Requires`} Token in <b>${andSecurityItem.name} ${andSecurityItem.in}</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>`} `)} </div> </div> </div> `)} </div> </div>`;
326
+ 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="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> &nbsp;` : 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> &nbsp;` : 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> &nbsp;` : html`Requires`} Token in <b>${andSecurityItem.name} ${andSecurityItem.in}</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>`} `)} </div> </div> </div> `)} </div> </div>`;
326
327
  }
327
328
 
328
329
  return '';
@@ -1,6 +1,7 @@
1
1
  import { html } from 'lit-element';
2
2
  import { marked } from 'marked';
3
3
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
4
+ import { getI18nText } from '../languages';
4
5
 
5
6
  function onApiServerChange(e, server) {
6
7
  if (e && e.target.checked) {
@@ -23,7 +24,7 @@ function onApiServerVarChange(e, serverObj) {
23
24
 
24
25
 
25
26
  function serverVarsTemplate() {
26
- return this.selectedServer && this.selectedServer.variables ? html` <div class="table-title"> SERVER VARIABLES</div> <table role="presentation" class="m-table"> ${Object.entries(this.selectedServer.variables).map(kv => html` <tr> <td style="vertical-align:middle">${kv[0]}</td> <td> ${kv[1].enum ? html` <select data-var="${kv[0]}" @input="${e => {
27
+ return this.selectedServer && this.selectedServer.variables ? 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 style="vertical-align:middle">${kv[0]}</td> <td> ${kv[1].enum ? html` <select data-var="${kv[0]}" @input="${e => {
27
28
  onApiServerVarChange.call(this, e, this.selectedServer);
28
29
  }}"> ${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 => {
29
30
  onApiServerVarChange.call(this, e, this.selectedServer);
@@ -35,8 +36,8 @@ export default function serverTemplate() {
35
36
  return undefined;
36
37
  }
37
38
 
38
- 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">API SERVER</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 => {
39
+ 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 => {
39
40
  onApiServerChange.call(this, e, server);
40
- }}" .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"> SELECTED: ${this.selectedServer && this.selectedServer.computedUrl || 'none'}</div> </div> <slot name="servers"></slot> ${serverVarsTemplate.call(this)} </section>`;
41
+ }}" .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.selectedServer && this.selectedServer.computedUrl || 'none'}</div> </div> <slot name="servers"></slot> ${serverVarsTemplate.call(this)} </section>`;
41
42
  }
42
43
  /* eslint-enable indent */
@@ -1,4 +1,6 @@
1
+ import { getI18nText } from '../languages';
1
2
  /* For Delayed Event Handler Execution */
3
+
2
4
  export function debounce(fn, delay) {
3
5
  let timeoutID = null;
4
6
  return (...args) => {
@@ -26,9 +28,9 @@ export function copyToClipboard(data, e) {
26
28
 
27
29
  try {
28
30
  document.execCommand('copy');
29
- btnEl.innerText = 'Copied';
31
+ btnEl.innerText = getI18nText('operations.copied');
30
32
  setTimeout(() => {
31
- btnEl.innerText = 'Copy';
33
+ btnEl.innerText = getI18nText('operations.copy');
32
34
  }, 5000);
33
35
  } catch (err) {
34
36
  console.error('Unable to copy', err); // eslint-disable-line no-console
@@ -1,31 +1,38 @@
1
1
  import cloneDeep from 'lodash.clonedeep';
2
2
  import { expandN } from 'regex-to-strings';
3
- import xmlFormatter from './xml/xml'; // When the type is not known for a property set the displayed type to be this:
3
+ import xmlFormatter from './xml/xml.js'; // When the type is not known for a property set the displayed type to be this:
4
4
 
5
5
  const IS_MISSING_TYPE_INFO_TYPE = '';
6
6
  /* Generates an schema object containing type and constraint info */
7
7
 
8
- export function getTypeInfo(schema) {
9
- var _schema$items;
8
+ export function getTypeInfo(schema, options = {
9
+ includeNulls: false
10
+ }) {
11
+ var _schema$items, _schema$const;
10
12
 
11
13
  if (!schema) {
12
14
  return undefined;
13
15
  }
14
16
 
15
- let dataType = '';
16
- let constraint = '';
17
+ let dataType = IS_MISSING_TYPE_INFO_TYPE;
17
18
 
18
19
  if (schema.circularReference) {
19
20
  dataType = `{recursive: ${schema.circularReference.name}} `;
20
21
  } else if (schema.type) {
21
22
  const arraySchema = Array.isArray(schema.type) ? schema.type : typeof schema.type === 'string' ? schema.type.split('┃') : schema.type;
22
- dataType = Array.isArray(arraySchema) ? arraySchema.filter(s => s !== 'null').join('┃') : schema.type;
23
+ dataType = Array.isArray(arraySchema) ? arraySchema.filter(s => s !== 'null' || options.includeNulls).join('┃') : schema.type;
23
24
 
24
- if (schema.format || schema.enum) {
25
- dataType = dataType.replace('string', schema.enum ? 'enum' : schema.format);
25
+ if (schema.format || schema.enum || schema.const) {
26
+ dataType = dataType.replace('string', schema.enum && 'enum' || schema.const && 'const' || schema.format);
27
+ }
28
+
29
+ if (schema.nullable && options.includeNulls) {
30
+ dataType += '┃null';
31
+ }
32
+
33
+ if (dataType.includes('┃null') && schema.format) {
34
+ schema.format += '┃null';
26
35
  }
27
- } else {
28
- dataType = IS_MISSING_TYPE_INFO_TYPE;
29
36
  }
30
37
 
31
38
  const info = {
@@ -39,21 +46,18 @@ export function getTypeInfo(schema) {
39
46
  title: schema.title || '',
40
47
  description: schema.description || '',
41
48
  constraint: '',
42
- allowedValues: '',
43
- arrayType: '',
44
- html: ''
45
- }; // Set Allowed Values
46
-
47
- info.allowedValues = Array.isArray(schema.enum) ? schema.enum.join('┃') : '';
49
+ allowedValues: (_schema$const = schema.const) !== null && _schema$const !== void 0 ? _schema$const : Array.isArray(schema.enum) ? schema.enum.join('') : '',
50
+ arrayType: ''
51
+ };
48
52
 
49
53
  if (dataType === 'array' && schema.items) {
50
- var _schema$items$default;
54
+ var _schema$items$default, _schema$const2;
51
55
 
52
56
  const arrayItemType = schema.items.type;
53
57
  const arrayItemDefault = (_schema$items$default = schema.items.default) !== null && _schema$items$default !== void 0 ? _schema$items$default : '';
54
58
  info.arrayType = `${schema.type} of ${Array.isArray(arrayItemType) ? arrayItemType.join('') : arrayItemType}`;
55
59
  info.default = arrayItemDefault;
56
- info.allowedValues = Array.isArray(schema.items.enum) ? schema.items.enum.join('┃') : '';
60
+ info.allowedValues = (_schema$const2 = schema.const) !== null && _schema$const2 !== void 0 ? _schema$const2 : Array.isArray(schema.items.enum) ? schema.items.enum.join('┃') : '';
57
61
  }
58
62
 
59
63
  if (dataType.match(/integer|number/g)) {
@@ -65,25 +69,24 @@ export function getTypeInfo(schema) {
65
69
  const rightBound = schema.maximum !== undefined ? ']' : ')';
66
70
 
67
71
  if (typeof minimum === 'number' || typeof maximum === 'number') {
68
- constraint = `Range: ${leftBound}${minimum !== null && minimum !== void 0 ? minimum : ''},${maximum !== null && maximum !== void 0 ? maximum : ''}${rightBound}`;
72
+ info.constraint = `Range: ${leftBound}${minimum !== null && minimum !== void 0 ? minimum : ''},${maximum !== null && maximum !== void 0 ? maximum : ''}${rightBound}`;
69
73
  }
70
74
 
71
75
  if (schema.multipleOf !== undefined) {
72
- constraint += `${constraint ? ', ' : ''}Multiples: ${schema.multipleOf}`;
76
+ info.constraint += `${info.constraint ? ', ' : ''}Multiples: ${schema.multipleOf}`;
73
77
  }
74
78
  }
75
79
 
76
80
  if (dataType.match(/string/g)) {
77
81
  if (schema.minLength !== undefined && schema.maxLength !== undefined) {
78
- constraint += `Min length: ${schema.minLength}, Max length: ${schema.maxLength}`;
82
+ info.constraint += `Min length: ${schema.minLength}, Max length: ${schema.maxLength}`;
79
83
  } else if (schema.minLength !== undefined) {
80
- constraint += `Min length: ${schema.minLength}`;
84
+ info.constraint += `Min length: ${schema.minLength}`;
81
85
  } else if (schema.maxLength !== undefined) {
82
- constraint += `Max length: ${schema.maxLength}`;
86
+ info.constraint += `Max length: ${schema.maxLength}`;
83
87
  }
84
88
  }
85
89
 
86
- info.constraint = constraint;
87
90
  info.html = JSON.stringify({
88
91
  type: info.type,
89
92
  format: info.format,
@@ -160,6 +163,10 @@ export function getSampleValueByType(schemaObj, fallbackPropertyName, skipExampl
160
163
  }
161
164
 
162
165
  if (typeValue.match(/^string/g)) {
166
+ if (schemaObj.const) {
167
+ return schemaObj.const;
168
+ }
169
+
163
170
  if (schemaObj.enum) {
164
171
  return schemaObj.enum[0];
165
172
  }
@@ -356,13 +363,13 @@ function getExampleValuesFromSchemaRecursive(schema, config = {}) {
356
363
  * For changing OpenAPI-Schema to an Object Notation,
357
364
  * This Object would further be an input to UI Components to generate an Object-Tree
358
365
  * @param {object} schema - Schema object from OpenAPI spec
359
- * @param {object} obj - recursively pass this object to generate object notation
366
+ * @param {object} options - recursively pass this object to generate object notation
360
367
  * @param {number} level - recursion level
361
368
  * @param {string} suffix - used for suffixing property names to avoid duplicate props during object composition
362
369
  */
363
370
 
364
371
 
365
- export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
372
+ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
366
373
  if (!rawSchema) {
367
374
  return undefined;
368
375
  }
@@ -380,18 +387,18 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
380
387
  allOf.map((v, i) => {
381
388
  if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) {
382
389
  const propSuffix = (v.anyOf || v.oneOf) && i > 0 ? i : '';
383
- const partialObj = schemaInObjectNotation(v, {}, level + 1, propSuffix);
390
+ const partialObj = schemaInObjectNotation(v, options, level + 1, propSuffix);
384
391
  Object.assign(objWithAllProps, partialObj);
385
392
  } else if (v.type === 'array' || v.items) {
386
- const partialObj = schemaInObjectNotation(v, {}, level + 1);
393
+ const partialObj = schemaInObjectNotation(v, options, level + 1);
387
394
  Object.assign(objWithAllProps, partialObj);
388
395
  } else if (v.type) {
389
396
  const prop = `prop${Object.keys(objWithAllProps).length}`;
390
- const typeObj = getTypeInfo(v);
397
+ const typeObj = getTypeInfo(v, options);
391
398
  objWithAllProps[prop] = `${typeObj.html}`;
392
399
  }
393
400
  });
394
- const obj = schemaInObjectNotation(schema, {}, 0);
401
+ const obj = schemaInObjectNotation(schema, options, 0);
395
402
  return Object.assign({}, objWithAllProps, typeof obj === 'object' && !Array.isArray(obj) ? obj : {});
396
403
  } else if (anyOf || oneOf) {
397
404
  const objWithAnyOfProps = {};
@@ -401,7 +408,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
401
408
  if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) {
402
409
  var _partialObj$Flags, _partialObj$Flags2;
403
410
 
404
- const partialObj = schemaInObjectNotation(v, {});
411
+ const partialObj = schemaInObjectNotation(v, options);
405
412
  objWithAnyOfProps[`::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`] = partialObj;
406
413
  objWithAnyOfProps['::type'] = 'xxx-of-option';
407
414
  readOnly = readOnly && ((_partialObj$Flags = partialObj['::flags']) === null || _partialObj$Flags === void 0 ? void 0 : _partialObj$Flags['🆁']);
@@ -410,7 +417,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
410
417
  var _partialObj$Flags3, _partialObj$Flags4;
411
418
 
412
419
  // This else-if block never seems to get executed
413
- const partialObj = schemaInObjectNotation(v, {});
420
+ const partialObj = schemaInObjectNotation(v, options);
414
421
  objWithAnyOfProps[`::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`] = partialObj;
415
422
  objWithAnyOfProps['::type'] = 'xxx-of-array';
416
423
  readOnly = readOnly && ((_partialObj$Flags3 = partialObj['::flags']) === null || _partialObj$Flags3 === void 0 ? void 0 : _partialObj$Flags3['🆁']);
@@ -419,13 +426,13 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
419
426
  var _objWithAnyOfProps$, _objWithAnyOfProps$2;
420
427
 
421
428
  const prop = `::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`;
422
- objWithAnyOfProps[prop] = `${getTypeInfo(v).html}`;
429
+ objWithAnyOfProps[prop] = `${getTypeInfo(v, options).html}`;
423
430
  objWithAnyOfProps['::type'] = 'xxx-of-option';
424
431
  readOnly = readOnly && ((_objWithAnyOfProps$ = objWithAnyOfProps['::flags']) === null || _objWithAnyOfProps$ === void 0 ? void 0 : _objWithAnyOfProps$['🆁']);
425
432
  writeOnly = writeOnly && ((_objWithAnyOfProps$2 = objWithAnyOfProps['::flags']) === null || _objWithAnyOfProps$2 === void 0 ? void 0 : _objWithAnyOfProps$2['🆆']);
426
433
  }
427
434
  });
428
- const obj = schemaInObjectNotation(schema, {}, 0);
435
+ const obj = schemaInObjectNotation(schema, options, 0);
429
436
  const resultObj = typeof obj === 'object' && !Array.isArray(obj) ? obj : {};
430
437
  resultObj[anyOf ? `::ANY~OF ${suffix}` : `::ONE~OF ${suffix}`] = objWithAnyOfProps;
431
438
  resultObj['::type'] = 'xxx-of';
@@ -459,7 +466,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
459
466
 
460
467
  if (primitiveType.length > 0) {
461
468
  subSchema.type = primitiveType.join('┃');
462
- multiPrimitiveTypes = getTypeInfo(subSchema);
469
+ multiPrimitiveTypes = getTypeInfo(subSchema, options);
463
470
 
464
471
  if (complexTypes.length === 0) {
465
472
  return `${multiPrimitiveTypes && multiPrimitiveTypes.html || ''}`;
@@ -477,7 +484,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
477
484
  multiTypeOptions[`::OPTION~${i + 1}`] = 'NULL~|~~|~~|~~|~~|~~|~~|~~|~';
478
485
  } else if ('integer, number, string, boolean,'.includes(`${v},`)) {
479
486
  subSchema.type = Array.isArray(v) ? v.join('┃') : v;
480
- const primitiveTypeInfo = getTypeInfo(subSchema);
487
+ const primitiveTypeInfo = getTypeInfo(subSchema, options);
481
488
  multiTypeOptions[`::OPTION~${i + 1}`] = primitiveTypeInfo.html;
482
489
  } else if (v === 'object') {
483
490
  // If object type iterate all the properties and create an object-type-option
@@ -494,9 +501,9 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
494
501
 
495
502
  for (const key in schema.properties) {
496
503
  if (schema.required && schema.required.includes(key)) {
497
- objTypeOption[`${key}*`] = schemaInObjectNotation(schema.properties[key], {}, level + 1);
504
+ objTypeOption[`${key}*`] = schemaInObjectNotation(schema.properties[key], options, level + 1);
498
505
  } else {
499
- objTypeOption[key] = schemaInObjectNotation(schema.properties[key], {}, level + 1);
506
+ objTypeOption[key] = schemaInObjectNotation(schema.properties[key], options, level + 1);
500
507
  }
501
508
  }
502
509
 
@@ -513,7 +520,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
513
520
  '::props': schemaInObjectNotation(Object.assign({
514
521
  readOnly: schema.readOnly,
515
522
  writeOnly: schema.writeOnly
516
- }, schema.items), {}, level + 1)
523
+ }, schema.items), options, level + 1)
517
524
  };
518
525
  }
519
526
  });
@@ -535,14 +542,14 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
535
542
 
536
543
  for (const key in schema.properties) {
537
544
  if (schema.required && schema.required.includes(key)) {
538
- obj[`${key}*`] = schemaInObjectNotation(schema.properties[key], {}, level + 1);
545
+ obj[`${key}*`] = schemaInObjectNotation(schema.properties[key], options, level + 1);
539
546
  } else {
540
- obj[key] = schemaInObjectNotation(schema.properties[key], {}, level + 1);
547
+ obj[key] = schemaInObjectNotation(schema.properties[key], options, level + 1);
541
548
  }
542
549
  }
543
550
 
544
551
  if (schema.additionalProperties) {
545
- obj['<any-key>'] = schemaInObjectNotation(schema.additionalProperties, {});
552
+ obj['<any-key>'] = schemaInObjectNotation(schema.additionalProperties, options);
546
553
  }
547
554
 
548
555
  return obj;
@@ -563,7 +570,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
563
570
  deprecated: schema.deprecated,
564
571
  readOnly: schema.readOnly,
565
572
  writeOnly: schema.writeOnly
566
- }, schema.items), {}, level + 1);
573
+ }, schema.items), options, level + 1);
567
574
 
568
575
  if ((_schema$items2 = schema.items) !== null && _schema$items2 !== void 0 && _schema$items2.items) {
569
576
  obj['::array-type'] = schema.items.items.type;
@@ -572,7 +579,7 @@ export function schemaInObjectNotation(rawSchema, _, level = 0, suffix = '') {
572
579
  return obj;
573
580
  }
574
581
 
575
- const typeObj = getTypeInfo(schema);
582
+ const typeObj = getTypeInfo(schema, options);
576
583
  return `${(typeObj === null || typeObj === void 0 ? void 0 : typeObj.html) || ''}`;
577
584
  }
578
585
  /* Create Example object */
@@ -1,6 +1,7 @@
1
1
  import OpenApiResolver from 'openapi-resolver/dist/openapi-resolver.browser';
2
2
  import { marked } from 'marked';
3
3
  import { invalidCharsRegEx } from './common-utils';
4
+ import { getI18nText } from '../languages';
4
5
  import cloneDeep from 'lodash.clonedeep';
5
6
  export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
6
7
  const inputSpecIsAUrl = typeof specUrlOrObject === 'string' && specUrlOrObject.match(/^http/) || typeof specUrlOrObject === 'object' && typeof specUrlOrObject.href === 'string';
@@ -53,7 +54,7 @@ export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
53
54
 
54
55
  securitySchemes.forEach(v => {
55
56
  if (v.type === 'http') {
56
- v.typeDisplay = v.scheme === 'basic' ? 'HTTP Basic' : 'HTTP Bearer';
57
+ v.typeDisplay = v.scheme === 'basic' ? getI18nText('authentication.http-basic') : 'HTTP Bearer';
57
58
  } else if (v.type === 'apiKey') {
58
59
  v.typeDisplay = `API Key (${v.name})`;
59
60
  } else if (v.type === 'oauth2') {
@@ -155,7 +156,7 @@ function getComponents(openApiSpec) {
155
156
 
156
157
  switch (component) {
157
158
  case 'schemas':
158
- cmpName = 'Schemas';
159
+ cmpName = getI18nText('menu.schemas');
159
160
  cmpDescription = '';
160
161
  break;
161
162