rapidoc 9.1.0 → 9.1.4

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 (67) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/index.html.gz +0 -0
  3. package/dist/rapidoc-min.js +2 -5
  4. package/dist/rapidoc-min.js.LICENSE.txt +17 -1
  5. package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
  6. package/dist/rapidoc-min.js.gz +0 -0
  7. package/dist/report.html +6 -5
  8. package/docker/Dockerfile +5 -5
  9. package/docs/api.html +48 -40
  10. package/docs/examples/auth-test1.html +113 -0
  11. package/docs/examples/auth.html +37 -34
  12. package/docs/examples/badges.html +1 -1
  13. package/docs/examples/dynamic-query-params.html +1 -0
  14. package/docs/examples/mongo.html +33 -0
  15. package/docs/examples/readwrite.html +40 -0
  16. package/docs/examples/slots.html +7 -0
  17. package/docs/examples.html +3 -2
  18. package/docs/index.html +2 -2
  19. package/docs/list.html +15 -3
  20. package/docs/quickstart.html +1 -1
  21. package/docs/rapidoc-min.js +2 -5
  22. package/docs/rapidoc-mini.html +20 -20
  23. package/docs/specs/auth-test1.yaml +35 -0
  24. package/docs/specs/auth.yaml +2 -2
  25. package/docs/specs/code-highlight.yaml +1 -1
  26. package/docs/specs/data-types.yaml +0 -1
  27. package/docs/specs/dynamic-query-params.yaml +41 -0
  28. package/docs/specs/examples.yaml +11 -0
  29. package/docs/specs/mongo.yaml +78 -0
  30. package/docs/specs/multipart-formdata.yaml +3 -0
  31. package/docs/specs/petstore_extended.yaml +1 -1
  32. package/docs/specs/readwrite.yaml +90 -0
  33. package/docs/specs/server.yaml +4 -4
  34. package/docs/specs/temp.json +24 -105
  35. package/docs/specs/temp.yaml +20 -282
  36. package/docs/welcome.html +3 -3
  37. package/index.html +11 -6
  38. package/package.json +22 -21
  39. package/src/components/api-request.js +105 -63
  40. package/src/components/api-response.js +10 -10
  41. package/src/components/json-tree.js +2 -1
  42. package/src/components/schema-table.js +51 -14
  43. package/src/components/schema-tree.js +59 -18
  44. package/src/components/tag-input.js +8 -1
  45. package/src/index.js +2 -1
  46. package/src/json-schema-viewer.js +341 -0
  47. package/src/rapidoc-mini.js +5 -1
  48. package/src/rapidoc.js +11 -7
  49. package/src/styles/font-styles.js +3 -2
  50. package/src/styles/nav-styles.js +2 -2
  51. package/src/templates/components-template.js +9 -10
  52. package/src/templates/endpoint-template.js +1 -1
  53. package/src/templates/expanded-endpoint-template.js +1 -1
  54. package/src/templates/focused-endpoint-template.js +1 -1
  55. package/src/templates/header-template.js +1 -1
  56. package/src/templates/json-schema-viewer-template.js +184 -0
  57. package/src/templates/main-body-template.js +4 -1
  58. package/src/templates/navbar-template.js +3 -3
  59. package/src/templates/overview-template.js +6 -3
  60. package/src/templates/security-scheme-template.js +78 -38
  61. package/src/templates/server-template.js +1 -1
  62. package/src/utils/common-utils.js +2 -1
  63. package/src/utils/schema-utils.js +24 -19
  64. package/src/utils/spec-parser.js +24 -3
  65. package/webpack.config.js +1 -12
  66. package/dist/rapidoc-min.js.map +0 -1
  67. package/dist/rapidoc-min.js.map.gz +0 -0
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import marked from 'marked';
2
+ import { marked } from 'marked';
3
3
  import { unsafeHTML } from 'lit-html/directives/unsafe-html';
4
4
  import FontStyles from '~/styles/font-styles';
5
5
  import SchemaStyles from '~/styles/schema-styles';
