rapidoc 9.2.0 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +13 -6
  4. package/index.html +6 -4
  5. package/package.json +15 -14
  6. package/src/components/api-request.js +44 -29
  7. package/src/components/api-response.js +5 -4
  8. package/src/components/json-tree.js +13 -2
  9. package/src/components/schema-table.js +37 -15
  10. package/src/components/schema-tree.js +40 -11
  11. package/src/json-schema-viewer.js +1 -1
  12. package/src/rapidoc-mini.js +25 -0
  13. package/src/rapidoc.js +39 -1
  14. package/src/styles/endpoint-styles.js +9 -9
  15. package/src/styles/nav-styles.js +3 -1
  16. package/src/styles/schema-styles.js +3 -1
  17. package/src/styles/tab-styles.js +1 -0
  18. package/src/templates/callback-template.js +8 -3
  19. package/src/templates/components-template.js +2 -0
  20. package/src/templates/endpoint-template.js +19 -15
  21. package/src/templates/expanded-endpoint-template.js +75 -71
  22. package/src/templates/header-template.js +1 -1
  23. package/src/templates/json-schema-viewer-template.js +1 -1
  24. package/src/templates/main-body-template.js +1 -1
  25. package/src/templates/navbar-template.js +21 -8
  26. package/src/templates/overview-template.js +1 -1
  27. package/src/templates/security-scheme-template.js +30 -20
  28. package/src/templates/server-template.js +2 -2
  29. package/src/utils/schema-utils.js +34 -22
  30. package/src/utils/spec-parser.js +1 -1
  31. package/src/utils/theme.js +11 -4
  32. package/webpack.config.js +1 -1
  33. package/.vscode/settings.json +0 -12
  34. package/dist/index.html +0 -6
  35. package/dist/index.html.gz +0 -0
  36. package/dist/rapidoc-min.js +0 -3670
  37. package/dist/rapidoc-min.js.LICENSE.txt +0 -68
  38. package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
  39. package/dist/rapidoc-min.js.gz +0 -0
  40. package/dist/rapidoc-min.js.map +0 -1
  41. package/dist/rapidoc-min.js.map.gz +0 -0
  42. package/dist/rapidoc.js +0 -43041
  43. package/dist/report.html +0 -38
