openapi-explorer 1.0.571 → 1.0.577
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/openapi-explorer.min.js +4 -4
- package/dist/browser/openapi-explorer.min.js.map +1 -1
- package/dist/es/components/api-request.js +42 -27
- package/dist/es/components/request-form-table.js +77 -11
- package/dist/es/utils/schema-utils.js +4 -1
- package/dist/lib/components/api-request.js +41 -26
- package/dist/lib/components/request-form-table.js +80 -11
- package/dist/lib/utils/schema-utils.js +5 -0
- package/package.json +1 -1
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import { html } from 'lit';
|
|
3
3
|
import { marked } from 'marked';
|
|
4
4
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
5
|
+
import { isPatternProperty } from '../utils/schema-utils';
|
|
6
|
+
import { map } from 'lit/directives/map.js';
|
|
7
|
+
import { range } from 'lit/directives/range.js';
|
|
5
8
|
|
|
6
9
|
function generateFormRows(data, options, dataType = 'object', key = '', description = '', schemaLevel = 0) {
|
|
7
10
|
const newSchemaLevel = data['::type'] && data['::type'].startsWith('xxx-of') ? schemaLevel : schemaLevel + 1;
|
|
@@ -45,6 +48,20 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
const parsedData = JSON.parse(data);
|
|
51
|
+
return generatePrimitiveRow.call(this, parsedData, {
|
|
52
|
+
key,
|
|
53
|
+
keyLabel,
|
|
54
|
+
keyDescr,
|
|
55
|
+
description,
|
|
56
|
+
dataType,
|
|
57
|
+
isRequired,
|
|
58
|
+
options
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function generatePrimitiveRow(rowData, parentRecursionOptions) {
|
|
63
|
+
var _this$duplicatedRowsB;
|
|
64
|
+
|
|
48
65
|
const {
|
|
49
66
|
type,
|
|
50
67
|
format,
|
|
@@ -57,13 +74,46 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
57
74
|
schemaDescription,
|
|
58
75
|
schemaTitle,
|
|
59
76
|
deprecated
|
|
60
|
-
} =
|
|
77
|
+
} = rowData;
|
|
78
|
+
const {
|
|
79
|
+
key,
|
|
80
|
+
keyLabel,
|
|
81
|
+
keyDescr,
|
|
82
|
+
description,
|
|
83
|
+
dataType,
|
|
84
|
+
isRequired,
|
|
85
|
+
options
|
|
86
|
+
} = parentRecursionOptions;
|
|
61
87
|
|
|
62
88
|
if (readOrWriteOnly === '🆁') {
|
|
63
89
|
return undefined;
|
|
64
90
|
}
|
|
65
91
|
|
|
66
|
-
|
|
92
|
+
const elementId = this.elementId || `${this.method}-${this.path}`;
|
|
93
|
+
const duplicateRowGeneratorKey = `${elementId}-${key}`;
|
|
94
|
+
|
|
95
|
+
const rowGenerator = e => {
|
|
96
|
+
var _e$target$dataset, _e$target$dataset2;
|
|
97
|
+
|
|
98
|
+
if (((_e$target$dataset = e.target.dataset) === null || _e$target$dataset === void 0 ? void 0 : _e$target$dataset.ptype) !== 'pattern-property-key' && !isPatternProperty((_e$target$dataset2 = e.target.dataset) === null || _e$target$dataset2 === void 0 ? void 0 : _e$target$dataset2.pname)) {
|
|
99
|
+
return;
|
|
100
|
+
} // If the row key has a value then add another row
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
const patternPropertyKeyEls = [...this.querySelectorAll("[data-ptype='pattern-property-key']")];
|
|
104
|
+
const patternPropertyInputEls = [...this.querySelectorAll("[data-ptype='form-input']")].filter(el => isPatternProperty(el.dataset.pname)); // If there is still some row that either has an empty key or an empty value, then skip adding a new row
|
|
105
|
+
|
|
106
|
+
if (patternPropertyKeyEls.some((keyElement, index) => !keyElement.value || !patternPropertyInputEls[index].value)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (e.target.value) {
|
|
111
|
+
this.duplicatedRowsByKey[duplicateRowGeneratorKey] = (this.duplicatedRowsByKey[duplicateRowGeneratorKey] || 1) + 1;
|
|
112
|
+
this.requestUpdate();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return map(range(((_this$duplicatedRowsB = this.duplicatedRowsByKey) === null || _this$duplicatedRowsB === void 0 ? void 0 : _this$duplicatedRowsB[duplicateRowGeneratorKey]) || 1), () => html` <tr> ${inputFieldKeyLabel.call(this, key.startsWith('::OPTION'), keyLabel, keyDescr, dataType, deprecated, isRequired, schemaTitle, format || type, rowGenerator)} ${dataType === 'array' ? getArrayFormField.call(this, keyLabel, example, defaultValue, format, rowGenerator) : ''} ${dataType !== 'array' ? getPrimitiveFormField.call(this, keyLabel, example, defaultValue, format, options, rowGenerator) : ''} <td> ${description ? html`<div class="param-description">${unsafeHTML(marked(description))}</div>` : ''} ${defaultValue || constraints || allowedValues || pattern ? html` <div class="param-constraint"> ${pattern ? html`<span style="font-weight:700">Pattern: </span>${pattern}<br>` : ''} ${constraints.length ? html`<span style="font-weight:700">Constraints: </span>${constraints.join(', ')}<br>` : ''} ${allowedValues === null || allowedValues === void 0 ? void 0 : allowedValues.split('┃').filter(v => v !== '').map((v, i) => html` ${i > 0 ? '|' : html`<span style="font-weight:700">Allowed: </span>`} ${html` <a part="anchor anchor-param-constraint" data-type="${type === 'array' ? type : 'string'}" data-enum="${v.trim()}" @click="${e => {
|
|
67
117
|
const inputEl = e.target.closest('table').querySelector(`[data-pname="${keyLabel}"]`);
|
|
68
118
|
|
|
69
119
|
if (inputEl) {
|
|
@@ -75,7 +125,17 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
75
125
|
if (inputEl) {
|
|
76
126
|
inputEl.value = e.target.dataset.exampleType === 'array' ? e.target.dataset.example.split('~|~') : e.target.dataset.example;
|
|
77
127
|
}
|
|
78
|
-
}}"> ${type === 'array' ? example.join(', ') : example} </a> ${type === 'array' ? '] ' : ''} </span>` : ''} </td> </tr>` : ''}
|
|
128
|
+
}}"> ${type === 'array' ? example.join(', ') : example} </a> ${type === 'array' ? '] ' : ''} </span>` : ''} </td> </tr>` : ''}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function inputFieldKeyLabel(isOption, keyLabel, keyDescription, dataType, deprecated, isRequired, schemaTitle, format, rowGenerator) {
|
|
132
|
+
if (isPatternProperty(keyLabel)) {
|
|
133
|
+
return html` <td style="width:160px;min-width:100px"> <div class="param-name ${deprecated ? 'deprecated' : ''}"> <input placeholder="${keyLabel}" @change="${e => {
|
|
134
|
+
rowGenerator(e);
|
|
135
|
+
}}" .value="${''}" spellcheck="false" type="${format === 'binary' ? 'file' : format === 'password' ? 'password' : 'text'}" part="textbox textbox-param" style="width:100%" data-ptype="pattern-property-key" data-pname="${keyLabel}" data-default="${''}" data-array="false"> </div></td>`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return html` <td style="width:160px;min-width:100px"> <div class="param-name ${deprecated ? 'deprecated' : ''}"> ${!deprecated && isRequired ? html`<span class="key-label">${keyLabel}</span><span style="color:var(--red)">*</span>` : isOption ? html`<span class="xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescription}</span>` : html`${keyLabel ? html`<span class="key-label"> ${keyLabel}</span>` : html`<span class="xxx-of-descr">${schemaTitle}</span>`}`} </div> <div class="param-type"> ${dataType === 'array' ? html`[<span>${format}</span>]` : `${format}`} </div> </td>`;
|
|
79
139
|
} // function getObjectFormField(keyLabel, example, defaultValue, format, options) {
|
|
80
140
|
// return html`
|
|
81
141
|
// <td>
|
|
@@ -86,30 +146,36 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
86
146
|
// part = "textarea textarea-param"
|
|
87
147
|
// style = "width:100%; border:none; resize:vertical;"
|
|
88
148
|
// data-array = "false"
|
|
89
|
-
// data-ptype = "
|
|
149
|
+
// data-ptype = "form-input"
|
|
90
150
|
// data-pname = "${keyLabel}"
|
|
91
151
|
// data-default = "${defaultValue || ''}"
|
|
92
152
|
// spellcheck = "false"
|
|
93
153
|
// .value="${options.fillRequestWithDefault === 'true' ? defaultValue : ''}"
|
|
94
154
|
// ></textarea>
|
|
95
155
|
// <!-- This textarea(hidden) is to store the original example value, in focused mode on navbar change it is used to update the example text -->
|
|
96
|
-
// <textarea data-pname = "hidden-${keyLabel}" data-ptype = "
|
|
156
|
+
// <textarea data-pname = "hidden-${keyLabel}" data-ptype = "hidden-form-input" class="is-hidden" style="display:none" .value="${defaultValue}"></textarea>
|
|
97
157
|
// </div>
|
|
98
158
|
// </div>
|
|
99
159
|
// </td>`;
|
|
100
160
|
// }
|
|
101
161
|
|
|
102
162
|
|
|
103
|
-
function getArrayFormField(keyLabel, example, defaultValue, format,
|
|
163
|
+
function getArrayFormField(keyLabel, example, defaultValue, format, rowGenerator) {
|
|
104
164
|
if (format === 'binary') {
|
|
105
|
-
return html`<td style="min-width:100px"> <div class="file-input-container col" style="align-items:flex-end" @click="${e => this.onAddRemoveFileInput(e, keyLabel
|
|
165
|
+
return html`<td style="min-width:100px"> <div class="file-input-container col" style="align-items:flex-end" @click="${e => this.onAddRemoveFileInput(e, keyLabel)}"> <div class="input-set row"> <input @change="${e => {
|
|
166
|
+
rowGenerator(e);
|
|
167
|
+
}}" type="file" part="file-input" class="file-input" data-pname="${keyLabel}" data-ptype="form-input" data-array="false" data-file-array="true"> <button class="file-input-remove-btn"> ✕ </button> </div> <button class="m-btn primary file-input-add-btn" part="btn btn-fill" style="margin:2px 25px 0 0;padding:2px 6px">ADD</button> </div> </td>`;
|
|
106
168
|
}
|
|
107
169
|
|
|
108
|
-
return html`<td style="min-width:100px"> <tag-input
|
|
170
|
+
return html`<td style="min-width:100px"> <tag-input @change="${e => {
|
|
171
|
+
rowGenerator(e);
|
|
172
|
+
}}" style="width:100%" data-ptype="form-input" data-pname="${keyLabel}" data-default="${defaultValue || ''}" data-array="true" placeholder="${(Array.isArray(example) ? example[0] : example) || defaultValue || 'add-multiple ↩'}" .value="${defaultValue || ''}"></tag-input> </td>`;
|
|
109
173
|
}
|
|
110
174
|
|
|
111
|
-
function getPrimitiveFormField(keyLabel, example, defaultValue, format, options) {
|
|
112
|
-
return html`<td style="min-width:100px"> <input placeholder="${example || defaultValue || ''}"
|
|
175
|
+
function getPrimitiveFormField(keyLabel, example, defaultValue, format, options, rowGenerator) {
|
|
176
|
+
return html`<td style="min-width:100px"> <input placeholder="${example || defaultValue || ''}" @change="${e => {
|
|
177
|
+
rowGenerator(e);
|
|
178
|
+
}}" .value="${options.fillRequestWithDefault && defaultValue || ''}" spellcheck="false" type="${format === 'binary' ? 'file' : format === 'password' ? 'password' : 'text'}" part="textbox textbox-param" style="width:100%" data-ptype="form-input" data-pname="${keyLabel}" data-default="${defaultValue || ''}" data-array="false"> </td>`;
|
|
113
179
|
}
|
|
114
180
|
|
|
115
181
|
export default function getRequestFormTable(data, mimeType) {
|
|
@@ -117,5 +183,5 @@ export default function getRequestFormTable(data, mimeType) {
|
|
|
117
183
|
mimeType: mimeType,
|
|
118
184
|
fillRequestWithDefault: this.fillRequestWithDefault === 'true'
|
|
119
185
|
};
|
|
120
|
-
return html` <table role="presentation" class="request-form-table" style="border:1px solid var(--light-border-color);width:100%"> ${data ? html`${generateFormRows.call(this, data['::type'] === 'array' ? data['::props'] : data, options, data['::type'])}` : ''} </table>`;
|
|
186
|
+
return html` <table id="request-form-table" role="presentation" class="request-form-table" style="border:1px solid var(--light-border-color);width:100%"> ${data ? html`${generateFormRows.call(this, data['::type'] === 'array' ? data['::props'] : data, options, data['::type'])}` : ''} </table>`;
|
|
121
187
|
}
|
|
@@ -385,6 +385,10 @@ function getSimpleValueResult(schema, config, namespace, prefix, xmlAttributes,
|
|
|
385
385
|
const value = getSampleValueByType(schema, config.propertyName, config.skipExampleStrings);
|
|
386
386
|
return [value];
|
|
387
387
|
}
|
|
388
|
+
|
|
389
|
+
export function isPatternProperty(label) {
|
|
390
|
+
return label.match(/^<any-key>|<pattern:/);
|
|
391
|
+
}
|
|
388
392
|
/**
|
|
389
393
|
* For changing OpenAPI-Schema to an Object Notation,
|
|
390
394
|
* This Object would further be an input to UI Components to generate an Object-Tree
|
|
@@ -394,7 +398,6 @@ function getSimpleValueResult(schema, config, namespace, prefix, xmlAttributes,
|
|
|
394
398
|
* @param {string} suffix - used for suffixing property names to avoid duplicate props during object composition
|
|
395
399
|
*/
|
|
396
400
|
|
|
397
|
-
|
|
398
401
|
export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
|
|
399
402
|
if (!rawSchema) {
|
|
400
403
|
return undefined;
|
|
@@ -43,6 +43,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
43
43
|
|
|
44
44
|
constructor() {
|
|
45
45
|
super();
|
|
46
|
+
this.duplicatedRowsByKey = {};
|
|
46
47
|
this.storedParamValues = {};
|
|
47
48
|
this.responseMessage = '';
|
|
48
49
|
this.responseStatus = '';
|
|
@@ -160,6 +161,10 @@ class ApiRequest extends _lit.LitElement {
|
|
|
160
161
|
attribute: 'fetch-credentials'
|
|
161
162
|
},
|
|
162
163
|
// properties for internal tracking
|
|
164
|
+
duplicatedRowsByKey: {
|
|
165
|
+
type: Object
|
|
166
|
+
},
|
|
167
|
+
// Tracking duplicated rows in form table
|
|
163
168
|
activeResponseTab: {
|
|
164
169
|
type: String
|
|
165
170
|
},
|
|
@@ -183,13 +188,8 @@ class ApiRequest extends _lit.LitElement {
|
|
|
183
188
|
}
|
|
184
189
|
|
|
185
190
|
updated(changedProperties) {
|
|
186
|
-
|
|
187
|
-
this.selectedRequestBodyType = '';
|
|
188
|
-
this.selectedRequestBodyExample = '';
|
|
189
|
-
} // In focused mode after rendering the request component, update the text-areas(which contains examples) using the original values from hidden textareas.
|
|
191
|
+
// In focused mode after rendering the request component, update the text-areas(which contains examples) using the original values from hidden textareas.
|
|
190
192
|
// This is done coz, user may update the dom by editing the textarea's and once the DOM is updated externally change detection wont happen, therefore update the values manually
|
|
191
|
-
|
|
192
|
-
|
|
193
193
|
if (this.renderStyle !== 'focused') {
|
|
194
194
|
return;
|
|
195
195
|
} // dont update example as only tabs is switched
|
|
@@ -432,7 +432,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
432
432
|
}
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
-
return (0, _lit.html)` <div class="request-body-container" data-selected-request-body-type="${this.selectedRequestBodyType}"> <div class="table-title top-gap row">
|
|
435
|
+
return (0, _lit.html)` <div class="request-body-container" data-selected-request-body-type="${this.selectedRequestBodyType}"> <div class="table-title top-gap row"> ${(0, _languages.getI18nText)('operations.request-body')} ${this.request_body.required ? (0, _lit.html)`<span class="mono-font" style="color:var(--red)">*</span>` : ''} <span style="font-weight:400;margin-left:5px"> ${this.selectedRequestBodyType}</span> <span style="flex:1"></span> ${reqBodyTypeSelectorHtml} </div> ${this.request_body.description ? (0, _lit.html)`<div class="m-markdown" style="margin-bottom:12px">${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(this.request_body.description))}</div>` : ''} ${reqBodySchemaHtml || reqBodyDefaultHtml ? (0, _lit.html)` <div class="tab-panel col" style="border-width:0 0 1px 0"> <div class="tab-buttons row" @click="${e => {
|
|
436
436
|
if (e.target.tagName.toLowerCase() === 'button') {
|
|
437
437
|
this.activeSchemaTab = e.target.dataset.tab;
|
|
438
438
|
}
|
|
@@ -499,7 +499,8 @@ class ApiRequest extends _lit.LitElement {
|
|
|
499
499
|
}
|
|
500
500
|
};
|
|
501
501
|
this.dispatchEvent(new CustomEvent('event', event));
|
|
502
|
-
}
|
|
502
|
+
} // onExecuteButtonClicked
|
|
503
|
+
|
|
503
504
|
|
|
504
505
|
async onTryClick() {
|
|
505
506
|
const tryBtnEl = this.querySelectorAll('.btn-execute')[0];
|
|
@@ -624,14 +625,19 @@ class ApiRequest extends _lit.LitElement {
|
|
|
624
625
|
fetchOptions.headers.append(el.dataset.pname, el.value);
|
|
625
626
|
}
|
|
626
627
|
}); // Request Body Params
|
|
628
|
+
// url-encoded Form Params (dynamic) - Parse JSON and generate Params
|
|
629
|
+
|
|
630
|
+
const formUrlDynamicTextAreaEl = requestPanelEl.querySelector("[data-ptype='dynamic-form']"); // url-encoded Form Params (regular)
|
|
631
|
+
|
|
632
|
+
const rawFormInputEls = [...requestPanelEl.querySelectorAll("[data-ptype='form-input']")];
|
|
633
|
+
const patternPropertyKeyEls = [...requestPanelEl.querySelectorAll("[data-ptype='pattern-property-key']")];
|
|
634
|
+
const patternPropertyInputEls = rawFormInputEls.filter(el => (0, _schemaUtils.isPatternProperty)(el.dataset.pname));
|
|
635
|
+
const formInputEls = rawFormInputEls.filter(el => !(0, _schemaUtils.isPatternProperty)(el.dataset.pname));
|
|
627
636
|
|
|
628
637
|
if (requestBodyContainerEl) {
|
|
629
638
|
const requestBodyType = requestBodyContainerEl.dataset.selectedRequestBodyType;
|
|
630
639
|
|
|
631
640
|
if (requestBodyType.includes('form-urlencoded')) {
|
|
632
|
-
// url-encoded Form Params (dynamic) - Parse JSON and generate Params
|
|
633
|
-
const formUrlDynamicTextAreaEl = requestPanelEl.querySelector("[data-ptype='dynamic-form']");
|
|
634
|
-
|
|
635
641
|
if (formUrlDynamicTextAreaEl) {
|
|
636
642
|
const val = formUrlDynamicTextAreaEl.value;
|
|
637
643
|
const formUrlDynParams = new URLSearchParams();
|
|
@@ -658,17 +664,23 @@ class ApiRequest extends _lit.LitElement {
|
|
|
658
664
|
curlData = ` \\\n -d ${formUrlDynParams.toString()}`;
|
|
659
665
|
}
|
|
660
666
|
} else {
|
|
661
|
-
// url-encoded Form Params (regular)
|
|
662
|
-
const formUrlEls = [...requestPanelEl.querySelectorAll("[data-ptype='form-urlencode']")];
|
|
663
667
|
const formUrlParams = new URLSearchParams();
|
|
664
|
-
|
|
668
|
+
patternPropertyInputEls.concat(formInputEls).forEach((el, counter) => {
|
|
669
|
+
var _patternPropertyKeyEl;
|
|
670
|
+
|
|
671
|
+
const keyName = ((_patternPropertyKeyEl = patternPropertyKeyEls[counter]) === null || _patternPropertyKeyEl === void 0 ? void 0 : _patternPropertyKeyEl.value) || el.dataset.pname;
|
|
672
|
+
|
|
673
|
+
if (el.type === 'file') {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
665
677
|
if (el.dataset.array === 'false') {
|
|
666
678
|
if (el.value) {
|
|
667
|
-
formUrlParams.append(
|
|
679
|
+
formUrlParams.append(keyName, el.value);
|
|
668
680
|
}
|
|
669
681
|
} else {
|
|
670
682
|
const vals = el.value && Array.isArray(el.value) ? el.value.join(',') : '';
|
|
671
|
-
formUrlParams.append(
|
|
683
|
+
formUrlParams.append(keyName, vals);
|
|
672
684
|
}
|
|
673
685
|
});
|
|
674
686
|
fetchOptions.body = formUrlParams;
|
|
@@ -676,21 +688,24 @@ class ApiRequest extends _lit.LitElement {
|
|
|
676
688
|
}
|
|
677
689
|
} else if (requestBodyType.includes('form-data')) {
|
|
678
690
|
const formDataParams = new FormData();
|
|
679
|
-
|
|
680
|
-
|
|
691
|
+
patternPropertyInputEls.concat(formInputEls).forEach((el, counter) => {
|
|
692
|
+
var _patternPropertyKeyEl2;
|
|
693
|
+
|
|
694
|
+
const keyName = ((_patternPropertyKeyEl2 = patternPropertyKeyEls[counter]) === null || _patternPropertyKeyEl2 === void 0 ? void 0 : _patternPropertyKeyEl2.value) || el.dataset.pname;
|
|
695
|
+
|
|
681
696
|
if (el.dataset.array === 'false') {
|
|
682
697
|
if (el.type === 'file' && el.files[0]) {
|
|
683
|
-
formDataParams.append(
|
|
684
|
-
curlForm += ` \\\n -F "${
|
|
698
|
+
formDataParams.append(keyName, el.files[0], el.files[0].name);
|
|
699
|
+
curlForm += ` \\\n -F "${keyName}=@${el.files[0].name}"`;
|
|
685
700
|
} else if (el.value) {
|
|
686
|
-
formDataParams.append(
|
|
687
|
-
curlForm += ` \\\n -F "${
|
|
701
|
+
formDataParams.append(keyName, el.value);
|
|
702
|
+
curlForm += ` \\\n -F "${keyName}=${el.value}"`;
|
|
688
703
|
}
|
|
689
704
|
} else if (el.value && Array.isArray(el.value)) {
|
|
690
705
|
el.value.forEach(v => {
|
|
691
|
-
curlForm += ` \\\n -F "${
|
|
706
|
+
curlForm += ` \\\n -F "${keyName}[]=${v}"`;
|
|
692
707
|
});
|
|
693
|
-
formDataParams.append(
|
|
708
|
+
formDataParams.append(keyName, el.value.join(','));
|
|
694
709
|
}
|
|
695
710
|
});
|
|
696
711
|
fetchOptions.body = formDataParams;
|
|
@@ -886,7 +901,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
886
901
|
}
|
|
887
902
|
}
|
|
888
903
|
|
|
889
|
-
onAddRemoveFileInput(e, pname
|
|
904
|
+
onAddRemoveFileInput(e, pname) {
|
|
890
905
|
if (e.target.tagName.toLowerCase() !== 'button') {
|
|
891
906
|
return;
|
|
892
907
|
}
|
|
@@ -908,7 +923,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
908
923
|
newInputEl.type = 'file';
|
|
909
924
|
newInputEl.setAttribute('class', 'file-input');
|
|
910
925
|
newInputEl.setAttribute('data-pname', pname);
|
|
911
|
-
newInputEl.setAttribute('data-ptype',
|
|
926
|
+
newInputEl.setAttribute('data-ptype', 'form-input');
|
|
912
927
|
newInputEl.setAttribute('data-array', 'false');
|
|
913
928
|
newInputEl.setAttribute('data-file-array', 'true'); // Remover Button
|
|
914
929
|
|
|
@@ -9,6 +9,12 @@ var _marked = require("marked");
|
|
|
9
9
|
|
|
10
10
|
var _unsafeHtml = require("lit/directives/unsafe-html.js");
|
|
11
11
|
|
|
12
|
+
var _schemaUtils = require("../utils/schema-utils");
|
|
13
|
+
|
|
14
|
+
var _map = require("lit/directives/map.js");
|
|
15
|
+
|
|
16
|
+
var _range = require("lit/directives/range.js");
|
|
17
|
+
|
|
12
18
|
/* eslint-disable indent */
|
|
13
19
|
function generateFormRows(data, options, dataType = 'object', key = '', description = '', schemaLevel = 0) {
|
|
14
20
|
const newSchemaLevel = data['::type'] && data['::type'].startsWith('xxx-of') ? schemaLevel : schemaLevel + 1;
|
|
@@ -52,6 +58,20 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
52
58
|
|
|
53
59
|
|
|
54
60
|
const parsedData = JSON.parse(data);
|
|
61
|
+
return generatePrimitiveRow.call(this, parsedData, {
|
|
62
|
+
key,
|
|
63
|
+
keyLabel,
|
|
64
|
+
keyDescr,
|
|
65
|
+
description,
|
|
66
|
+
dataType,
|
|
67
|
+
isRequired,
|
|
68
|
+
options
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function generatePrimitiveRow(rowData, parentRecursionOptions) {
|
|
73
|
+
var _this$duplicatedRowsB;
|
|
74
|
+
|
|
55
75
|
const {
|
|
56
76
|
type,
|
|
57
77
|
format,
|
|
@@ -64,13 +84,46 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
64
84
|
schemaDescription,
|
|
65
85
|
schemaTitle,
|
|
66
86
|
deprecated
|
|
67
|
-
} =
|
|
87
|
+
} = rowData;
|
|
88
|
+
const {
|
|
89
|
+
key,
|
|
90
|
+
keyLabel,
|
|
91
|
+
keyDescr,
|
|
92
|
+
description,
|
|
93
|
+
dataType,
|
|
94
|
+
isRequired,
|
|
95
|
+
options
|
|
96
|
+
} = parentRecursionOptions;
|
|
68
97
|
|
|
69
98
|
if (readOrWriteOnly === '🆁') {
|
|
70
99
|
return undefined;
|
|
71
100
|
}
|
|
72
101
|
|
|
73
|
-
|
|
102
|
+
const elementId = this.elementId || `${this.method}-${this.path}`;
|
|
103
|
+
const duplicateRowGeneratorKey = `${elementId}-${key}`;
|
|
104
|
+
|
|
105
|
+
const rowGenerator = e => {
|
|
106
|
+
var _e$target$dataset, _e$target$dataset2;
|
|
107
|
+
|
|
108
|
+
if (((_e$target$dataset = e.target.dataset) === null || _e$target$dataset === void 0 ? void 0 : _e$target$dataset.ptype) !== 'pattern-property-key' && !(0, _schemaUtils.isPatternProperty)((_e$target$dataset2 = e.target.dataset) === null || _e$target$dataset2 === void 0 ? void 0 : _e$target$dataset2.pname)) {
|
|
109
|
+
return;
|
|
110
|
+
} // If the row key has a value then add another row
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
const patternPropertyKeyEls = [...this.querySelectorAll("[data-ptype='pattern-property-key']")];
|
|
114
|
+
const patternPropertyInputEls = [...this.querySelectorAll("[data-ptype='form-input']")].filter(el => (0, _schemaUtils.isPatternProperty)(el.dataset.pname)); // If there is still some row that either has an empty key or an empty value, then skip adding a new row
|
|
115
|
+
|
|
116
|
+
if (patternPropertyKeyEls.some((keyElement, index) => !keyElement.value || !patternPropertyInputEls[index].value)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (e.target.value) {
|
|
121
|
+
this.duplicatedRowsByKey[duplicateRowGeneratorKey] = (this.duplicatedRowsByKey[duplicateRowGeneratorKey] || 1) + 1;
|
|
122
|
+
this.requestUpdate();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (0, _map.map)((0, _range.range)(((_this$duplicatedRowsB = this.duplicatedRowsByKey) === null || _this$duplicatedRowsB === void 0 ? void 0 : _this$duplicatedRowsB[duplicateRowGeneratorKey]) || 1), () => (0, _lit.html)` <tr> ${inputFieldKeyLabel.call(this, key.startsWith('::OPTION'), keyLabel, keyDescr, dataType, deprecated, isRequired, schemaTitle, format || type, rowGenerator)} ${dataType === 'array' ? getArrayFormField.call(this, keyLabel, example, defaultValue, format, rowGenerator) : ''} ${dataType !== 'array' ? getPrimitiveFormField.call(this, keyLabel, example, defaultValue, format, options, rowGenerator) : ''} <td> ${description ? (0, _lit.html)`<div class="param-description">${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(description))}</div>` : ''} ${defaultValue || constraints || allowedValues || pattern ? (0, _lit.html)` <div class="param-constraint"> ${pattern ? (0, _lit.html)`<span style="font-weight:700">Pattern: </span>${pattern}<br>` : ''} ${constraints.length ? (0, _lit.html)`<span style="font-weight:700">Constraints: </span>${constraints.join(', ')}<br>` : ''} ${allowedValues === null || allowedValues === void 0 ? void 0 : allowedValues.split('┃').filter(v => v !== '').map((v, i) => (0, _lit.html)` ${i > 0 ? '|' : (0, _lit.html)`<span style="font-weight:700">Allowed: </span>`} ${(0, _lit.html)` <a part="anchor anchor-param-constraint" data-type="${type === 'array' ? type : 'string'}" data-enum="${v.trim()}" @click="${e => {
|
|
74
127
|
const inputEl = e.target.closest('table').querySelector(`[data-pname="${keyLabel}"]`);
|
|
75
128
|
|
|
76
129
|
if (inputEl) {
|
|
@@ -82,7 +135,17 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
82
135
|
if (inputEl) {
|
|
83
136
|
inputEl.value = e.target.dataset.exampleType === 'array' ? e.target.dataset.example.split('~|~') : e.target.dataset.example;
|
|
84
137
|
}
|
|
85
|
-
}}"> ${type === 'array' ? example.join(', ') : example} </a> ${type === 'array' ? '] ' : ''} </span>` : ''} </td> </tr>` : ''}
|
|
138
|
+
}}"> ${type === 'array' ? example.join(', ') : example} </a> ${type === 'array' ? '] ' : ''} </span>` : ''} </td> </tr>` : ''}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function inputFieldKeyLabel(isOption, keyLabel, keyDescription, dataType, deprecated, isRequired, schemaTitle, format, rowGenerator) {
|
|
142
|
+
if ((0, _schemaUtils.isPatternProperty)(keyLabel)) {
|
|
143
|
+
return (0, _lit.html)` <td style="width:160px;min-width:100px"> <div class="param-name ${deprecated ? 'deprecated' : ''}"> <input placeholder="${keyLabel}" @change="${e => {
|
|
144
|
+
rowGenerator(e);
|
|
145
|
+
}}" .value="${''}" spellcheck="false" type="${format === 'binary' ? 'file' : format === 'password' ? 'password' : 'text'}" part="textbox textbox-param" style="width:100%" data-ptype="pattern-property-key" data-pname="${keyLabel}" data-default="${''}" data-array="false"> </div></td>`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return (0, _lit.html)` <td style="width:160px;min-width:100px"> <div class="param-name ${deprecated ? 'deprecated' : ''}"> ${!deprecated && isRequired ? (0, _lit.html)`<span class="key-label">${keyLabel}</span><span style="color:var(--red)">*</span>` : isOption ? (0, _lit.html)`<span class="xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescription}</span>` : (0, _lit.html)`${keyLabel ? (0, _lit.html)`<span class="key-label"> ${keyLabel}</span>` : (0, _lit.html)`<span class="xxx-of-descr">${schemaTitle}</span>`}`} </div> <div class="param-type"> ${dataType === 'array' ? (0, _lit.html)`[<span>${format}</span>]` : `${format}`} </div> </td>`;
|
|
86
149
|
} // function getObjectFormField(keyLabel, example, defaultValue, format, options) {
|
|
87
150
|
// return html`
|
|
88
151
|
// <td>
|
|
@@ -93,30 +156,36 @@ function generateFormRows(data, options, dataType = 'object', key = '', descript
|
|
|
93
156
|
// part = "textarea textarea-param"
|
|
94
157
|
// style = "width:100%; border:none; resize:vertical;"
|
|
95
158
|
// data-array = "false"
|
|
96
|
-
// data-ptype = "
|
|
159
|
+
// data-ptype = "form-input"
|
|
97
160
|
// data-pname = "${keyLabel}"
|
|
98
161
|
// data-default = "${defaultValue || ''}"
|
|
99
162
|
// spellcheck = "false"
|
|
100
163
|
// .value="${options.fillRequestWithDefault === 'true' ? defaultValue : ''}"
|
|
101
164
|
// ></textarea>
|
|
102
165
|
// <!-- This textarea(hidden) is to store the original example value, in focused mode on navbar change it is used to update the example text -->
|
|
103
|
-
// <textarea data-pname = "hidden-${keyLabel}" data-ptype = "
|
|
166
|
+
// <textarea data-pname = "hidden-${keyLabel}" data-ptype = "hidden-form-input" class="is-hidden" style="display:none" .value="${defaultValue}"></textarea>
|
|
104
167
|
// </div>
|
|
105
168
|
// </div>
|
|
106
169
|
// </td>`;
|
|
107
170
|
// }
|
|
108
171
|
|
|
109
172
|
|
|
110
|
-
function getArrayFormField(keyLabel, example, defaultValue, format,
|
|
173
|
+
function getArrayFormField(keyLabel, example, defaultValue, format, rowGenerator) {
|
|
111
174
|
if (format === 'binary') {
|
|
112
|
-
return (0, _lit.html)`<td style="min-width:100px"> <div class="file-input-container col" style="align-items:flex-end" @click="${e => this.onAddRemoveFileInput(e, keyLabel
|
|
175
|
+
return (0, _lit.html)`<td style="min-width:100px"> <div class="file-input-container col" style="align-items:flex-end" @click="${e => this.onAddRemoveFileInput(e, keyLabel)}"> <div class="input-set row"> <input @change="${e => {
|
|
176
|
+
rowGenerator(e);
|
|
177
|
+
}}" type="file" part="file-input" class="file-input" data-pname="${keyLabel}" data-ptype="form-input" data-array="false" data-file-array="true"> <button class="file-input-remove-btn"> ✕ </button> </div> <button class="m-btn primary file-input-add-btn" part="btn btn-fill" style="margin:2px 25px 0 0;padding:2px 6px">ADD</button> </div> </td>`;
|
|
113
178
|
}
|
|
114
179
|
|
|
115
|
-
return (0, _lit.html)`<td style="min-width:100px"> <tag-input
|
|
180
|
+
return (0, _lit.html)`<td style="min-width:100px"> <tag-input @change="${e => {
|
|
181
|
+
rowGenerator(e);
|
|
182
|
+
}}" style="width:100%" data-ptype="form-input" data-pname="${keyLabel}" data-default="${defaultValue || ''}" data-array="true" placeholder="${(Array.isArray(example) ? example[0] : example) || defaultValue || 'add-multiple ↩'}" .value="${defaultValue || ''}"></tag-input> </td>`;
|
|
116
183
|
}
|
|
117
184
|
|
|
118
|
-
function getPrimitiveFormField(keyLabel, example, defaultValue, format, options) {
|
|
119
|
-
return (0, _lit.html)`<td style="min-width:100px"> <input placeholder="${example || defaultValue || ''}"
|
|
185
|
+
function getPrimitiveFormField(keyLabel, example, defaultValue, format, options, rowGenerator) {
|
|
186
|
+
return (0, _lit.html)`<td style="min-width:100px"> <input placeholder="${example || defaultValue || ''}" @change="${e => {
|
|
187
|
+
rowGenerator(e);
|
|
188
|
+
}}" .value="${options.fillRequestWithDefault && defaultValue || ''}" spellcheck="false" type="${format === 'binary' ? 'file' : format === 'password' ? 'password' : 'text'}" part="textbox textbox-param" style="width:100%" data-ptype="form-input" data-pname="${keyLabel}" data-default="${defaultValue || ''}" data-array="false"> </td>`;
|
|
120
189
|
}
|
|
121
190
|
|
|
122
191
|
function getRequestFormTable(data, mimeType) {
|
|
@@ -124,5 +193,5 @@ function getRequestFormTable(data, mimeType) {
|
|
|
124
193
|
mimeType: mimeType,
|
|
125
194
|
fillRequestWithDefault: this.fillRequestWithDefault === 'true'
|
|
126
195
|
};
|
|
127
|
-
return (0, _lit.html)` <table role="presentation" class="request-form-table" style="border:1px solid var(--light-border-color);width:100%"> ${data ? (0, _lit.html)`${generateFormRows.call(this, data['::type'] === 'array' ? data['::props'] : data, options, data['::type'])}` : ''} </table>`;
|
|
196
|
+
return (0, _lit.html)` <table id="request-form-table" role="presentation" class="request-form-table" style="border:1px solid var(--light-border-color);width:100%"> ${data ? (0, _lit.html)`${generateFormRows.call(this, data['::type'] === 'array' ? data['::props'] : data, options, data['::type'])}` : ''} </table>`;
|
|
128
197
|
}
|
|
@@ -5,6 +5,7 @@ exports.generateExample = generateExample;
|
|
|
5
5
|
exports.getExampleValuesFromSchema = getExampleValuesFromSchema;
|
|
6
6
|
exports.getSampleValueByType = getSampleValueByType;
|
|
7
7
|
exports.getTypeInfo = getTypeInfo;
|
|
8
|
+
exports.isPatternProperty = isPatternProperty;
|
|
8
9
|
exports.schemaInObjectNotation = schemaInObjectNotation;
|
|
9
10
|
|
|
10
11
|
var _lodash = _interopRequireDefault(require("lodash.clonedeep"));
|
|
@@ -402,6 +403,10 @@ function getSimpleValueResult(schema, config, namespace, prefix, xmlAttributes,
|
|
|
402
403
|
const value = getSampleValueByType(schema, config.propertyName, config.skipExampleStrings);
|
|
403
404
|
return [value];
|
|
404
405
|
}
|
|
406
|
+
|
|
407
|
+
function isPatternProperty(label) {
|
|
408
|
+
return label.match(/^<any-key>|<pattern:/);
|
|
409
|
+
}
|
|
405
410
|
/**
|
|
406
411
|
* For changing OpenAPI-Schema to an Object Notation,
|
|
407
412
|
* This Object would further be an input to UI Components to generate an Object-Tree
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-explorer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.577",
|
|
4
4
|
"description": "OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console",
|
|
5
5
|
"author": "Rhosys Developers <developers@rhosys.ch>",
|
|
6
6
|
"type": "module",
|