@@ -123,11 +123,31 @@ export default class SchemaTable extends LitElement {
123
123
  `;
124
124
  }
125
125
 
126
- generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0) {
126
+ generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0, readOrWrite = '') {
127
+ if (this.schemaHideReadOnly === 'true') {
128
+ if (dataType === 'array') {
129
+ if (readOrWrite === 'readonly') {
130
+ return;
131
+ }
132
+ }
133
+ if (data['::readwrite'] === 'readonly') {
134
+ return;
135
+ }
136
+ }
137
+ if (this.schemaHideWriteOnly === 'true') {
138
+ if (dataType === 'array') {
139
+ if (readOrWrite === 'writeonly') {
140
+ return;
141
+ }
142
+ }
143
+ if (data['::readwrite'] === 'writeonly') {
144
+ return;
145
+ }
146
+ }
147
+
127
148
  const newSchemaLevel = data['::type']?.startsWith('xxx-of') ? schemaLevel : (schemaLevel + 1);
128
149
  const newIndentLevel = dataType === 'xxx-of-option' || data['::type'] === 'xxx-of-option' || key.startsWith('::OPTION') ? indentLevel : (indentLevel + 1);
129
150
  const leftPadding = 16 * newIndentLevel; // 2 space indentation at each level
130
-
131
151
  if (!data) {
132
152
  return html`<div class="null" style="display:inline;">null</div>`;
133
153
  }
@@ -189,7 +209,10 @@ export default class SchemaTable extends LitElement {
189
209
  }
190
210
  ${data['::type'] === 'xxx-of' && dataType === 'array' ? html`<span style="color:var(--primary-color)">ARRAY</span>` : ''}
191
211
  </div>
192
- <div class='td key-type'>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div>
212
+ <div class='td key-type' title="${data['::readwrite'] === 'readonly' ? 'Read-Only' : data['::readwrite'] === 'writeonly' ? 'Write-Only' : ''}">
213
+ ${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}
214
+ ${data['::readwrite'] === 'readonly' ? ' 🆁' : data['::readwrite'] === 'writeonly' ? ' 🆆' : ''}
215
+ </div>
193
216
  <div class='td key-descr m-markdown-small' style='line-height:1.7'>${unsafeHTML(marked(description || ''))}</div>
194
217
  </div>`
195
218
  : html`
@@ -197,7 +220,9 @@ export default class SchemaTable extends LitElement {
197
220
  ? html`
198
221
  <div class='tr'>
199
222
  <div class='td key'></div>
200
- <div class='td key-type'> ${arrayType && arrayType !== 'object' ? `${dataType} of ${arrayType}` : dataType}</div>
223
+ <div class='td key-type'>
224
+ ${arrayType && arrayType !== 'object' ? `${dataType} of ${arrayType}` : dataType}
225
+ </div>
201
226
  <div class='td key-descr'></div>
202
227
  </div>`
203
228
  : ''
@@ -206,10 +231,10 @@ export default class SchemaTable extends LitElement {
206
231
  }
207
232
  <div class='object-body'>
208
233
  ${Array.isArray(data) && data[0]
209
- ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel)}`
234
+ ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, '')}`
210
235
  : html`