@@ -37,81 +37,85 @@ export function expandedEndpointBodyTemplate(path, tagName = '') {
37
37
  return html`
38
38
  ${this.renderStyle === 'read' ? html`<div class='divider' part="operation-divider"></div>` : ''}
39
39
  <div class='expanded-endpoint-body observe-me ${path.method} ${path.deprecated ? 'deprecated' : ''} ' part="section-operation ${path.elementId}" id='${path.elementId}'>
40
- ${(this.renderStyle === 'focused' && tagName !== 'General ⦂') ? html`<h3 class="upper" style="font-weight:bold"> ${tagName} </h3>` : ''}
41
- ${path.deprecated ? html`<div class="bold-text red-text"> DEPRECATED </div>` : ''}
42
- ${html`
43
- ${path.xBadges && path.xBadges?.length > 0
44
- ? html`
45
- <div style="display:flex; flex-wrap:wrap; margin-bottom: -24px; font-size: var(--font-size-small);">
46
- ${path.xBadges.map((v) => (
47
- html`<span style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
48
- ))
49
- }
50
- </div>
40
+ ${(this.renderStyle === 'focused' && tagName !== 'General ⦂') ? html`<h3 class="upper" style="font-weight:bold" part="section-operation-tag"> ${tagName} </h3>` : ''}
41
+ ${path.deprecated ? html`<div class="bold-text red-text"> DEPRECATED </div>` : ''}
42
+ ${html`
43
+ ${path.xBadges && path.xBadges?.length > 0
44
+ ? html`
45
+ <div style="display:flex; flex-wrap:wrap; margin-bottom: -24px; font-size: var(--font-size-small);">
46
+ ${path.xBadges.map((v) => (
47
+ html`<span style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
48
+ ))
49
+ }
50
+ </div>
51
+ `
52
+ : ''
53
+ }
54
+ <h2 part="section-operation-summary"> ${path.shortSummary || `${path.method.toUpperCase()} ${path.path}`}</h2>
55
+ ${path.isWebhook
56
+ ? html`<span part="section-operation-webhook style="color:var(--primary-color); font-weight:bold; font-size: var(--font-size-regular);"> WEBHOOK </span>`
57
+ : html`
58
+ <div class='mono-font part="section-operation-webhook-method" regular-font-size' style='text-align:left; direction:ltr; padding: 8px 0; color:var(--fg3)'>
59
+ <span part="label-operation-method" class='regular-font upper method-fg bold-text ${path.method}'>${path.method}</span>
60
+ <span part="label-operation-path">${path.path}</span>
61
+ </div>
51
62
  `
52
- : ''
63
+ }
64
+ <slot name="${path.elementId}"></slot>`
53
65
  }
54
- <h2> ${path.shortSummary || `${path.method.toUpperCase()} ${path.path}`}</h2>
55
- ${path.isWebhook
56
- ? html`<span style="color:var(--primary-color); font-weight:bold; font-size: var(--font-size-regular);"> WEBHOOK </span>`
57
- : html`
58
- <div class='mono-font part="section-operation-url" regular-font-size' style='text-align:left; direction:ltr; padding: 8px 0; color:var(--fg3)'>
59
- <span part="label-operation-method" class='regular-font upper method-fg bold-text ${path.method}'>${path.method}</span>
60
- <span part="label-operation-path">${path.path}</span>
61
- </div>
62
- `
63
- }
64
- <slot name="${path.elementId}"></slot>`
65
- }
66
- ${path.description ? html`<div class="m-markdown"> ${unsafeHTML(marked(path.description))}</div>` : ''}
67
- ${pathSecurityTemplate.call(this, path.security)}
68
- ${codeSampleTabPanel}
69
- <div class='expanded-req-resp-container'>
70
- <api-request
71
- class = "${this.renderStyle}-mode"
72
- style = "width:100%;"
73
- method = "${path.method}"
74
- path = "${path.path}"
75
- .security = "${path.security}"
76
- .parameters = "${path.parameters}"
77
- .request_body = "${path.requestBody}"
78
- .api_keys = "${nonEmptyApiKeys}"
79
- .servers = "${path.servers}"
80
- server-url = "${path.servers?.[0]?.url || this.selectedServer.computedUrl}"
81
- fill-request-fields-with-example = "${this.fillRequestFieldsWithExample}"
82
- allow-try = "${this.allowTry}"
83
- accept = "${accept}"
84
- render-style="${this.renderStyle}"
85
- schema-style = "${this.schemaStyle}"
86
- active-schema-tab = "${this.defaultSchemaTab}"
87
- schema-expand-level = "${this.schemaExpandLevel}"
88
- schema-description-expanded = "${this.schemaDescriptionExpanded}"
89
- allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}"
90
- schema-hide-read-only = "${this.schemaHideReadOnly}"
91
- fetch-credentials = "${this.fetchCredentials}"
92
- exportparts = "btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
93
- file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
94
- anchor:anchor, anchor-param-example:anchor-param-example"
95
- > </api-request>
66
+ ${path.description ? html`<div class="m-markdown"> ${unsafeHTML(marked(path.description))}</div>` : ''}
67
+ ${pathSecurityTemplate.call(this, path.security)}
68
+ ${codeSampleTabPanel}
69
+ <div class='expanded-req-resp-container'>
70
+ <api-request
71
+ class = "${this.renderStyle}-mode"
72
+ style = "width:100%;"
73
+ method = "${path.method}"
74
+ path = "${path.path}"
75
+ .security = "${path.security}"
76
+ .parameters = "${path.parameters}"
77
+ .request_body = "${path.requestBody}"
78
+ .api_keys = "${nonEmptyApiKeys}"
79
+ .servers = "${path.servers}"
80
+ server-url = "${path.servers?.[0]?.url || this.selectedServer.computedUrl}"
81
+ fill-request-fields-with-example = "${this.fillRequestFieldsWithExample}"
82
+ use-summary-to-list-example = "${this.useSummaryToListExamples}"
83
+ allow-try = "${this.allowTry}"
84
+ accept = "${accept}"
85
+ render-style="${this.renderStyle}"
86
+ schema-style = "${this.schemaStyle}"
87
+ active-schema-tab = "${this.defaultSchemaTab}"
88
+ schema-expand-level = "${this.schemaExpandLevel}"
89
+ schema-description-expanded = "${this.schemaDescriptionExpanded}"
90
+ allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}"
91
+ schema-hide-read-only = "${path.isWebhook ? false : this.schemaHideReadOnly}"
92
+ schema-hide-write-only = "${path.isWebhook ? this.schemaHideWriteOnly : false}"
93
+ fetch-credentials = "${this.fetchCredentials}"
94
+ exportparts = "btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
95
+ file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
96
+ anchor:anchor, anchor-param-example:anchor-param-example, schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
97
+ > </api-request>
96
98
 
97
- ${path.callbacks ? callbackTemplate.call(this, path.callbacks) : ''}
99
+ ${path.callbacks ? callbackTemplate.call(this, path.callbacks) : ''}
98
100
 
