api-render-ui 1.0.0 → 1.0.2
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/LICENSE +21 -0
- package/Readme.md +79 -0
- package/api-render-ui.css +20 -4
- package/api-render-ui.js +622 -158
- package/package.json +16 -5
- package/test.html +1124 -123
package/api-render-ui.js
CHANGED
|
@@ -27,6 +27,37 @@
|
|
|
27
27
|
throw new Error('Invalid mount point specified');
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// 默认值生成器函数
|
|
31
|
+
function getDefaultValues(fieldSchema) {
|
|
32
|
+
// 优先使用schema中定义的默认值
|
|
33
|
+
if ('default' in fieldSchema) {
|
|
34
|
+
return fieldSchema.default;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 处理类型数组(如anyOf情况)
|
|
38
|
+
const types = Array.isArray(fieldSchema.type) ? fieldSchema.type : [fieldSchema.type];
|
|
39
|
+
|
|
40
|
+
for (const type of types) {
|
|
41
|
+
switch (type) {
|
|
42
|
+
case 'string':
|
|
43
|
+
case 'string': case 'password': case 'email':
|
|
44
|
+
return '';
|
|
45
|
+
case 'number': case 'float': case 'double': case 'integer':
|
|
46
|
+
return 0;
|
|
47
|
+
case 'boolean':
|
|
48
|
+
return false;
|
|
49
|
+
case 'array':
|
|
50
|
+
return [];
|
|
51
|
+
case 'object':
|
|
52
|
+
return {};
|
|
53
|
+
case 'null':
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 默认返回null(安全处理)
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
30
61
|
|
|
31
62
|
// 解析OpenAPI规范并构建API操作列表
|
|
32
63
|
function parseOpenAPI(openapiSpec) {
|
|
@@ -40,24 +71,53 @@
|
|
|
40
71
|
const apiOperator = {
|
|
41
72
|
method: method.toUpperCase(),
|
|
42
73
|
url: path,
|
|
43
|
-
|
|
44
|
-
|
|
74
|
+
apiDetailInfo: null,
|
|
75
|
+
requestBody: null,
|
|
76
|
+
response: {},
|
|
77
|
+
auths: [
|
|
78
|
+
{
|
|
79
|
+
type: "No Auth"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "Basic Auth",
|
|
83
|
+
parameters: [
|
|
84
|
+
{
|
|
85
|
+
name: "userName",
|
|
86
|
+
value: ""
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "password",
|
|
90
|
+
value: ""
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
45
95
|
};
|
|
46
96
|
|
|
47
|
-
//
|
|
48
|
-
if (operation.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
97
|
+
// requestBody
|
|
98
|
+
if (operation.requestBody) {
|
|
99
|
+
|
|
100
|
+
const content = operation.requestBody.content['application/json'];
|
|
101
|
+
if (!content) return;
|
|
102
|
+
|
|
103
|
+
const schema = content.schema;
|
|
104
|
+
if (schema.$ref) {
|
|
105
|
+
const modelName = schema.$ref.split('/').pop();
|
|
106
|
+
const modelSchema = openapiSpec.components.schemas[modelName];
|
|
107
|
+
|
|
108
|
+
if (modelSchema) {
|
|
109
|
+
const model = {};
|
|
110
|
+
|
|
111
|
+
// 处理所有属性
|
|
112
|
+
Object.entries(modelSchema.properties).forEach(([field, fieldSchema]) => {
|
|
113
|
+
model[field] = getDefaultValues(fieldSchema);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
apiOperator.requestBody = model;
|
|
57
117
|
}
|
|
58
|
-
}
|
|
118
|
+
}
|
|
59
119
|
}
|
|
60
|
-
|
|
120
|
+
apiOperator.apiDetailInfo = operation;
|
|
61
121
|
// 添加到结果列表
|
|
62
122
|
apiOperatorList.push(apiOperator);
|
|
63
123
|
});
|
|
@@ -71,7 +131,7 @@
|
|
|
71
131
|
console.log('解析结果:', apiOperatorList);
|
|
72
132
|
|
|
73
133
|
// 生成内容
|
|
74
|
-
apiOperatorList.forEach(
|
|
134
|
+
apiOperatorList.forEach(apiOperator => {
|
|
75
135
|
const reqOperator = document.createElement('div');
|
|
76
136
|
reqOperator.setAttribute('data-layer', 'apioperator');
|
|
77
137
|
reqOperator.className = 'Apioperator codigma-apioperator';
|
|
@@ -86,9 +146,9 @@
|
|
|
86
146
|
methodType.className = 'Methodtype codigma-methodtype';
|
|
87
147
|
|
|
88
148
|
const methodValue = document.createElement('div');
|
|
89
|
-
methodValue.setAttribute('data-layer',
|
|
90
|
-
methodValue.className = `${
|
|
91
|
-
methodValue.textContent =
|
|
149
|
+
methodValue.setAttribute('data-layer', apiOperator.method.toLowerCase());
|
|
150
|
+
methodValue.className = `${apiOperator.method} codigma-${apiOperator.method.toLowerCase()}`;
|
|
151
|
+
methodValue.textContent = apiOperator.method;
|
|
92
152
|
|
|
93
153
|
methodType.appendChild(methodValue);
|
|
94
154
|
methodContainer.appendChild(methodType);
|
|
@@ -98,24 +158,25 @@
|
|
|
98
158
|
const urlElement = document.createElement('div');
|
|
99
159
|
urlElement.setAttribute('data-layer', 'requrl');
|
|
100
160
|
urlElement.className = 'Requrl codigma-requrl';
|
|
101
|
-
urlElement.textContent =
|
|
161
|
+
urlElement.textContent = apiOperator.url;
|
|
102
162
|
reqOperator.appendChild(urlElement);
|
|
103
163
|
|
|
104
164
|
this.container.appendChild(reqOperator);
|
|
105
165
|
|
|
106
166
|
// 添加点击事件
|
|
107
|
-
reqOperator.addEventListener('click', renderApiUnit(
|
|
167
|
+
reqOperator.addEventListener('click', renderApiUnit(apiOperator, this.container, elementMap));
|
|
108
168
|
});
|
|
109
169
|
|
|
110
170
|
// 清空挂载点并插入新内容
|
|
111
171
|
mountElement.innerHTML = '';
|
|
112
172
|
mountElement.appendChild(this.container);
|
|
113
173
|
|
|
114
|
-
function renderApiUnit(
|
|
174
|
+
function renderApiUnit(apiOperator, containerRef, elementMap) {
|
|
175
|
+
let responseSectionRef = null;
|
|
115
176
|
return function (evt) {
|
|
116
177
|
console.log('点击的API操作:');
|
|
117
|
-
console.log('方法:',
|
|
118
|
-
console.log('URL:',
|
|
178
|
+
console.log('方法:', apiOperator.method);
|
|
179
|
+
console.log('URL:', apiOperator.url);
|
|
119
180
|
console.log('------------------------');
|
|
120
181
|
|
|
121
182
|
const currentTarget = evt.currentTarget;
|
|
@@ -126,22 +187,47 @@
|
|
|
126
187
|
elementMap.delete(currentTarget); // 清除映射
|
|
127
188
|
return;
|
|
128
189
|
}
|
|
129
|
-
|
|
130
|
-
// 示例变量赋值(根据实际需要使用)
|
|
131
|
-
let method = item.method;
|
|
132
|
-
let url = item.url;
|
|
133
|
-
let parametersQueryOrPath = item.parametersQueryOrPath;
|
|
134
|
-
let parametersBody = item.parametersBody;
|
|
135
|
-
let contentType = 'application/json';
|
|
136
|
-
let acceptType = 'application/json';
|
|
137
|
-
let userName = 'admin';
|
|
138
|
-
let password = 'secret';
|
|
139
190
|
|
|
140
191
|
// 创建根容器
|
|
141
192
|
const apiContainer = document.createElement('div');
|
|
142
193
|
apiContainer.setAttribute('data-layer', 'apiunit');
|
|
143
194
|
apiContainer.className = 'Requnit codigma-apiunit';
|
|
144
195
|
// 请求操作区
|
|
196
|
+
const reqOperator = createReqOperator();
|
|
197
|
+
apiContainer.appendChild(reqOperator);
|
|
198
|
+
// 请求内容区
|
|
199
|
+
const reqContent = document.createElement('div');
|
|
200
|
+
reqContent.setAttribute('data-layer', 'reqcontent');
|
|
201
|
+
reqContent.className = 'Reqcontent codigma-apiunit-reqcontent';
|
|
202
|
+
// 参数部分
|
|
203
|
+
const paramSection = createSection(apiOperator);
|
|
204
|
+
// 头部部分
|
|
205
|
+
const headerSection = createSectionHeader(apiOperator);
|
|
206
|
+
// 授权部分
|
|
207
|
+
const authSection = createSectionAuth(apiOperator);
|
|
208
|
+
// 请求体部分
|
|
209
|
+
const bodySection = createSectionRequestBody(apiOperator.requestBody);
|
|
210
|
+
|
|
211
|
+
reqContent.append(paramSection, headerSection, authSection, bodySection);
|
|
212
|
+
apiContainer.appendChild(reqContent);
|
|
213
|
+
// 响应部分
|
|
214
|
+
const responseSection = createSectionResponse(apiOperator);
|
|
215
|
+
responseSectionRef = responseSection
|
|
216
|
+
apiContainer.appendChild(responseSection);
|
|
217
|
+
|
|
218
|
+
// 添加到文档
|
|
219
|
+
// 插入到当前元素后面
|
|
220
|
+
if (currentTarget.nextSibling) {
|
|
221
|
+
containerRef.insertBefore(apiContainer, currentTarget.nextSibling);
|
|
222
|
+
} else {
|
|
223
|
+
containerRef.appendChild(apiContainer);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 存储映射关系
|
|
227
|
+
elementMap.set(currentTarget, apiContainer);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function createReqOperator() {
|
|
145
231
|
const reqOperator = document.createElement('div');
|
|
146
232
|
reqOperator.setAttribute('data-layer', 'apioperator');
|
|
147
233
|
reqOperator.className = 'Reqoperator codigma-apiunit-apioperator';
|
|
@@ -152,7 +238,7 @@
|
|
|
152
238
|
const methodTypeInner = document.createElement('div');
|
|
153
239
|
methodTypeInner.setAttribute('data-layer', 'methodtype');
|
|
154
240
|
methodTypeInner.className = 'Methodtype codigma-apiunit-methodtype';
|
|
155
|
-
methodTypeInner.textContent = method;
|
|
241
|
+
methodTypeInner.textContent = apiOperator.method;
|
|
156
242
|
methodType.appendChild(methodTypeInner);
|
|
157
243
|
// 方法选项图标 - 使用内联SVG
|
|
158
244
|
const methodOpt = document.createElement('div');
|
|
@@ -161,29 +247,21 @@
|
|
|
161
247
|
methodOpt.className = 'Methodopt';
|
|
162
248
|
|
|
163
249
|
// 创建内联SVG
|
|
164
|
-
const svg =
|
|
165
|
-
svg.setAttribute('width', '21');
|
|
166
|
-
svg.setAttribute('height', '22');
|
|
167
|
-
svg.setAttribute('viewBox', '0 0 21 22');
|
|
168
|
-
svg.setAttribute('fill', 'none');
|
|
169
|
-
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
170
|
-
|
|
171
|
-
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
172
|
-
path.setAttribute('d', 'M5.5 8.5L10.5 13.5L15.5 8.5');
|
|
173
|
-
path.setAttribute('stroke', 'var(--Labels---Vibrant---Controls-Primary--, #404040)');
|
|
174
|
-
path.setAttribute('stroke-width', '2');
|
|
175
|
-
path.setAttribute('stroke-linecap', 'round');
|
|
176
|
-
path.setAttribute('stroke-linejoin', 'round');
|
|
177
|
-
|
|
178
|
-
svg.appendChild(path);
|
|
250
|
+
const svg = createSvg();
|
|
179
251
|
methodOpt.appendChild(svg);
|
|
180
252
|
methodType.appendChild(methodOpt);
|
|
181
253
|
reqOperator.appendChild(methodType);
|
|
182
254
|
// 请求URL
|
|
183
|
-
const reqUrl =
|
|
255
|
+
const reqUrl = createInputElement();
|
|
184
256
|
reqUrl.setAttribute('data-layer', 'requrl');
|
|
185
257
|
reqUrl.className = 'Requrl codigma-apiunit-requrl';
|
|
186
|
-
reqUrl.
|
|
258
|
+
reqUrl.value = apiOperator.url; // 绑定初始值
|
|
259
|
+
// 可选:添加输入事件监听(根据需求)
|
|
260
|
+
reqUrl.addEventListener('input', (e) => {
|
|
261
|
+
console.log('当前值:', e.target.value);
|
|
262
|
+
// 这里可以添加保存逻辑(如更新状态/发送请求
|
|
263
|
+
apiOperator.url = e.target.value
|
|
264
|
+
});
|
|
187
265
|
reqOperator.appendChild(reqUrl);
|
|
188
266
|
// 发送按钮
|
|
189
267
|
const sendButton = document.createElement('div');
|
|
@@ -194,23 +272,28 @@
|
|
|
194
272
|
sendText.className = 'Send codigma-apiunit-send';
|
|
195
273
|
sendText.textContent = 'Send';
|
|
196
274
|
sendButton.appendChild(sendText);
|
|
275
|
+
|
|
276
|
+
sendButton.addEventListener('click', (e) => {
|
|
277
|
+
console.log('当前值:', e.target.value);
|
|
278
|
+
// 这里可以添加保存逻辑(如更新状态/发送请求
|
|
279
|
+
sendRequest(apiOperator, responseSectionRef)
|
|
280
|
+
});
|
|
281
|
+
|
|
197
282
|
reqOperator.appendChild(sendButton);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
reqContent.className = 'Reqcontent codigma-apiunit-reqcontent';
|
|
203
|
-
// 参数部分
|
|
283
|
+
return reqOperator;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function createSection(apiOperator) {
|
|
204
287
|
const paramSection = document.createElement('div');
|
|
205
288
|
paramSection.setAttribute('data-layer', 'paramters-section');
|
|
206
|
-
paramSection.className = '
|
|
289
|
+
paramSection.className = 'codigma-apiunit-paramters-section';
|
|
207
290
|
// 参数容器头
|
|
208
291
|
const paramCnr = document.createElement('div');
|
|
209
292
|
paramCnr.setAttribute('data-layer', 'parameters-cnr');
|
|
210
|
-
paramCnr.className = '
|
|
293
|
+
paramCnr.className = 'codigma-apiunit-parameters-cnr';
|
|
211
294
|
const paramText = document.createElement('div');
|
|
212
295
|
paramText.setAttribute('data-layer', 'parameters');
|
|
213
|
-
paramText.className = '
|
|
296
|
+
paramText.className = 'codigma-apiunit-send';
|
|
214
297
|
paramText.textContent = 'Parameters';
|
|
215
298
|
paramCnr.appendChild(paramText);
|
|
216
299
|
paramSection.appendChild(paramCnr);
|
|
@@ -218,20 +301,25 @@
|
|
|
218
301
|
const paramValues = document.createElement('div');
|
|
219
302
|
paramValues.setAttribute('data-layer', 'paraKeyValues');
|
|
220
303
|
paramValues.className = 'Parakeyvalues codigma-apiunit-parakeyvalues';
|
|
221
|
-
|
|
304
|
+
let parameters = apiOperator.apiDetailInfo.parameters || [];
|
|
305
|
+
const parameterRows = parameters.filter(parameter => isPathOrQueryParam(parameter))
|
|
306
|
+
.map(parameter => createRow(parameter));
|
|
222
307
|
paramValues.append(...parameterRows);
|
|
223
308
|
paramSection.append(paramCnr, paramValues);
|
|
224
|
-
|
|
309
|
+
return paramSection;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function createSectionHeader(apiOperator) {
|
|
225
313
|
const headerSection = document.createElement('div');
|
|
226
314
|
headerSection.setAttribute('data-layer', 'headers-section');
|
|
227
|
-
headerSection.className = '
|
|
315
|
+
headerSection.className = 'codigma-apiunit-paramters-section';
|
|
228
316
|
// 头部容器头
|
|
229
317
|
const headerCnr = document.createElement('div');
|
|
230
318
|
headerCnr.setAttribute('data-layer', 'headers-cnr');
|
|
231
|
-
headerCnr.className = '
|
|
319
|
+
headerCnr.className = 'codigma-apiunit-parameters-cnr';
|
|
232
320
|
const headerText = document.createElement('div');
|
|
233
321
|
headerText.setAttribute('data-layer', 'headers');
|
|
234
|
-
headerText.className = '
|
|
322
|
+
headerText.className = 'codigma-apiunit-send';
|
|
235
323
|
headerText.textContent = 'Headers';
|
|
236
324
|
headerCnr.appendChild(headerText);
|
|
237
325
|
headerSection.appendChild(headerCnr);
|
|
@@ -239,35 +327,15 @@
|
|
|
239
327
|
const headerValues = document.createElement('div');
|
|
240
328
|
headerValues.setAttribute('data-layer', 'paraKeyValues');
|
|
241
329
|
headerValues.className = 'Parakeyvalues codigma-apiunit-parakeyvalues';
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const contentTypeLabel = document.createElement('div');
|
|
247
|
-
contentTypeLabel.setAttribute('data-layer', 'Content-Type:');
|
|
248
|
-
contentTypeLabel.className = 'ContentType codigma-apiunit-send';
|
|
249
|
-
contentTypeLabel.textContent = 'Content-Type:';
|
|
250
|
-
const contentTypeValue = document.createElement('div');
|
|
251
|
-
contentTypeValue.setAttribute('data-layer', 'valueText');
|
|
252
|
-
contentTypeValue.className = 'Valuetext codigma-apiunit-valuetext';
|
|
253
|
-
contentTypeValue.textContent = contentType;
|
|
254
|
-
contentTypeRow.append(contentTypeLabel, contentTypeValue);
|
|
255
|
-
// Accept
|
|
256
|
-
const acceptRow = document.createElement('div');
|
|
257
|
-
acceptRow.setAttribute('data-layer', 'keyValue2');
|
|
258
|
-
acceptRow.className = 'Keyvalue2 codigma-apiunit-keyvalue';
|
|
259
|
-
const acceptLabel = document.createElement('div');
|
|
260
|
-
acceptLabel.setAttribute('data-layer', 'Accept:');
|
|
261
|
-
acceptLabel.className = 'Accept codigma-apiunit-send';
|
|
262
|
-
acceptLabel.textContent = 'Accept:';
|
|
263
|
-
const acceptValue = document.createElement('div');
|
|
264
|
-
acceptValue.setAttribute('data-layer', 'valueText');
|
|
265
|
-
acceptValue.className = 'Valuetext codigma-apiunit-valuetext';
|
|
266
|
-
acceptValue.textContent = acceptType;
|
|
267
|
-
acceptRow.append(acceptLabel, acceptValue);
|
|
268
|
-
headerValues.append(contentTypeRow, acceptRow);
|
|
330
|
+
let parameters = apiOperator.apiDetailInfo.parameters || [];
|
|
331
|
+
const headerRows = parameters.filter(parameter => isHeaderParam(parameter))
|
|
332
|
+
.map(parameter => createRow(parameter));
|
|
333
|
+
headerValues.append(...headerRows);
|
|
269
334
|
headerSection.append(headerCnr, headerValues);
|
|
270
|
-
|
|
335
|
+
return headerSection;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function createSectionAuth(apiOperator) {
|
|
271
339
|
const authSection = document.createElement('div');
|
|
272
340
|
authSection.setAttribute('data-layer', 'authorization-section');
|
|
273
341
|
authSection.className = 'AuthorizationSection codigma-apiunit-paramters-section';
|
|
@@ -285,35 +353,20 @@
|
|
|
285
353
|
const authValues = document.createElement('div');
|
|
286
354
|
authValues.setAttribute('data-layer', 'paraKeyValues');
|
|
287
355
|
authValues.className = 'Parakeyvalues codigma-apiunit-parakeyvalues';
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
userValue.setAttribute('data-layer', 'valueText');
|
|
298
|
-
userValue.className = 'Valuetext codigma-apiunit-valuetext';
|
|
299
|
-
userValue.textContent = userName;
|
|
300
|
-
userRow.append(userLabel, userValue);
|
|
301
|
-
// 密码
|
|
302
|
-
const passRow = document.createElement('div');
|
|
303
|
-
passRow.setAttribute('data-layer', 'keyValue2');
|
|
304
|
-
passRow.className = 'Keyvalue2 codigma-apiunit-keyvalue';
|
|
305
|
-
const passLabel = document.createElement('div');
|
|
306
|
-
passLabel.setAttribute('data-layer', 'Password:');
|
|
307
|
-
passLabel.className = 'Password codigma-apiunit-send';
|
|
308
|
-
passLabel.textContent = 'Password:';
|
|
309
|
-
const passValue = document.createElement('div');
|
|
310
|
-
passValue.setAttribute('data-layer', 'valueText');
|
|
311
|
-
passValue.className = 'Valuetext codigma-apiunit-valuetext';
|
|
312
|
-
passValue.textContent = password;
|
|
313
|
-
passRow.append(passLabel, passValue);
|
|
314
|
-
authValues.append(userRow, passRow);
|
|
356
|
+
|
|
357
|
+
let auths = apiOperator.auths || []
|
|
358
|
+
const authTypeRow = createSelectRow(auths, authValues)
|
|
359
|
+
if(auths.length > 0) {
|
|
360
|
+
let parameters = apiOperator.auths[0].parameters || [];
|
|
361
|
+
const authRows = parameters.map(parameter => createRow(parameter));
|
|
362
|
+
authValues.append(authTypeRow, ...authRows);
|
|
363
|
+
}
|
|
364
|
+
|
|
315
365
|
authSection.append(authCnr, authValues);
|
|
316
|
-
|
|
366
|
+
return authSection;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function createSectionRequestBody(requestBody) {
|
|
317
370
|
const bodySection = document.createElement('div');
|
|
318
371
|
bodySection.setAttribute('data-layer', 'request-body-section');
|
|
319
372
|
bodySection.className = 'RequestBodySection codigma-apiunit-request-body-section';
|
|
@@ -328,15 +381,15 @@
|
|
|
328
381
|
bodyCnr.appendChild(bodyText);
|
|
329
382
|
bodySection.appendChild(bodyCnr);
|
|
330
383
|
// 请求体内容
|
|
331
|
-
const bodyValue = document.createElement('
|
|
384
|
+
const bodyValue = document.createElement('textarea');
|
|
332
385
|
bodyValue.setAttribute('data-layer', 'bodyTextValue');
|
|
333
|
-
bodyValue.className = 'Id0CategoryId0NameNamePhotourlsTagsId0NameStatusAvailable codigma-apiunit-
|
|
334
|
-
bodyValue.
|
|
386
|
+
bodyValue.className = 'Id0CategoryId0NameNamePhotourlsTagsId0NameStatusAvailable codigma-apiunit-parakeyvalues';
|
|
387
|
+
bodyValue.value = JSON.stringify(requestBody);
|
|
335
388
|
bodySection.appendChild(bodyValue);
|
|
389
|
+
return bodySection;
|
|
390
|
+
}
|
|
336
391
|
|
|
337
|
-
|
|
338
|
-
apiContainer.appendChild(reqContent);
|
|
339
|
-
// 响应部分
|
|
392
|
+
function createSectionResponse(apiOperator) {
|
|
340
393
|
const responseSection = document.createElement('div');
|
|
341
394
|
responseSection.setAttribute('data-layer', 'reqresponse');
|
|
342
395
|
responseSection.className = 'Reqresponse codigma-apiunit-reqresponse';
|
|
@@ -357,44 +410,95 @@
|
|
|
357
410
|
responseText.textContent = 'Response';
|
|
358
411
|
responseCnr.appendChild(responseText);
|
|
359
412
|
responseTitle.appendChild(responseCnr);
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
timeStatus.className = 'TimeStatus0 codigma-apiunit-send';
|
|
363
|
-
timeStatus.textContent = 'Time Status:0';
|
|
364
|
-
responseDesc.append(responseTitle, timeStatus);
|
|
413
|
+
const timeStatusElement = createTimeStatusElement(apiOperator);
|
|
414
|
+
responseDesc.append(responseTitle, timeStatusElement);
|
|
365
415
|
// 响应体
|
|
366
416
|
const responseBody = document.createElement('div');
|
|
367
417
|
responseBody.setAttribute('data-layer', 'responsebody');
|
|
368
418
|
responseBody.className = 'Responsebody codigma-apiunit-responsebody';
|
|
369
419
|
responseSection.append(responseDesc, responseBody);
|
|
370
|
-
|
|
420
|
+
return responseSection;
|
|
421
|
+
}
|
|
371
422
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
423
|
+
function createTimeStatusElement(apiOperator) {
|
|
424
|
+
const timeStatus = document.createElement('div');
|
|
425
|
+
timeStatus.setAttribute('data-layer', 'TimeStatus');
|
|
426
|
+
timeStatus.className = 'TimeStatus0 codigma-apiunit-send';
|
|
427
|
+
updateTimeStatus(timeStatus, apiOperator);
|
|
428
|
+
return timeStatus;
|
|
429
|
+
}
|
|
379
430
|
|
|
380
|
-
|
|
381
|
-
|
|
431
|
+
function createRow(parameter) {
|
|
432
|
+
const petIdRow = document.createElement('div');
|
|
433
|
+
petIdRow.setAttribute('data-layer', 'keyValue');
|
|
434
|
+
petIdRow.className = 'Keyvalue codigma-apiunit-keyvalue';
|
|
435
|
+
const petIdLabel = document.createElement('div');
|
|
436
|
+
petIdLabel.setAttribute('data-layer', parameter["name"]);
|
|
437
|
+
petIdLabel.className = parameter["name"] + ' codigma-apiunit-send';
|
|
438
|
+
petIdLabel.textContent = parameter["name"] + ':';
|
|
439
|
+
const petIdValue = createInputElement();
|
|
440
|
+
petIdValue.setAttribute('data-layer', 'valueText');
|
|
441
|
+
petIdValue.className = 'Valuetext codigma-apiunit-valuetext';
|
|
442
|
+
petIdValue.value = parameter["value"] || "";
|
|
382
443
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
444
|
+
// 可选:添加输入事件监听(根据需求)
|
|
445
|
+
petIdValue.addEventListener('input', (e) => {
|
|
446
|
+
console.log('当前值:', e.target.value);
|
|
447
|
+
// 这里可以添加保存逻辑(如更新状态/发送请求
|
|
448
|
+
parameter["value"] = e.target.value
|
|
449
|
+
});
|
|
450
|
+
petIdRow.append(petIdLabel, petIdValue);
|
|
451
|
+
return petIdRow;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function createInputElement() {
|
|
455
|
+
const inputText = document.createElement('input');
|
|
456
|
+
inputText.setAttribute('type', 'text');
|
|
457
|
+
inputText.setAttribute('name', 'text-input');
|
|
458
|
+
inputText.setAttribute('label', 'text-input');
|
|
459
|
+
inputText.setAttribute('autocomplete', 'off');
|
|
460
|
+
return inputText;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function createSelectRow(auths, authValues) {
|
|
464
|
+
// 创建外层容器div
|
|
465
|
+
const container = document.createElement('div');
|
|
466
|
+
container.setAttribute('data-layer', 'keyValue');
|
|
467
|
+
container.className = 'Keyvalue codigma-apiunit-keyvalue';
|
|
468
|
+
|
|
469
|
+
// 创建type显示div
|
|
470
|
+
const typeLabel = document.createElement('div');
|
|
471
|
+
typeLabel.setAttribute('data-layer', "type");
|
|
472
|
+
typeLabel.className = 'type codigma-apiunit-send';
|
|
473
|
+
typeLabel.textContent = 'Type:';
|
|
474
|
+
|
|
475
|
+
// 创建select元素
|
|
476
|
+
const selectElement = document.createElement('select');
|
|
477
|
+
selectElement.name = 'text-select';
|
|
478
|
+
selectElement.label = 'text-select';
|
|
479
|
+
selectElement.setAttribute('data-layer', 'valueText');
|
|
480
|
+
|
|
481
|
+
// 示例选项(可根据实际需求添加
|
|
482
|
+
auths.forEach(auth => {
|
|
483
|
+
const option1 = document.createElement('option');
|
|
484
|
+
option1.value = auth["type"];
|
|
485
|
+
option1.textContent = auth["type"];
|
|
486
|
+
selectElement.appendChild(option1);
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
// 添加选择事件监听
|
|
490
|
+
selectElement.addEventListener('change', function (event) {
|
|
491
|
+
//切换前先移除掉原来的元素
|
|
492
|
+
authValues && Array.from(authValues.children).slice(1).forEach(el => el.remove());
|
|
493
|
+
const auth = auths[event.target.selectedIndex];
|
|
494
|
+
let parameters = auth.parameters || [];
|
|
495
|
+
const authRows = parameters.map(parameter => createRow(parameter));
|
|
496
|
+
authValues.append(...authRows);
|
|
497
|
+
});
|
|
498
|
+
// 组装DOM结构
|
|
499
|
+
container.appendChild(typeLabel);
|
|
500
|
+
container.appendChild(selectElement);
|
|
501
|
+
return container;
|
|
398
502
|
}
|
|
399
503
|
}
|
|
400
504
|
};
|
|
@@ -405,4 +509,364 @@
|
|
|
405
509
|
} else {
|
|
406
510
|
global.ApiRenderer = ApiRenderer;
|
|
407
511
|
}
|
|
408
|
-
})(window);
|
|
512
|
+
})(window);
|
|
513
|
+
|
|
514
|
+
function isPathOrQueryParam(param) {
|
|
515
|
+
return param.in === 'path' || param.in === 'query';
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function isHeaderParam(param) {
|
|
519
|
+
return param.in === 'header';
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
*
|
|
524
|
+
*const apiDetailInfo: any = {
|
|
525
|
+
customQueryparameters: [
|
|
526
|
+
{
|
|
527
|
+
name: '',
|
|
528
|
+
value: ''
|
|
529
|
+
}
|
|
530
|
+
],
|
|
531
|
+
customHeaderparameters: [
|
|
532
|
+
{
|
|
533
|
+
name: '',
|
|
534
|
+
value: ''
|
|
535
|
+
}
|
|
536
|
+
],
|
|
537
|
+
bodyModel: ""
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const apiInfo: any = {
|
|
541
|
+
index: this.getRandomInt(10000, 20000),
|
|
542
|
+
id: this.uuid(),
|
|
543
|
+
serviceName: "",
|
|
544
|
+
method: "get",
|
|
545
|
+
symbol: "GET",
|
|
546
|
+
path: "",
|
|
547
|
+
apiUrl: "",
|
|
548
|
+
summary: "",
|
|
549
|
+
label: "Untitle",
|
|
550
|
+
tabLabel: "Untitle",
|
|
551
|
+
apiDetailInfo: apiDetailInfo,
|
|
552
|
+
server: "",
|
|
553
|
+
symbolColor: "green",
|
|
554
|
+
custom: true,
|
|
555
|
+
isActive: true,
|
|
556
|
+
response: {}
|
|
557
|
+
}
|
|
558
|
+
*
|
|
559
|
+
*
|
|
560
|
+
* const apiOperator = {
|
|
561
|
+
method: method.toUpperCase(),
|
|
562
|
+
url: path,
|
|
563
|
+
apiDetailInfo: null,
|
|
564
|
+
requestBody: null
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
* @param {*} apiOperator
|
|
568
|
+
* @param {*} apiInfo
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
function sendRequest(apiOperator, responseSectionRef) {
|
|
572
|
+
let reuqestUrl = getRequestUrl(apiOperator);
|
|
573
|
+
const result = checkIfParameter(apiOperator);
|
|
574
|
+
|
|
575
|
+
let header = result.hasRequestBody ? 'application/json' :
|
|
576
|
+
(result.hasRequestFormData ? 'application/x-www-form-urlencoded' : 'application/json');
|
|
577
|
+
let headers = {
|
|
578
|
+
'Content-Type': header
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
//TODO
|
|
582
|
+
if (apiOperator.custom) {
|
|
583
|
+
for (let index = 0; index < apiOperator.apiDetailInfo.customHeaderparameters.length; index++) {
|
|
584
|
+
const paras = apiOperator.apiDetailInfo.customHeaderparameters[index];
|
|
585
|
+
if (paras.name != '' && paras.value != '' && paras.name != null && paras.value != null) {
|
|
586
|
+
headers[paras.name] = paras.value
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
let body = result.hasRequestBody ? apiOperator.requestBody :
|
|
592
|
+
(result.hasRequestFormData ? getRequestFormData(apiOperator.apiDetailInfo) : null);
|
|
593
|
+
|
|
594
|
+
//TODO
|
|
595
|
+
if (apiOperator.custom) {
|
|
596
|
+
if (apiOperator.method.toUpperCase() == "POST" || apiOperator.method.toUpperCase() == "PUT") {
|
|
597
|
+
body = apiOperator.apiDetailInfo.bodyModel;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
apiOperator.ifSendingRequest = true;
|
|
602
|
+
const startTime = Date.now(); // 记录开始时间
|
|
603
|
+
|
|
604
|
+
apiOperator.controller = new AbortController();
|
|
605
|
+
const signal = apiOperator.controller.signal;
|
|
606
|
+
|
|
607
|
+
//正在发送请求时创建遮罩层
|
|
608
|
+
const overlayLayerContainer = createRequestOverlayLayer(apiOperator, responseSectionRef);
|
|
609
|
+
|
|
610
|
+
// 使用 fetch 发送请求,并传递 signal
|
|
611
|
+
fetch(reuqestUrl, {
|
|
612
|
+
method: apiOperator.method.toUpperCase(),
|
|
613
|
+
headers: headers,
|
|
614
|
+
body: body != null ? JSON.stringify(body) : null,
|
|
615
|
+
signal: signal
|
|
616
|
+
})
|
|
617
|
+
.then(response => {
|
|
618
|
+
if (!response.ok) {
|
|
619
|
+
apiOperator.response = {
|
|
620
|
+
status: response.status,
|
|
621
|
+
statusText: response.statusText
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const endTime = Date.now(); // 即使在错误的情况下也记录结束时间
|
|
625
|
+
apiOperator.requestDuration = formatDuration(endTime - startTime);
|
|
626
|
+
apiOperator.ifSendingRequest = false;
|
|
627
|
+
// apiOperator.responseJsoneditor.value = "";
|
|
628
|
+
throw new Error('Network response was not ok.');
|
|
629
|
+
}
|
|
630
|
+
const endTime = Date.now(); // 记录结束时间
|
|
631
|
+
apiOperator.requestDuration = formatDuration(endTime - startTime); // 计算耗时
|
|
632
|
+
|
|
633
|
+
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
634
|
+
responsebodyElement.removeChild(overlayLayerContainer);
|
|
635
|
+
|
|
636
|
+
apiOperator.ifSendingRequest = false;
|
|
637
|
+
apiOperator.response = {
|
|
638
|
+
status: response.status,
|
|
639
|
+
statusText: response.statusText
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// 在responseSectionRef元素范围内查找TimeStatus元素
|
|
643
|
+
const timeStatusElement = responseSectionRef.querySelector('[data-layer="TimeStatus"]');
|
|
644
|
+
if (timeStatusElement) {
|
|
645
|
+
updateTimeStatus(timeStatusElement, apiOperator);
|
|
646
|
+
} else {
|
|
647
|
+
console.log("在reqresponse范围内未找到TimeStatus元素");
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
let responseClone = response.clone();
|
|
651
|
+
return response.json() // 解析为json
|
|
652
|
+
.catch(error => {
|
|
653
|
+
// 如果解析 JSON 失败,则回退到文本解析
|
|
654
|
+
return responseClone.text();
|
|
655
|
+
});
|
|
656
|
+
})
|
|
657
|
+
.then(data => {
|
|
658
|
+
apiOperator.gotResponse = true;
|
|
659
|
+
// 此时 data 可能是 JSON 对象,也可能是文本字符串
|
|
660
|
+
if (typeof data === 'object') {
|
|
661
|
+
// 假设 data 是 JSON 对象,你可以在这里处理它
|
|
662
|
+
console.log('Received JSON:', data);
|
|
663
|
+
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
664
|
+
responsebodyElement.textContent = JSON.stringify(data, null, 4)
|
|
665
|
+
} else {
|
|
666
|
+
// 假设 data 是文本字符串,你可以在这里处理它
|
|
667
|
+
console.log('Received text:', data);
|
|
668
|
+
responsebodyElement.textContent = data;
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
.catch(error => {
|
|
672
|
+
// 错误处理
|
|
673
|
+
console.error('There has been a problem with your fetch operation:', error);
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function updateTimeStatus(timeStatus, apiOperator) {
|
|
678
|
+
timeStatus.textContent
|
|
679
|
+
= `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
683
|
+
// 创建主容器
|
|
684
|
+
const container = document.createElement('div');
|
|
685
|
+
Object.assign(container.style, {
|
|
686
|
+
position: 'absolute',
|
|
687
|
+
top: 0,
|
|
688
|
+
width: '100%',
|
|
689
|
+
height: '100%',
|
|
690
|
+
display: 'flex',
|
|
691
|
+
justifyContent: 'center',
|
|
692
|
+
alignItems: 'center',
|
|
693
|
+
backgroundColor: 'rgb(255, 255, 255)',
|
|
694
|
+
opacity: 0.8
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
// 创建内容容器
|
|
698
|
+
const contentDiv = document.createElement('div');
|
|
699
|
+
Object.assign(contentDiv.style, {
|
|
700
|
+
display: 'flex',
|
|
701
|
+
gap: '5px',
|
|
702
|
+
alignItems: 'center',
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
// 创建文本div
|
|
706
|
+
const textDiv = document.createElement('div');
|
|
707
|
+
textDiv.textContent = 'Sending request...';
|
|
708
|
+
|
|
709
|
+
// 创建取消按钮
|
|
710
|
+
const cancelBtn = document.createElement('button');
|
|
711
|
+
cancelBtn.className = 'request-cancel-btn';
|
|
712
|
+
Object.assign(cancelBtn.style, {
|
|
713
|
+
border: '0px'
|
|
714
|
+
});
|
|
715
|
+
cancelBtn.textContent = 'Cancel';
|
|
716
|
+
|
|
717
|
+
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
718
|
+
// 组装DOM结构
|
|
719
|
+
contentDiv.appendChild(textDiv);
|
|
720
|
+
contentDiv.appendChild(cancelBtn);
|
|
721
|
+
container.appendChild(contentDiv);
|
|
722
|
+
responsebodyElement.appendChild(container);
|
|
723
|
+
|
|
724
|
+
// 添加点击事件
|
|
725
|
+
cancelBtn.addEventListener('click', (e) => {
|
|
726
|
+
// 如果你想取消请求,调用 controller 的 abort 方法
|
|
727
|
+
if (apiOperator.controller) {
|
|
728
|
+
apiOperator.controller.abort();
|
|
729
|
+
apiOperator.ifSendingRequest = false;
|
|
730
|
+
container.style.display = 'none';
|
|
731
|
+
responsebodyElement.removeChild(container);
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
return container
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
function checkIfParameter(apiOperator) {
|
|
739
|
+
let hasRequestBody = false;
|
|
740
|
+
let hasRequestFormData = false;
|
|
741
|
+
const parameters = apiOperator.apiDetailInfo.parameters;
|
|
742
|
+
if (parameters) {
|
|
743
|
+
for (let index = 0; index < parameters.length; index++) {
|
|
744
|
+
const parameter = parameters[index];
|
|
745
|
+
if (parameter.in == "query" || parameter.in == "path") {
|
|
746
|
+
} else if (parameter.in == "body") {
|
|
747
|
+
hasRequestBody = true;
|
|
748
|
+
parameter.name = parameter.name.charAt(0).toUpperCase() + parameter.name.slice(1);
|
|
749
|
+
} else if (parameter.in == "formData") {
|
|
750
|
+
hasRequestFormData = true;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
//support openapi 3.0
|
|
756
|
+
const requestBody = apiOperator.apiDetailInfo.requestBody;
|
|
757
|
+
if (requestBody) {
|
|
758
|
+
hasRequestBody = true;
|
|
759
|
+
}
|
|
760
|
+
// 返回包含两个状态的对象
|
|
761
|
+
return { hasRequestBody, hasRequestFormData };
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
function formatDuration(milliseconds) {
|
|
765
|
+
let totalSeconds = Math.floor(milliseconds / 1000);
|
|
766
|
+
let seconds = totalSeconds % 60;
|
|
767
|
+
let minutes = Math.floor(totalSeconds / 60) % 60;
|
|
768
|
+
let hours = Math.floor(totalSeconds / (60 * 60));
|
|
769
|
+
|
|
770
|
+
// 毫秒部分
|
|
771
|
+
let millisecondsPart = Math.floor(milliseconds % 1000);
|
|
772
|
+
// 毫秒不足三位时前面补0
|
|
773
|
+
millisecondsPart = millisecondsPart.toString().padStart(3, '0');
|
|
774
|
+
|
|
775
|
+
// 时分秒不足两位时前面补0
|
|
776
|
+
hours = hours.toString().padStart(2, '0');
|
|
777
|
+
minutes = minutes.toString().padStart(2, '0');
|
|
778
|
+
seconds = seconds.toString().padStart(2, '0');
|
|
779
|
+
|
|
780
|
+
// 返回格式化的字符串
|
|
781
|
+
return `${hours}h${minutes}m${seconds}s${millisecondsPart}ms`;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function getRequestUrl(apiOperator) {
|
|
785
|
+
let reuqestUrl = apiOperator.url;
|
|
786
|
+
|
|
787
|
+
const requestParameters = apiOperator.apiDetailInfo.parameters || [];
|
|
788
|
+
if (requestParameters == null) {
|
|
789
|
+
return reuqestUrl;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
for (const element of requestParameters) {
|
|
793
|
+
if (element.in == "path") {
|
|
794
|
+
reuqestUrl = reuqestUrl.replace("{" + element.name + "}", element.value);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
let queryParams = getQueryParams(apiOperator, requestParameters);
|
|
799
|
+
reuqestUrl = queryParams.length > 0 ? (reuqestUrl + "?" + queryParams.join("&")) : reuqestUrl;
|
|
800
|
+
|
|
801
|
+
return reuqestUrl;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
function getQueryParams(apiOperator, requestParameters) {
|
|
805
|
+
let queryParams = [];
|
|
806
|
+
for (const element of requestParameters) {
|
|
807
|
+
if (element.in == "query") {
|
|
808
|
+
if (element.type == "array" || (element.schema != null && element.schema.type == 'array')) {
|
|
809
|
+
if (element.value != null) {
|
|
810
|
+
for (let index = 0; index < element.value.length; index++) {
|
|
811
|
+
queryParams.push(element.name + "=" + element.value[index].value);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
} else {
|
|
815
|
+
queryParams.push(element.name + "=" + element.value);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (apiOperator.custom) {
|
|
821
|
+
for (let index = 0; index < apiOperator.apiDetailInfo.customQueryparameters.length; index++) {
|
|
822
|
+
const paras = apiOperator.apiDetailInfo.customQueryparameters[index];
|
|
823
|
+
if (paras.name != '' && paras.value != '' && paras.name != null && paras.value != null) {
|
|
824
|
+
queryParams.push(paras.name + "=" + paras.value)
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
return queryParams;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function getRequestFormData(apiDetailInfo) {
|
|
833
|
+
let formData = '';
|
|
834
|
+
const requestParameters = apiDetailInfo.parameters;
|
|
835
|
+
if (requestParameters == null) {
|
|
836
|
+
return "";
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
let first = 0;
|
|
840
|
+
for (const element of requestParameters) {
|
|
841
|
+
if (element.in == "formData") {
|
|
842
|
+
if (first == 0) {
|
|
843
|
+
formData = element.name + "=" + element.value;
|
|
844
|
+
} else {
|
|
845
|
+
formData = formData + "&" + element.name + "=" + element.value;
|
|
846
|
+
}
|
|
847
|
+
first++;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return formData;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
function createSvg() {
|
|
856
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
857
|
+
svg.setAttribute('width', '21');
|
|
858
|
+
svg.setAttribute('height', '22');
|
|
859
|
+
svg.setAttribute('viewBox', '0 0 21 22');
|
|
860
|
+
svg.setAttribute('fill', 'none');
|
|
861
|
+
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
862
|
+
|
|
863
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
864
|
+
path.setAttribute('d', 'M5.5 8.5L10.5 13.5L15.5 8.5');
|
|
865
|
+
path.setAttribute('stroke', 'var(--Labels---Vibrant---Controls-Primary--, #404040)');
|
|
866
|
+
path.setAttribute('stroke-width', '2');
|
|
867
|
+
path.setAttribute('stroke-linecap', 'round');
|
|
868
|
+
path.setAttribute('stroke-linejoin', 'round');
|
|
869
|
+
|
|
870
|
+
svg.appendChild(path);
|
|
871
|
+
return svg;
|
|
872
|
+
}
|