211
236
  ${Object.keys(data).map((dataKey) => html`
212
- ${['::description', '::type', '::props', '::deprecated', '::array-type'].includes(dataKey)
237
+ ${['::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey)
213
238
  ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object'
214
239
  ? html`${this.generateTree(
215
240
  data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
@@ -219,6 +244,7 @@ export default class SchemaTable extends LitElement {
219
244
  data[dataKey]['::description'],
220
245
  newSchemaLevel,
221
246
  newIndentLevel,
247
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
222
248
  )}`
223
249
  : ''
224
250
  : html`${this.generateTree(
@@ -229,6 +255,7 @@ export default class SchemaTable extends LitElement {
229
255
  data[dataKey]['::description'],
230
256
  newSchemaLevel,
231
257
  newIndentLevel,
258
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
232
259
  )}`
233
260
  }
234
261
  `)}
@@ -239,17 +266,29 @@ export default class SchemaTable extends LitElement {
239
266
  }
240
267
 
241
268
  // For Primitive Data types
242
- const [type, readorWriteOnly, constraint, defaultValue, allowedValues, pattern, schemaDescription, schemaTitle, deprecated] = data.split('~|~');
243
- if (readorWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
269
+ const [type, readOrWriteOnly, constraint, defaultValue, allowedValues, pattern, schemaDescription, schemaTitle, deprecated] = data.split('~|~');
270
+ if (readOrWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
244
271
  return;
245
272
  }
246
- if (readorWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
273
+ if (readOrWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
247
274
  return;
248
275
  }
249
276
  const dataTypeCss = type.replace(/┃.*/g, '').replace(/[^a-zA-Z0-9+]/g, '').substring(0, 4).toLowerCase();
277
+ let dataTypeHtml = '';
278
+ if (dataType === 'array') {
279
+ dataTypeHtml = html`
280
+ <div class='td key-type ${dataTypeCss}' title="${readOrWrite === 'readonly' ? 'Read-Only' : readOrWriteOnly === 'writeonly' ? 'Write-Only' : ''}">
281
+ [${type}] ${readOrWrite === 'readonly' ? '🆁' : readOrWrite === 'writeonly' ? '🆆' : ''}
282
+ </div>`;
283
+ } else {
284
+ dataTypeHtml = html`
285
+ <div class='td key-type ${dataTypeCss}' title="${readOrWriteOnly === '🆁' ? 'Read-Only' : readOrWriteOnly === '🆆' ? 'Write-Only' : ''}">
286
+ ${type} ${readOrWriteOnly}
287
+ </div>`;
288
+ }
250
289
  return html`
251
290
  <div class = "tr primitive">
252
- <div class="td key ${deprecated}" style='padding-left:${leftPadding}px' >
291
+ <div class="td key ${deprecated}" style='padding-left:${leftPadding}px'>
253
292
  ${keyLabel?.endsWith('*')
254
293
  ? html`<span class="key-label">${keyLabel.substring(0, keyLabel.length - 1)}</span><span style='color:var(--red);'>*</span>`
255
294
  : key.startsWith('::OPTION')
@@ -257,9 +296,7 @@ export default class SchemaTable extends LitElement {
257
296
  : html`${keyLabel ? html`<span class="key-label"> ${keyLabel}</span>` : html`<span class="xxx-of-descr">${schemaTitle}</span>`}`
258
297
  }
259
298
  </div>
260
- <div class='td key-type ${dataTypeCss}'>
261
- ${dataType === 'array' ? `[${type}]` : type}
262
- <span style="font-family: var(--font-mono);">${readorWriteOnly} </span> </div>
299
+ ${dataTypeHtml}
263
300
  <div class='td key-descr'>
264
301
  ${dataType === 'array' ? html`<span class="m-markdown-small">${unsafeHTML(marked(description))}</span>` : ''}
265
302
  ${constraint ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Constraints: </span> ${constraint}</div>` : ''}
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import marked from 'marked';
2
+ import { marked } from 'marked';
3
3
  import { unsafeHTML } from 'lit-html/directives/unsafe-html';
4
4
  import FontStyles from '~/styles/font-styles';
5
5
  import SchemaStyles from '~/styles/schema-styles';
@@ -115,7 +115,6 @@ export default class SchemaTree extends LitElement {
115
115
  this.data['::type'] === 'array' ? this.data['::props'] : this.data,
116
116
  this.data['::type'],
117
117
  this.data['::array-type'] || '',
118
-
119
118
  )}`
120
119
  : html`<span class='mono-font' style='color:var(--red)'> Schema not found </span>`
121
120
  }
@@ -123,7 +122,28 @@ export default class SchemaTree extends LitElement {
123
122
  `;
124
123
  }
125
124
 
126
- generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0) {
125
+ generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0, readOrWrite = '') {
126
+ if (this.schemaHideReadOnly === 'true') {
127
+ if (dataType === 'array') {
128
+ if (readOrWrite === 'readonly') {
129
+ return;
130
+ }
131
+ }
132
+ if (data['::readwrite'] === 'readonly') {
133
+ return;
134
+ }
135
+ }
136
+ if (this.schemaHideWriteOnly === 'true') {
137
+ if (dataType === 'array') {
138
+ if (readOrWrite === 'writeonly') {
139
+ return;
140
+ }
141
+ }
142
+ if (data['::readwrite'] === 'writeonly') {
143
+ return;
144
+ }
145
+ }
146
+
127
147
  if (!data) {
128
148
  return html`<div class="null" style="display:inline;">null</div>`;
129
149
  }
@@ -189,13 +209,13 @@ export default class SchemaTree extends LitElement {
189
209
  <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style='min-width:${minFieldColWidth}px'>
190
210
  ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION')
191
211
  ? html`<span class='key-label xxx-of-key'>${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
192
- : keyLabel.endsWith('*')
193
- ? html`<span class="key-label">${keyLabel.substring(0, keyLabel.length - 1)}</span><span style='color:var(--red);'>*</span>`
194
- : keyLabel === '::props' || keyLabel === '::ARRAY~OF'
195
- ? ''
196
- : schemaLevel > 0
197
- ? html`<span class="key-label">${keyLabel}:</span>`
198
- : ''
212
+ : keyLabel === '::props' || keyLabel === '::ARRAY~OF'
213
+ ? ''
214
+ : schemaLevel > 0
215
+ ? html`<span class="key-label" title="${readOrWrite === 'readonly' ? 'Read-Only' : readOrWrite === 'writeonly' ? 'Write-Only' : ''}">
216
+ ${keyLabel.replace(/\*$/, '')}${keyLabel.endsWith('*') ? html`<span style="color:var(--red)">*</span>` : ''}${readOrWrite === 'readonly' ? html` 🆁` : readOrWrite === 'writeonly' ? html` 🆆` : readOrWrite}:
217
+ </span>`
218
+ : ''
199
219
  }
200
220
  ${data['::type'] === 'xxx-of' && dataType === 'array' ? html`<span style="color:var(--primary-color)">ARRAY</span>` : ''}
201
221
  ${openBracket}
@@ -204,10 +224,10 @@ export default class SchemaTree extends LitElement {
204
224
  </div>
205
225
  <div class='inside-bracket ${data['::type'] || 'no-type-info'}' style='padding-left:${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' ? 0 : leftPadding}px;'>
206
226
  ${Array.isArray(data) && data[0]
207
- ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel)}`
227
+ ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, data[0]['::readwrite'])}`
208
228
  : html`