99
- <api-response
100
- class = "${this.renderStyle}-mode"
101
- style = "width:100%;"
102
- .responses = "${path.responses}"
103
- render-style = "${this.renderStyle}"
104
- schema-style = "${this.schemaStyle}"
105
- active-schema-tab = "${this.defaultSchemaTab}"
106
- schema-expand-level = "${this.schemaExpandLevel}"
107
- schema-description-expanded = "${this.schemaDescriptionExpanded}"
108
- allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}"
109
- schema-hide-write-only = "${this.schemaHideWriteOnly}"
110
- selected-status = "${Object.keys(path.responses || {})[0] || ''}"
111
- exportparts = "btn:btn, btn-response-status:btn-response-status, btn-selected-response-status:btn-selected-response-status, btn-fill:btn-fill, btn-copy:btn-copy"
112
- > </api-response>
101
+ <api-response
102
+ class = "${this.renderStyle}-mode"
103
+ style = "width:100%;"
104
+ .responses = "${path.responses}"
105
+ render-style = "${this.renderStyle}"
106
+ schema-style = "${this.schemaStyle}"
107
+ active-schema-tab = "${this.defaultSchemaTab}"
108
+ schema-expand-level = "${this.schemaExpandLevel}"
109
+ schema-description-expanded = "${this.schemaDescriptionExpanded}"
110
+ allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}"
111
+ schema-hide-read-only = "${path.isWebhook ? this.schemaHideReadOnly : false}"
112
+ schema-hide-write-only = "${path.isWebhook ? false : this.schemaHideWriteOnly}"
113
+ selected-status = "${Object.keys(path.responses || {})[0] || ''}"
114
+ exportparts = "btn:btn, btn-response-status:btn-response-status, btn-selected-response-status:btn-selected-response-status, btn-fill:btn-fill, btn-copy:btn-copy,
115
+ schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
116
+ > </api-response>
117
+ </div>
113
118
  </div>
114
- </div>
115
119
  `;
116
120
  }
117
121
 
@@ -120,7 +124,7 @@ export default function expandedEndpointTemplate() {
120
124
  return html`