209
229
  ${Object.keys(data).map((dataKey) => html`
210
- ${['::description', '::type', '::props', '::deprecated', '::array-type'].includes(dataKey)
230
+ ${['::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey)
211
231
  ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object'
212
232
  ? html`${this.generateTree(
213
233
  data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
@@ -217,6 +237,7 @@ export default class SchemaTree extends LitElement {
217
237
  data[dataKey]['::description'],
218
238
  newSchemaLevel,
219
239
  newIndentLevel,
240
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
220
241
  )}`
221
242
  : ''
222
243
  : html`${this.generateTree(
@@ -227,6 +248,7 @@ export default class SchemaTree extends LitElement {
227
248
  data[dataKey]['::description'],
228
249
  newSchemaLevel,
229
250
  newIndentLevel,
251
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
230
252
  )}`
231
253
  }
232
254
  `)}
@@ -240,15 +262,34 @@ export default class SchemaTree extends LitElement {
240
262
  `;
241
263
  }
242
264
 
243
- // For Primitive Data types
244
- const [type, readorWriteOnly, constraint, defaultValue, allowedValues, pattern, schemaDescription, , deprecated] = data.split('~|~');
245
- if (readorWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
265
+ // For Primitive types and array of Primitives
266
+ const [type, primitiveReadOrWrite, constraint, defaultValue, allowedValues, pattern, schemaDescription, , deprecated] = data.split('~|~');
267
+ if (primitiveReadOrWrite === '🆁' && this.schemaHideReadOnly === 'true') {
246
268
  return;
247
269
  }
248
- if (readorWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
270
+ if (primitiveReadOrWrite === '🆆' && this.schemaHideWriteOnly === 'true') {
249
271
  return;
250
272
  }
251
273
  const dataTypeCss = type.replace(/┃.*/g, '').replace(/[^a-zA-Z0-9+]/g, '').substring(0, 4).toLowerCase();
274
+
275
+ let finalReadWriteText = '';
276
+ let finalReadWriteTip = '';
277
+ if (dataType === 'array') {
278
+ if (readOrWrite === 'readonly') {
279
+ finalReadWriteText = '🆁';
280
+ finalReadWriteTip = 'Read-Only';
281
+ } else if (readOrWrite === 'writeonly') {
282
+ finalReadWriteText = '🆆';
283
+ finalReadWriteTip = 'Write-Only';
284
+ }
285
+ } else if (primitiveReadOrWrite === '🆁') {
286
+ finalReadWriteText = '🆁';
287
+ finalReadWriteTip = 'Read-Only';
288
+ } else if (primitiveReadOrWrite === '🆆') {
289
+ finalReadWriteText = '🆆';
290
+ finalReadWriteTip = 'Write-Only';
291
+ }
292
+
252
293
  return html`
253
294
  <div class = "tr primitive">
254
295
  <div class="td key ${deprecated}" style='min-width:${minFieldColWidth}px' >
@@ -258,9 +299,9 @@ export default class SchemaTree extends LitElement {
258
299
  ? html`<span class='key-label xxx-of-key'>${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
259
300
  : html`<span class="key-label">${keyLabel}:</span>`
260
301
  }
261
- <span class="${dataTypeCss}" >
302
+ <span class="${dataTypeCss}" title="${finalReadWriteTip}">
262
303
  ${dataType === 'array' ? `[${type}]` : `${type}`}
263
- ${readorWriteOnly}
304
+ ${finalReadWriteText}
264
305
  </span>
265
306
  </div>
266
307
  <div class='td key-descr'>
@@ -38,7 +38,14 @@ export default class TagInput extends LitElement {
38
38
  afterPaste(e) {
39
39
  const clipboardData = e.clipboardData || window.clipboardData;
40
40
  const pastedData = clipboardData.getData('Text');
41
- this.value = pastedData ? pastedData.split(',').filter((v) => v.trim() !== '') : '';
41
+ const pastedArray = pastedData ? pastedData.split(',').filter((v) => v.trim() !== '') : '';
42
+ if (pastedArray) {
43
+ if (Array.isArray(this.value)) {
44
+ this.value = [...this.value, ...pastedArray];
45
+ } else {
46
+ this.value = pastedArray;
47
+ }
48
+ }
42
49
  e.preventDefault();
43
50
  }
44
51
 
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import RapiDoc from '~/rapidoc';
2
2
  import RapiDocMini from '~/rapidoc-mini';
3
3
  import OAuthReceiver from '~/oauth-receiver';
4
+ import JsonSchemaViewer from '~/json-schema-viewer';
4
5
 
5
6
  export default { RapiDoc };
6
- export { RapiDocMini, OAuthReceiver };
7
+ export { RapiDocMini, OAuthReceiver, JsonSchemaViewer };
@@ -0,0 +1,341 @@
1
+ import { css, LitElement } from 'lit-element';
2
+ import { marked } from 'marked';
3
+ import Prism from 'prismjs';
4
+ import 'prismjs/components/prism-css';
5
+ import 'prismjs/components/prism-yaml';
6
+ import 'prismjs/components/prism-go';
7
+ import 'prismjs/components/prism-java';
8
+ import 'prismjs/components/prism-json';
9
+ import 'prismjs/components/prism-bash';
10
+ import 'prismjs/components/prism-python';
11
+ import 'prismjs/components/prism-http';
12
+ import 'prismjs/components/prism-csharp';
13
+
14
+ // Styles
15
+ import FontStyles from '~/styles/font-styles';
16
+ import InputStyles from '~/styles/input-styles';
17
+ import FlexStyles from '~/styles/flex-styles';
18
+ import TableStyles from '~/styles/table-styles';
19
+ import PrismStyles from '~/styles/prism-styles';
20
+ import TabStyles from '~/styles/tab-styles';
21
+ import NavStyles from '~/styles/nav-styles';
22
+ import InfoStyles from '~/styles/info-styles';
23
+
24
+ import EndpointStyles from '~/styles/endpoint-styles';
25
+ import ProcessSpec from '~/utils/spec-parser';
26
+ import jsonSchemaViewerTemplate from '~/templates/json-schema-viewer-template';
27
+
28
+ export default class JsonSchemaViewer extends LitElement {
29
+ constructor() {
30
+ super();
31
+ this.isMini = false;
32
+ this.updateRoute = 'false';
33
+ this.renderStyle = 'focused';
34
+ this.showHeader = 'true';
35
+ this.allowAdvancedSearch = 'false';
36
+ this.selectedExampleForEachSchema = {};
37
+ }
38
+
39
+ static get properties() {
40
+ return {
41
+ // Spec
42
+ specUrl: { type: String, attribute: 'spec-url' },
43
+
44
+ // Schema Styles
45
+ schemaStyle: { type: String, attribute: 'schema-style' },
46
+ schemaExpandLevel: { type: Number, attribute: 'schema-expand-level' },
47
+ schemaDescriptionExpanded: { type: String, attribute: 'schema-description-expanded' },
48
+ allowSchemaDescriptionExpandToggle: { type: String, attribute: 'allow-schema-description-expand-toggle' },
49
+
50
+ // Hide/show Sections
51
+ showHeader: { type: String, attribute: 'show-header' },
52
+ showSideNav: { type: String, attribute: 'show-side-nav' },
53
+ showInfo: { type: String, attribute: 'show-info' },
54
+
55
+ // Allow or restrict features
56
+ allowSpecUrlLoad: { type: String, attribute: 'allow-spec-url-load' },
57
+ allowSpecFileLoad: { type: String, attribute: 'allow-spec-file-load' },
58
+ allowSpecFileDownload: { type: String, attribute: 'allow-spec-file-download' },
59
+ allowSearch: { type: String, attribute: 'allow-search' },
60
+
61
+ // Main Colors and Font
62
+ theme: { type: String },
63
+ bgColor: { type: String, attribute: 'bg-color' },
64
+ textColor: { type: String, attribute: 'text-color' },
65
+ primaryColor: { type: String, attribute: 'primary-color' },
66
+ fontSize: { type: String, attribute: 'font-size' },
67
+ regularFont: { type: String, attribute: 'regular-font' },
68
+ monoFont: { type: String, attribute: 'mono-font' },
69
+ loadFonts: { type: String, attribute: 'load-fonts' },
70
+
71
+ // Internal Properties
72
+ loading: { type: Boolean }, // indicates spec is being loaded
73
+ };
74
+ }
75
+
76
+ static get styles() {
77
+ return [
78
+ FontStyles,
79
+ InputStyles,
80
+ FlexStyles,
81
+ TableStyles,
82
+ EndpointStyles,
83
+ PrismStyles,
84
+ TabStyles,
85
+ NavStyles,
86
+ InfoStyles,
87
+ css`
88
+ :host {
89
+ display:flex;
90
+ flex-direction: column;
91
+ min-width:360px;
92
+ width:100%;
93
+ height:100%;
94
+ margin:0;
95
+ padding:0;
96
+ overflow: hidden;
97
+ letter-spacing:normal;
98
+ color:var(--fg);
99
+ background-color:var(--bg);
100
+ font-family:var(--font-regular);
101
+ }
102
+ .body {
103
+ display:flex;
104
+ height:100%;
105
+ width:100%;
106
+ overflow:hidden;
107
+ }
108
+ .nav-bar {
109
+ width: 230px;
110
+ display:flex;
111
+ }
112
+
113
+ .main-content {
114
+ margin:0;
115
+ padding: 16px;
116
+ display:block;
117
+ flex:1;
118
+ height:100%;
119
+ overflow-y: auto;
120
+ overflow-x: hidden;
121
+ scrollbar-width: thin;
122
+ scrollbar-color: var(--border-color) transparent;
123
+ }
124
+ .main-content-inner--view-mode {
125
+ padding: 0 8px;
126
+ }
127
+ .main-content::-webkit-scrollbar {
128
+ width: 8px;
129
+ height: 8px;
130
+ }
131
+ .main-content::-webkit-scrollbar-track {
132
+ background:transparent;
133
+ }
134
+ .main-content::-webkit-scrollbar-thumb {
135
+ background-color: var(--border-color);
136
+ }
137
+ .header {
138
+ background-color:var(--header-bg);
139
+ color:var(--header-fg);
140
+ width:100%;
141
+ }
142
+ .header-title {
143
+ font-size:calc(var(--font-size-regular) + 8px);
144
+ padding:0 8px;
145
+ }
146
+ input.header-input{
147
+ background:var(--header-color-darker);
148
+ color:var(--header-fg);
149
+ border:1px solid var(--header-color-border);
150
+ flex:1;
151
+ padding-right:24px;
152
+ border-radius:3px;
153
+ }
154
+ input.header-input::placeholder {
155
+ opacity:0.4;
156
+ }
157
+ .loader {
158
+ margin: 16px auto 16px auto;
159
+ border: 4px solid var(--bg3);
160
+ border-radius: 50%;
161
+ border-top: 4px solid var(--primary-color);
162
+ width: 36px;
163
+ height: 36px;
164
+ animation: spin 2s linear infinite;
165
+ }
166
+ @media only screen and (min-width: 768px) {
167
+ .only-large-screen{
168
+ display:block;
169
+ }
170
+ .only-large-screen-flex{
171
+ display:flex;
172
+ }
173
+ }`,
174
+ ];
175
+ }
176
+
177
+ // Startup
178
+ connectedCallback() {
179
+ super.connectedCallback();
180
+ const parent = this.parentElement;
181
+ if (parent) {
182
+ if (parent.offsetWidth === 0 && parent.style.width === '') {
183
+ parent.style.width = '100vw';
184
+ }
185
+ if (parent.offsetHeight === 0 && parent.style.height === '') {
186
+ parent.style.height = '100vh';
187
+ }
188
+ if (parent.tagName === 'BODY') {
189
+ if (!parent.style.marginTop) { parent.style.marginTop = '0'; }
190
+ if (!parent.style.marginRight) { parent.style.marginRight = '0'; }
191
+ if (!parent.style.marginBottom) { parent.style.marginBottom = '0'; }
192
+ if (!parent.style.marginLeft) { parent.style.marginLeft = '0'; }
193
+ }
194
+ }
195
+
196
+ if (this.loadFonts !== 'false') {
197
+ const fontDescriptor = {
198
+ family: 'Open Sans',
199
+ style: 'normal',
200
+ weight: '300',
201
+ unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
202
+ };
203
+ const fontWeight300 = new FontFace(
204
+ 'Open Sans',
205
+ "url(https://fonts.gstatic.com/s/opensans/v18/mem5YaGs126MiZpBA-UN_r8OUuhpKKSTjw.woff2) format('woff2')",
206
+ fontDescriptor,
207
+ );
208
+ fontDescriptor.weight = '600';
209
+ const fontWeight600 = new FontFace(
210
+ 'Open Sans',
211
+ "url(https://fonts.gstatic.com/s/opensans/v18/mem5YaGs126MiZpBA-UNirkOUuhpKKSTjw.woff2) format('woff2')",
212
+ fontDescriptor,
213
+ );
214
+ fontWeight300.load().then((font) => { document.fonts.add(font); });
215
+ fontWeight600.load().then((font) => { document.fonts.add(font); });
216
+ }
217
+
218
+ this.renderStyle = 'focused';
219
+ this.pathsExpanded = this.pathsExpanded === 'true';
220
+
221
+ if (!this.showInfo || !'true, false,'.includes(`${this.showInfo},`)) { this.showInfo = 'true'; }
222
+ if (!this.showSideNav || !'true false'.includes(this.showSideNav)) { this.showSideNav = 'true'; }
223
+ if (!this.showHeader || !'true, false,'.includes(`${this.showHeader},`)) { this.showHeader = 'true'; }
224
+
225
+ if (!this.schemaStyle || !'tree, table,'.includes(`${this.schemaStyle},`)) { this.schemaStyle = 'tree'; }
226
+ if (!this.theme || !'light, dark,'.includes(`${this.theme},`)) {
227
+ this.theme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) ? 'light' : 'dark';
228
+ }
229
+ if (!this.allowSearch || !'true, false,'.includes(`${this.allowSearch},`)) { this.allowSearch = 'true'; }
230
+ if (!this.schemaExpandLevel || this.schemaExpandLevel < 1) { this.schemaExpandLevel = 99999; }
231
+ if (!this.schemaDescriptionExpanded || !'true, false,'.includes(`${this.schemaDescriptionExpanded},`)) { this.schemaDescriptionExpanded = 'false'; }
232
+ if (!this.responseAreaHeight) { this.responseAreaHeight = '300px'; }
233
+ if (!this.fontSize || !'default, large, largest,'.includes(`${this.fontSize},`)) { this.fontSize = 'default'; }
234
+ if (!this.matchType || !'includes regex'.includes(this.matchType)) { this.matchType = 'includes'; }
235
+ if (!this.allowSchemaDescriptionExpandToggle || !'true, false,'.includes(`${this.allowSchemaDescriptionExpandToggle},`)) { this.allowSchemaDescriptionExpandToggle = 'true'; }
236
+
237
+ marked.setOptions({
238
+ highlight: (code, lang) => {
239
+ if (Prism.languages[lang]) {
240
+ return Prism.highlight(code, Prism.languages[lang], lang);
241
+ }
242
+ return code;
243
+ },
244
+ });
245
+ }
246
+
247
+ render() {
248
+ return jsonSchemaViewerTemplate.call(this, true, false, false, this.pathsExpanded);
249
+ }
250
+
251
+ attributeChangedCallback(name, oldVal, newVal) {
252
+ if (name === 'spec-url') {
253
+ if (oldVal !== newVal) {
254
+ // put it at the end of event-loop to load all the attributes
255
+ window.setTimeout(async () => {
256
+ await this.loadSpec(newVal);
257
+ }, 0);
258
+ }
259
+ }
260
+ super.attributeChangedCallback(name, oldVal, newVal);
261
+ }
262
+
263
+ onSepcUrlChange() {
264
+ this.setAttribute('spec-url', this.shadowRoot.getElementById('spec-url').value);
265
+ }
266
+
267
+ onSearchChange(e) {
268
+ // Todo: Filter Search
269
+ this.matchPaths = e.target.value;
270
+ }
271
+
272
+ // Public Method
273
+ async loadSpec(specUrl) {
274
+ if (!specUrl) {
275
+ return;
276
+ }
277
+ try {
278
+ this.resolvedSpec = {
279
+ specLoadError: false,
280
+ isSpecLoading: true,
281
+ tags: [],
282
+ };
283
+ this.loading = true;
284
+ this.loadFailed = false;
285
+ this.requestUpdate();
286
+ const spec = await ProcessSpec.call(
287
+ this,
288
+ specUrl,
289
+ this.generateMissingTags === 'true',
290
+ this.sortTags === 'true',
291
+ this.getAttribute('sort-endpoints-by'),
292
+ );
293
+ this.loading = false;
294
+ this.afterSpecParsedAndValidated(spec);
295
+ } catch (err) {
296
+ this.loading = false;
297
+ this.loadFailed = true;
298
+ this.resolvedSpec = null;
299
+ console.error(`RapiDoc: Unable to resolve the API spec.. ${err.message}`); // eslint-disable-line no-console
300
+ }
301
+ }
302
+
303
+ async afterSpecParsedAndValidated(spec) {
304
+ this.resolvedSpec = spec;
305
+ const specLoadedEvent = new CustomEvent('spec-loaded', { detail: spec });
306
+ this.dispatchEvent(specLoadedEvent);
307
+ }
308
+
309
+ // Called by anchor tags created using markdown
310
+ handleHref(e) {
311
+ if (e.target.tagName.toLowerCase() === 'a') {
312
+ if (e.target.getAttribute('href').startsWith('#')) {
313
+ const gotoEl = this.shadowRoot.getElementById(e.target.getAttribute('href').replace('#', ''));
314
+ if (gotoEl) {
315
+ gotoEl.scrollIntoView({ behavior: 'auto', block: 'start' });
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ // Example Dropdown @change Handler
322
+ onSelectExample(e) {
323
+ const exampleContainerEl = e.target.closest('.json-schema-example-panel');
324
+ const exampleEls = [...exampleContainerEl.querySelectorAll('.example')];
325
+ exampleEls.forEach((v) => {
326
+ v.style.display = v.dataset.example === e.target.value ? 'flex' : 'none';
327
+ });
328
+ }
329
+
330
+ async scrollToEventTarget(event) {
331
+ const navEl = event.currentTarget;
332
+ if (!navEl.dataset.contentId) {
333
+ return;
334
+ }
335
+ const contentEl = this.shadowRoot.getElementById(navEl.dataset.contentId);
336
+ if (contentEl) {
337
+ contentEl.scrollIntoView({ behavior: 'auto', block: 'start' });
338
+ }
339
+ }
340
+ }
341
+ customElements.define('json-schema-viewer', JsonSchemaViewer);