121
125
  ${this.resolvedSpec.tags.map((tag) => html`
122
126
  <section id="${tag.elementId}" part="section-tag" class="regular-font section-gap--read-mode observe-me" style="border-top:1px solid var(--primary-color);">
123
- <div class="title tag" part="label-tag-title">${tag.name}</div>
127
+ <div class="title tag" part="section-tag-title label-tag-title">${tag.name}</div>
124
128
  <slot name="${tag.elementId}"></slot>
125
129
  <div class="regular-font-size">
126
130
  ${
@@ -4,7 +4,7 @@ import logoTemplate from '~/templates/logo-template';
4
4
  /* eslint-disable indent */
5
5
  export default function headerTemplate() {
6
6
  return html`
7
- <header class="row header regular-font" part="section-header" style="padding:8px 4px 8px 4px;min-height:48px;">
7
+ <header class="row main-header regular-font" part="section-header" style="padding:8px 4px 8px 4px;min-height:48px;">
8
8
  <div class="only-large-screen-flex" style="align-items: center;">
9
9
  <slot name="logo" class="logo" part="section-logo">
10
10
  ${logoTemplate('height:36px;width:36px;margin-left:5px')}
@@ -154,7 +154,7 @@ export default function jsonSchemaViewerTemplate(isMini = false) {
154
154
  <!-- Header -->
155
155
  ${this.showHeader === 'false' ? '' : headerTemplate.call(this)}
156
156
 
157
- <div id='the-main-body' class="body" dir= ${this.pageDirection}>
157
+ <div id='the-main-body' class="body ${this.cssClasses}" dir= ${this.pageDirection}>
158
158
 
159
159
  <!-- Side Nav -->
160
160
  ${jsonSchemaNavTemplate.call(this)}
@@ -73,7 +73,7 @@ export default function mainBodyTemplate(isMini = false, showExpandCollapse = tr
73
73
  <!-- Advanced Search -->
74
74
  ${this.allowAdvancedSearch === 'false' ? '' : advancedSearchTemplate.call(this)}
75
75
 
76
- <div id='the-main-body' class="body" dir= ${this.pageDirection}>
76
+ <div id='the-main-body' class="body ${this.cssClasses}" dir= ${this.pageDirection} >
77
77
  <!-- Side Nav -->
78
78
  ${((this.renderStyle === 'read' || this.renderStyle === 'focused')
79
79
  && this.showSideNav === 'true'
@@ -50,7 +50,7 @@ export default function navbarTemplate() {
50
50
  ${(this.allowSearch === 'false' && this.allowAdvancedSearch === 'false')
51
51
  ? ''
52
52
  : html`
53
- <div style="display:flex; flex-direction:row; justify-content:center; align-items:center; padding:8px 24px 12px 24px; ${this.allowAdvancedSearch === 'false' ? 'border-bottom: 1px solid var(--nav-hover-bg-color)' : ''}">
53
+ <div style="display:flex; flex-direction:row; justify-content:center; align-items:stretch; padding:8px 24px 12px 24px; ${this.allowAdvancedSearch === 'false' ? 'border-bottom: 1px solid var(--nav-hover-bg-color)' : ''}">
54
54
  ${this.allowSearch === 'false'
55
55
  ? ''
56
56
  : html`
@@ -67,7 +67,9 @@ export default function navbarTemplate() {
67
67
  </div>
68
68
  ${this.matchPaths
69
69
  ? html`
70
- <div @click = '${this.onClearSearch}' style='margin-left:5px; cursor:pointer; align-self:center; color:var(--nav-text-color)' class='small-font-size primary-text bold-text'> CLEAR </div>`
70
+ <button @click = '${this.onClearSearch}' class="m-btn thin-border" style="margin-left:5px; color:var(--nav-text-color); width:75px; padding:6px 8px;" part="btn btn-outline btn-clear-filter">
71
+ CLEAR
72
+ </button>`
71
73
  : ''
72
74
  }
73
75
  `
@@ -75,8 +77,8 @@ export default function navbarTemplate() {
75
77
  ${this.allowAdvancedSearch === 'false' || this.matchPaths
76
78
  ? ''
77
79
  : html`
78
- <button class="m-btn primary" part="btn btn-fill btn-search" style="margin-left:5px;" @click="${this.onShowSearchModalClicked}">
79
- Search
80
+ <button class="m-btn primary" part="btn btn-fill btn-search" style="margin-left:5px; padding:6px 8px; width:75px" @click="${this.onShowSearchModalClicked}">
81
+ SEARCH
80
82
  </button>
81
83
  `
82
84
  }
@@ -89,7 +91,12 @@ export default function navbarTemplate() {
89
91
  : html`
90
92
  ${(this.infoDescriptionHeadingsInNavBar === 'true')
91
93
  ? html`
92
- ${this.resolvedSpec.infoDescriptionHeaders.length > 0 ? html`<div class='nav-bar-info' id='link-overview' data-content-id='overview' @click = '${(e) => this.scrollToEventTarget(e, false)}' > Overview </div>` : ''}
94
+ ${this.resolvedSpec.infoDescriptionHeaders.length > 0
95
+ ? html`<div class='nav-bar-info' id='link-overview' data-content-id='overview' @click = '${(e) => this.scrollToEventTarget(e, false)}'>
96
+ ${this.resolvedSpec.info?.title?.trim() || 'Overview'}
97
+ </div>`
98
+ : ''
99
+ }
93
100
  <div class="overview-headers">
94
101
  ${this.resolvedSpec.infoDescriptionHeaders.map((header) => html`
95
102
  <div
@@ -104,7 +111,9 @@ export default function navbarTemplate() {
104
111
  </div>
105
112
  ${this.resolvedSpec.infoDescriptionHeaders.length > 0 ? html`<hr style='border-top: 1px solid var(--nav-hover-bg-color); border-width:1px 0 0 0; margin: 15px 0 0 0'/>` : ''}
106
113
  `
107
- : html`<div class='nav-bar-info' id='link-overview' data-content-id='overview' @click = '${(e) => this.scrollToEventTarget(e, false)}'> Overview </div>`
114
+ : html`<div class='nav-bar-info' id='link-overview' data-content-id='overview' @click = '${(e) => this.scrollToEventTarget(e, false)}'>
115
+ ${this.resolvedSpec.info?.title?.trim() || 'Overview'}
116
+ </div>`
108
117
  }
109
118
  `
110
119
  }
@@ -197,10 +206,14 @@ export default function navbarTemplate() {
197
206
  this.scrollToEventTarget(e, false);
198
207
  }}'
199
208
  >
200
- <span style = "${p.deprecated ? 'filter:opacity(0.5)' : ''}">
209
+ <span style = "display:flex; align-items:start; ${p.deprecated ? 'filter:opacity(0.5)' : ''}">
210
+ ${html`<span class="nav-method ${this.showMethodInNavBar} ${p.method}">
211
+ ${this.showMethodInNavBar === 'as-colored-block' ? p.method.substring(0, 3).toUpperCase() : p.method.toUpperCase()}
212
+ </span>`
213
+ }
201
214
  ${p.isWebhook ? html`<span style="font-weight:bold; margin-right:8px; font-size: calc(var(--font-size-small) - 2px)">WEBHOOK</span>` : ''}
202
215
  ${this.usePathInNavBar === 'true'
203
- ? html`<span class='mono-font'>${p.method.toUpperCase()} ${p.path}</span>`
216
+ ? html`<span class='mono-font'>${p.path}</span>`
204
217
  : p.summary || p.shortSummary
205
218
  }
206
219
  </span>
@@ -16,7 +16,7 @@ export default function overviewTemplate() {
16
16
  class="observe-me ${this.renderStyle === 'view' ? 'section-gap' : 'section-gap--read-mode'}">
17
17
  ${this.resolvedSpec?.info
18
18
  ? html`
19
- <div id="api-title" part="label-overview-title" style="font-size:32px">
19
+ <div id="api-title" part="section-overview-title" style="font-size:32px">
20
20
  ${this.resolvedSpec.info.title}
21
21
  ${!this.resolvedSpec.info.version ? '' : html`
22
22
  <span style = 'font-size:var(--font-size-small);font-weight:bold'>
@@ -252,7 +252,7 @@ async function onInvokeOAuthFlow(securitySchemeId, flowType, authUrl, tokenUrl,
252
252
 
253
253
  /* eslint-disable indent */
254
254
 
255
- function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow, defaultScopes = []) {
255
+ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow, defaultScopes = [], receiveTokenIn = 'header') {
256
256
  let { authorizationUrl, tokenUrl, refreshUrl } = authFlow;
257
257
  const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0);
258
258
  if (refreshUrl && !isUrlAbsolute(refreshUrl)) {
@@ -337,8 +337,8 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
337
337
  ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'password'
338
338
  ? html`
339
339
  <select style="margin-right:5px;" class="${flowName} ${securitySchemeId} oauth-send-client-secret-in">
340
- <option value = 'header' selected> Authorization Header </option>
341
- <option value = 'request-body'> Request Body </option>
340
+ <option value = 'header' .selected = ${receiveTokenIn === 'header'} > Authorization Header </option>
341
+ <option value = 'request-body' .selected = ${receiveTokenIn === 'request-body'}> Request Body </option>
342
342
  </select>`
343
343
  : ''
344
344
  }`
@@ -462,7 +462,7 @@ export default function securitySchemeTemplate() {
462
462
  ? html`
463
463
  <tr>
464
464
  <td style="border:none; padding-left:48px">
465
- ${Object.keys(v.flows).map((f) => oAuthFlowTemplate.call(this, f, v['x-client-id'], v['x-client-secret'], v.securitySchemeId, v.flows[f], v['x-default-scopes']))}
465
+ ${Object.keys(v.flows).map((f) => oAuthFlowTemplate.call(this, f, v['x-client-id'], v['x-client-secret'], v.securitySchemeId, v.flows[f], v['x-default-scopes'], v['x-receive-token-in']))}
466
466
  </td>
467
467
  </tr>
468
468
  `
@@ -483,21 +483,28 @@ export function pathSecurityTemplate(pathSecurity) {
483
483
  pathSecurity.forEach((pSecurity) => {
484
484
  const andSecurityKeys1 = [];
485
485
  const andKeyTypes = [];
486
- Object.keys(pSecurity).forEach((pathSecurityKey) => {
487
- let pathScopes = '';
488
- const s = this.resolvedSpec.securitySchemes.find((ss) => ss.securitySchemeId === pathSecurityKey);
489
- if (pSecurity[pathSecurityKey] && Array.isArray(pSecurity[pathSecurityKey])) {
490
- pathScopes = pSecurity[pathSecurityKey].join(', ');
491
- }
492
- if (s) {
493
- andKeyTypes.push(s.typeDisplay);
494
- andSecurityKeys1.push({ ...s, ...({ scopes: pathScopes }) });
495
- }
496
- });
497
- orSecurityKeys1.push({
498
- securityTypes: andKeyTypes.length > 1 ? `${andKeyTypes[0]} + ${andKeyTypes.length - 1} more` : andKeyTypes[0],
499
- securityDefs: andSecurityKeys1,
500
- });
486
+ if (Object.keys(pSecurity).length === 0) {
487
+ orSecurityKeys1.push({
488
+ securityTypes: 'None',
489
+ securityDefs: [],
490
+ });
491
+ } else {
492
+ Object.keys(pSecurity).forEach((pathSecurityKey) => {
493
+ let pathScopes = '';
494
+ const s = this.resolvedSpec.securitySchemes.find((ss) => ss.securitySchemeId === pathSecurityKey);
495
+ if (pSecurity[pathSecurityKey] && Array.isArray(pSecurity[pathSecurityKey])) {
496
+ pathScopes = pSecurity[pathSecurityKey].join(', ');
497
+ }
498
+ if (s) {
499
+ andKeyTypes.push(s.typeDisplay);
500
+ andSecurityKeys1.push({ ...s, ...({ scopes: pathScopes }) });
501
+ }
502
+ });
503
+ orSecurityKeys1.push({
504
+ securityTypes: andKeyTypes.length > 1 ? `${andKeyTypes[0]} + ${andKeyTypes.length - 1} more` : andKeyTypes[0],
505
+ securityDefs: andSecurityKeys1,
506
+ });
507
+ }
501
508
  });
502
509
  return html`<div style="position:absolute; top:3px; right:2px; font-size:var(--font-size-small); line-height: 1.5;">
503
510
  <div style="position:relative; display:flex; min-width:350px; max-width:700px; justify-content: flex-end;">
@@ -513,7 +520,10 @@ export function pathSecurityTemplate(pathSecurity) {
513
520
  ${i !== 0 ? html`<div style="padding:3px 4px;"> OR </div>` : ''}
514
521
  <div class="tooltip">
515
522
  <div style = "padding:2px 4px; white-space:nowrap; text-overflow:ellipsis;max-width:150px; overflow:hidden;">
516
- <a part="anchor anchor-operation-security" href="#auth"> ${orSecurityItem1.securityTypes} </a>
523
+ ${this.updateRoute === 'true' && this.allowAuthentication === 'true'
524
+ ? html`<a part="anchor anchor-operation-security" href="#auth"> ${orSecurityItem1.securityTypes} </a>`
525
+ : html`${orSecurityItem1.securityTypes}`
526
+ }
517
527
  </div>
518
528
  <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;">
519
529
  ${orSecurityItem1.securityDefs.length > 1 ? html`<div>Requires <b>all</b> of the following </div>` : ''}
@@ -35,7 +35,7 @@ function serverVarsTemplate() {
35
35
  // const selectedServerObj = this.resolvedSpec.servers.find((v) => (v.url === this.selectedServer));
36
36
  return this.selectedServer && this.selectedServer.variables
37
37
  ? html`
38
- <div class="table-title"> SERVER VARIABLES</div>
38
+ <div class="table-title">SERVER VARIABLES</div>
39
39
  <table class='m-table'>
40
40
  ${Object.entries(this.selectedServer.variables).map((kv) => html`
41
41
  <tr>
@@ -86,7 +86,7 @@ export default function serverTemplate() {
86
86
  if (!this.resolvedSpec || this.resolvedSpec.specLoadError) { return ''; }
87
87
  return html`
88
88
  <section id = 'servers' part="section-servers" style="text-align:left; direction:ltr; margin-top:24px; margin-bottom:24px;" class='regular-font observe-me ${'read focused'.includes(this.renderStyle) ? 'section-gap--read-mode' : 'section-gap'}'>
89
- <div class = 'sub-title'>API SERVER</div>
89
+ <div part = "section-servers-title" class = "sub-title">API SERVER</div>
90
90
  <div class = 'mono-font' style='margin: 12px 0; font-size:calc(var(--font-size-small) + 1px);'>
91
91
  ${!this.resolvedSpec.servers || this.resolvedSpec.servers?.length === 0
92
92
  ? ''
@@ -12,7 +12,7 @@ export function getTypeInfo(schema) {
12
12
  const schemaNode = schema.$ref.substring(n + 1);
13
13
  dataType = `{recursive: ${schemaNode}} `;
14
14
  } else if (schema.type) {
15
- dataType = Array.isArray(schema.type) ? schema.type.join('┃') : schema.type;
15
+ dataType = Array.isArray(schema.type) ? schema.type.join(schema.length === 2 ? ' or ' : '┃') : schema.type;
16
16
  if (schema.format || schema.enum) {
17
17
  dataType = dataType.replace('string', schema.enum ? 'enum' : schema.format);
18
18
  }
@@ -389,12 +389,20 @@ export function schemaToSampleObj(schema, config = { }) {
389
389
  const oneOfSamples = schemaToSampleObj(schema.oneOf[key], config);
390
390
  for (const sampleKey in oneOfSamples) {
391
391
  // 2. In the final example include a one-of item along with properties
392
- if (oneOfSamples[sampleKey] === null) {
393
- const finalExample = Object.assign(oneOfSamples[sampleKey], objWithSchemaProps);
394
- obj[`example-${i}`] = finalExample;
395
- addSchemaInfoToExample(schema.oneOf[key], obj[`example-${i}`]);
396
- i++;
392
+ let finalExample;
393
+ if (Object.keys(objWithSchemaProps).length > 0) {
394
+ if (oneOfSamples[sampleKey] === null || typeof oneOfSamples[sampleKey] !== 'object') {
395
+ // This doesn't really make sense since every oneOf schema _should_ be an object if there are common properties, so we'll skip this
396
+ continue;
397
+ } else {
398
+ finalExample = Object.assign(oneOfSamples[sampleKey], objWithSchemaProps);
399
+ }
400
+ } else {
401
+ finalExample = oneOfSamples[sampleKey];
397
402
  }
403
+ obj[`example-${i}`] = finalExample;
404
+ addSchemaInfoToExample(schema.oneOf[key], obj[`example-${i}`]);
405
+ i++;
398
406
  }
399
407
  }
400
408
  }
@@ -460,18 +468,22 @@ export function schemaToSampleObj(schema, config = { }) {
460
468
  }
461
469
  }
462
470
  } else if (schema.type === 'array' || schema.items) {
463
- if (schema.example) {
464
- obj['example-0'] = schema.example;
465
- } else if (schema.items?.example) { // schemas and properties support single example but not multiple examples.
466
- obj['example-0'] = [schema.items.example];
467
- } else {
468
- const samples = schemaToSampleObj(schema.items, config);
469
- let i = 0;
470
- for (const key in samples) {
471
- obj[`example-${i}`] = [samples[key]];
472
- addSchemaInfoToExample(schema.items, obj[`example-${i}`]);
473
- i++;
471
+ if (schema.items || schema.example) {
472
+ if (schema.example) {
473
+ obj['example-0'] = schema.example;
474
+ } else if (schema.items?.example) { // schemas and properties support single example but not multiple examples.
475
+ obj['example-0'] = [schema.items.example];
476
+ } else {
477
+ const samples = schemaToSampleObj(schema.items, config);
478
+ let i = 0;
479
+ for (const key in samples) {
480
+ obj[`example-${i}`] = [samples[key]];
481
+ addSchemaInfoToExample(schema.items, obj[`example-${i}`]);
482
+ i++;
483
+ }
474
484
  }
485
+ } else {
486
+ obj['example-0'] = [];
475
487
  }
476
488
  } else {
477
489
  return { 'example-0': getSampleValueByType(schema) };
@@ -484,15 +496,15 @@ function generateMarkdownForArrayAndObjectDescription(schema, level = 0) {
484
496
  if (schema.title) {
485
497
  markdown = `**${schema.title}:** `;
486
498
  }
499
+ if (schema.description) {
500
+ markdown = `${markdown} ${schema.description} ${schema.minItems || schema.maxItems ? '<span class="more-content">⤵</span><br/>' : ''}`;
501
+ }
487
502
  if (schema.minItems) {
488
503
  markdown = `${markdown} **Min Items:** ${schema.minItems}`;
489
504
  }
490
505
  if (schema.maxItems) {
491
506
  markdown = `${markdown} **Max Items:** ${schema.maxItems}`;
492
507
  }
493
- if (schema.description) {
494
- markdown = `${markdown} ${schema.description}`;
495
- }
496
508
  if (level > 0 && schema.items?.description) {
497
509
  let itemsMarkdown = '';
498
510
  if (schema.items.minProperties) {
@@ -600,7 +612,7 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') {
600
612
  });
601
613
  let multiPrimitiveTypes;
602
614
  if (primitiveType.length > 0) {
603
- subSchema.type = primitiveType.join('┃');
615
+ subSchema.type = primitiveType.join(primitiveType.length === 2 ? ' or ' : '┃');
604
616
  multiPrimitiveTypes = getTypeInfo(subSchema);
605
617
  if (complexTypes.length === 0) {
606
618
  return `${multiPrimitiveTypes?.html || ''}`;
@@ -670,7 +682,7 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') {
670
682
  obj['::type'] = 'array';
671
683
  obj['::deprecated'] = schema.deprecated || false;
672
684
  obj['::readwrite'] = schema.readOnly ? 'readonly' : schema.writeOnly ? 'writeonly' : '';
673
- if (schema.items.items) {
685
+ if (schema.items?.items) {
674
686
  obj['::array-type'] = schema.items.items.type;
675
687
  }
676
688
  obj['::props'] = schemaInObjectNotation(schema.items, {}, (level + 1));
@@ -106,7 +106,7 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
106
106
  } else if (v.type === 'oauth2') {
107
107
  v.typeDisplay = `OAuth (${v.securitySchemeId})`;
108
108
  } else {
109
- v.typeDisplay = v.type;
109
+ v.typeDisplay = v.type || 'None';
110
110
  }
111
111
  });
112
112
 
@@ -11,7 +11,7 @@ export default function setTheme(baseTheme, theme = {}) {
11
11
 
12
12
  // Dark and Light Theme colors
13
13
  if (baseTheme === 'dark') {
14
- const bg1 = theme.bg1 ? theme.bg1 : '#333';
14
+ const bg1 = theme.bg1 ? theme.bg1 : '#2a2b2c';
15
15
  const fg1 = theme.fg1 ? theme.fg1 : '#bbb';
16
16
 
17
17
  const bg2 = theme.bg2 ? theme.bg2 : ColorUtils.color.brightness(bg1, 5); // or #383838;
@@ -27,7 +27,7 @@ export default function setTheme(baseTheme, theme = {}) {
27
27
  const headerColor = theme.headerColor ? theme.headerColor : ColorUtils.color.brightness(bg1, 10);
28
28
 
29
29
  const navBgColor = theme.navBgColor ? theme.navBgColor : ColorUtils.color.brightness(bg1, 10);
30
- const navTextColor = theme.navTextColor ? theme.navTextColor : ColorUtils.color.opacity(ColorUtils.color.invert(navBgColor), '0.65');
30
+ const navTextColor = theme.navTextColor ? theme.navTextColor : ColorUtils.color.opacity(ColorUtils.color.invert(navBgColor), '0.50');
31
31
  const navHoverBgColor = theme.navHoverBgColor ? theme.navHoverBgColor : ColorUtils.color.brightness(navBgColor, -15);
32
32
  const navHoverTextColor = theme.navHoverTextColor ? theme.navHoverTextColor : ColorUtils.color.invert(navBgColor);
33
33
  const navAccentColor = theme.navAccentColor ? theme.navAccentColor : ColorUtils.color.brightness(primaryColor, 25);
@@ -96,7 +96,7 @@ export default function setTheme(baseTheme, theme = {}) {
96
96
  codeOperatorColor: theme.codeOperatorColor || '#67cdcc',
97
97
  };
98
98
  } else {
99
- const bg1 = (theme.bg1 ? theme.bg1 : '#ffffff');
99
+ const bg1 = (theme.bg1 ? theme.bg1 : '#fafbfc');
100
100
  const fg1 = (theme.fg1 ? theme.fg1 : '#444444');
101
101
  const bg2 = theme.bg2 ? theme.bg2 : ColorUtils.color.brightness(bg1, -5); // or '#fafafa'
102
102
  const bg3 = theme.bg3 ? theme.bg3 : ColorUtils.color.brightness(bg1, -15); // or '#f6f6f6'
@@ -118,7 +118,7 @@ export default function setTheme(baseTheme, theme = {}) {
118
118
  const navHoverTextColor = theme.navHoverTextColor ? theme.navHoverTextColor : primaryColor;
119
119
  const navAccentColor = theme.navAccentColor ? theme.navAccentColor : primaryColor;
120
120
  */
121
- const navBgColor = theme.navBgColor ? theme.navBgColor : ColorUtils.color.brightness(bg1, -180);
121
+ const navBgColor = theme.navBgColor ? theme.navBgColor : ColorUtils.color.brightness(bg1, -200);
122
122
  const navTextColor = theme.navTextColor ? theme.navTextColor : ColorUtils.color.opacity(ColorUtils.color.invert(navBgColor), '0.65');
123
123
  const navHoverBgColor = theme.navHoverBgColor ? theme.navHoverBgColor : ColorUtils.color.brightness(navBgColor, -15);
124
124
  const navHoverTextColor = theme.navHoverTextColor ? theme.navHoverTextColor : ColorUtils.color.invert(navBgColor);
@@ -260,6 +260,13 @@ export default function setTheme(baseTheme, theme = {}) {
260
260
  --nav-hover-text-color:${newTheme.navHoverTextColor};
261
261
  --nav-accent-color:${newTheme.navAccentColor};
262
262
 
263
+ /* Nav API Method Colors*/
264
+ --nav-get-color:${newTheme.blue};
265
+ --nav-put-color:${newTheme.orange};
266
+ --nav-post-color:${newTheme.green};
267
+ --nav-delete-color:${newTheme.red};
268
+ --nav-head-color:${newTheme.yellow};
269
+
263
270
  /* Primary Colors */
264
271
  --primary-color:${newTheme.primaryColor};
265
272
  --primary-color-invert:${newTheme.primaryColorInvert};
package/webpack.config.js CHANGED
@@ -29,7 +29,7 @@ const rapidocBanner = `
29
29
  * @preserve
30
30
  * RapiDoc ${rapidocVersion.replace()} - WebComponent to View OpenAPI docs
31
31
  * License: MIT
32
- * Repo : https://github.com/mrin9/RapiDoc
32
+ * Repo : https://github.com/rapi-doc/RapiDoc
33
33
  * Author : Mrinmoy Majumdar
34
34
  *`;
35
35
 
@@ -1,12 +0,0 @@
1
- {
2
- "cSpell.ignoreWords": [
3
- "doc",
4
- "gtag",
5
- "rapi"
6
- ],
7
- "cSpell.words": [
8
- "descr",
9
- "prismjs",
10
- "webcomponent"
11
- ]
12
- }
package/dist/index.html DELETED
@@ -1,6 +0,0 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,user-scalable=yes"><title>RapiDoc</title><link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.1/build/styles/default.min.css"><script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.1/build/highlight.min.js"></script><script defer="defer" src="rapidoc-min.js"></script></head><script>window.addEventListener('DOMContentLoaded', (event) => {
2
- const docEl = document.getElementById('thedoc');
3
- docEl.addEventListener('before-try', (e) => {
4
- e.detail.request.headers.append('AAA-BBB', 'CCC DDDD');
5
- });
6
- });</script><body><rapi-doc spec-url="./specs/aaa.yaml" id="thedoc" theme="dark" render-style="read" schema-style="tree" use-path-in-nav-bar="true" show-components="true" show-info="true" show-header="true" allow-search="false" allow-advanced-search="true" allow-spec-url-load="false" allow-spec-file-load="false" allow-spec-file-download="true" allow-server-selection="true" allow-authentication="true" update-route="false" match-type="regex" persist-auth="true"></rapi-doc></body></html>
Binary file