api-render-ui 1.1.1 → 1.1.3
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/index.cjs +615 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +615 -143
- package/dist/index.js.map +1 -1
- package/example/animal.html +1137 -254
- package/package.json +1 -1
- package/src/api-render-ui.css +3 -1
- package/src/api-render-ui.ts +880 -170
- package/src/inlined-styles.ts +3 -1
package/dist/index.js
CHANGED
|
@@ -186,10 +186,12 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
186
186
|
align-items: center;
|
|
187
187
|
align-self: stretch;
|
|
188
188
|
display: inline-flex;
|
|
189
|
-
height: 114px;
|
|
190
189
|
justify-content: flex-start;
|
|
191
190
|
padding-right: 5px
|
|
192
191
|
}
|
|
192
|
+
.codigma-apiunit-request-body-info {
|
|
193
|
+
align-self: stretch;
|
|
194
|
+
}
|
|
193
195
|
.codigma-apiunit-parakeyvalues {
|
|
194
196
|
align-items: flex-start;
|
|
195
197
|
align-self: stretch;
|
|
@@ -263,7 +265,7 @@ var ApiRenderer = class _ApiRenderer {
|
|
|
263
265
|
}, options);
|
|
264
266
|
this.container = null;
|
|
265
267
|
}
|
|
266
|
-
render(apiSpec, renderUnit = false) {
|
|
268
|
+
render(apiSpec, currentServer, serviceName, renderUnit = false) {
|
|
267
269
|
const appendInlineStyle = (text) => {
|
|
268
270
|
if (!_ApiRenderer.globalStyleInjected) {
|
|
269
271
|
const styleEl = document.createElement("style");
|
|
@@ -280,7 +282,7 @@ var ApiRenderer = class _ApiRenderer {
|
|
|
280
282
|
}
|
|
281
283
|
if (apiSpec["openapi"] && apiSpec["openapi"].startsWith("3.") || apiSpec["swagger"] && apiSpec["swagger"].startsWith("2.")) {
|
|
282
284
|
const countApi = countOpenAPI(apiSpec);
|
|
283
|
-
const apiOperatorList =
|
|
285
|
+
const apiOperatorList = parseOpenApiSpec(apiSpec, currentServer, serviceName);
|
|
284
286
|
if (countApi == 1 && renderUnit) {
|
|
285
287
|
this.container = createApiUnit(apiOperatorList[0]);
|
|
286
288
|
} else {
|
|
@@ -345,12 +347,47 @@ var ApiRenderer = class _ApiRenderer {
|
|
|
345
347
|
mountElement.appendChild(this.container);
|
|
346
348
|
}
|
|
347
349
|
};
|
|
350
|
+
var auths = [
|
|
351
|
+
{
|
|
352
|
+
value: "No Auth"
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
value: "Basic Auth",
|
|
356
|
+
parameters: [
|
|
357
|
+
{
|
|
358
|
+
name: "userName",
|
|
359
|
+
value: ""
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: "password",
|
|
363
|
+
value: ""
|
|
364
|
+
}
|
|
365
|
+
]
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
value: "OAuth 2.0"
|
|
369
|
+
}
|
|
370
|
+
];
|
|
371
|
+
var grantTypes = [
|
|
372
|
+
{ value: "authorization_code" },
|
|
373
|
+
{ value: "Implicit" },
|
|
374
|
+
{ value: "Resource Owner Password Credentials" },
|
|
375
|
+
{ value: "client_credentials" }
|
|
376
|
+
];
|
|
377
|
+
var clientAuthenticationOpts = [
|
|
378
|
+
{ value: "Headers", displayName: "Send credentials in headers" },
|
|
379
|
+
{ value: "Body", displayName: "Send credentials in body" }
|
|
380
|
+
];
|
|
381
|
+
var consumeOpts = [
|
|
382
|
+
{ value: "None" },
|
|
383
|
+
{ value: "application/json" },
|
|
384
|
+
{ value: "application/xml" },
|
|
385
|
+
{ value: "application/x-www-form-urlencoded" },
|
|
386
|
+
{ value: "multipart/form-data" },
|
|
387
|
+
{ value: "text/plain" }
|
|
388
|
+
];
|
|
348
389
|
function renderApiUnit(apiOperator, containerRef, elementMap) {
|
|
349
390
|
return function(evt) {
|
|
350
|
-
console.log("\u70B9\u51FB\u7684API\u64CD\u4F5C\uFF1A");
|
|
351
|
-
console.log("\u65B9\u6CD5:", apiOperator.method);
|
|
352
|
-
console.log("URL:", apiOperator.url);
|
|
353
|
-
console.log("------------------------");
|
|
354
391
|
const currentTarget = evt.currentTarget;
|
|
355
392
|
if (elementMap.has(currentTarget)) {
|
|
356
393
|
const newElement = elementMap.get(currentTarget);
|
|
@@ -381,7 +418,7 @@ function createApiUnit(apiOperator) {
|
|
|
381
418
|
const paramSection = createParamSection(apiOperator);
|
|
382
419
|
const headerSection = createSectionHeader(apiOperator);
|
|
383
420
|
const authSection = createSectionAuth(apiOperator);
|
|
384
|
-
const bodySection = createSectionRequestBody(apiOperator
|
|
421
|
+
const bodySection = createSectionRequestBody(apiOperator);
|
|
385
422
|
reqContent.append(paramSection, headerSection, authSection, bodySection);
|
|
386
423
|
apiContainer.appendChild(reqContent);
|
|
387
424
|
apiContainer.appendChild(responseSection);
|
|
@@ -412,7 +449,6 @@ function createReqOperator(apiOperator) {
|
|
|
412
449
|
reqUrl.className = "Requrl codigma-apiunit-requrl";
|
|
413
450
|
reqUrl.value = apiOperator.url;
|
|
414
451
|
reqUrl.addEventListener("input", (e) => {
|
|
415
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
416
452
|
apiOperator.url = e.target.value;
|
|
417
453
|
});
|
|
418
454
|
reqOperator.appendChild(reqUrl);
|
|
@@ -425,7 +461,6 @@ function createReqOperator(apiOperator) {
|
|
|
425
461
|
sendText.textContent = "Send";
|
|
426
462
|
sendButton.appendChild(sendText);
|
|
427
463
|
sendButton.addEventListener("click", (e) => {
|
|
428
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
429
464
|
const respRef = apiOperator._responseSectionRef || null;
|
|
430
465
|
sendRequest(apiOperator, respRef);
|
|
431
466
|
});
|
|
@@ -492,17 +527,135 @@ function createSectionAuth(apiOperator) {
|
|
|
492
527
|
const authValues = document.createElement("div");
|
|
493
528
|
authValues.setAttribute("data-layer", "paraKeyValues");
|
|
494
529
|
authValues.className = "Parakeyvalues codigma-apiunit-parakeyvalues";
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
530
|
+
const authTypeRow = createSelectRow("Authorization Type", auths);
|
|
531
|
+
authTypeRow.children[1].addEventListener("change", function(event) {
|
|
532
|
+
authValues && Array.from(authValues.children).slice(1).forEach((el) => el.remove());
|
|
533
|
+
const auth = auths[event.target.selectedIndex];
|
|
534
|
+
if (auth.value == "No Auth") {
|
|
535
|
+
} else if (auth.value == "Basic Auth") {
|
|
536
|
+
apiOperator.auth = [
|
|
537
|
+
{
|
|
538
|
+
name: "userName",
|
|
539
|
+
value: ""
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
name: "password",
|
|
543
|
+
value: ""
|
|
544
|
+
}
|
|
545
|
+
];
|
|
546
|
+
const authRows = apiOperator.auth.map((parameter) => createRow(parameter));
|
|
547
|
+
authValues.append(...authRows);
|
|
548
|
+
} else if (auth.value == "OAuth 2.0") {
|
|
549
|
+
apiOperator.auth = {};
|
|
550
|
+
renderAuthForm(apiOperator, authValues, authTypeRow);
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
authValues.append(authTypeRow);
|
|
502
554
|
authSection.append(authCnr, authValues);
|
|
503
555
|
return authSection;
|
|
504
556
|
}
|
|
505
|
-
function
|
|
557
|
+
function createElement(tag, props = {}, classes = []) {
|
|
558
|
+
const el = document.createElement(tag);
|
|
559
|
+
Object.entries(props).forEach(([key, value]) => el.setAttribute(key, value));
|
|
560
|
+
if (classes.length) el.classList.add(...classes);
|
|
561
|
+
return el;
|
|
562
|
+
}
|
|
563
|
+
function createLabeledInput(apiOperator, labelText, inputId, inputName, modelKey, required = false) {
|
|
564
|
+
const wrapper = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
565
|
+
const label = createElement("label", { for: inputId }, ["type", "codigma-apiunit-send"]);
|
|
566
|
+
label.textContent = labelText + ":";
|
|
567
|
+
const input = createElement("input", {
|
|
568
|
+
type: "text",
|
|
569
|
+
id: inputId,
|
|
570
|
+
name: inputName,
|
|
571
|
+
autocomplete: "off",
|
|
572
|
+
...required ? { required: "true" } : {}
|
|
573
|
+
}, ["Valuetext", "codigma-apiunit-valuetext"]);
|
|
574
|
+
input.value = apiOperator.auth[modelKey] || "";
|
|
575
|
+
input.addEventListener("input", (e) => {
|
|
576
|
+
apiOperator.auth[modelKey] = e.target.value;
|
|
577
|
+
});
|
|
578
|
+
wrapper.appendChild(label);
|
|
579
|
+
wrapper.appendChild(input);
|
|
580
|
+
return wrapper;
|
|
581
|
+
}
|
|
582
|
+
function createSelect(apiOperator, labelText, selectId, options, modelKey, changeHandler) {
|
|
583
|
+
const wrapper = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
584
|
+
const label = createElement("label", { for: selectId }, ["type", "codigma-apiunit-send"]);
|
|
585
|
+
label.textContent = labelText + ":";
|
|
586
|
+
const select = createElement("select", {
|
|
587
|
+
id: selectId,
|
|
588
|
+
name: selectId
|
|
589
|
+
}, []);
|
|
590
|
+
options.forEach((opt) => {
|
|
591
|
+
const option = createElement("option", { value: opt.value });
|
|
592
|
+
option.textContent = opt.displayName || opt.value;
|
|
593
|
+
select.appendChild(option);
|
|
594
|
+
});
|
|
595
|
+
select.value = apiOperator.auth[modelKey] || options[0]?.value || "";
|
|
596
|
+
select.addEventListener("change", (e) => {
|
|
597
|
+
const val = e.target.value;
|
|
598
|
+
changeHandler(val);
|
|
599
|
+
});
|
|
600
|
+
wrapper.appendChild(label);
|
|
601
|
+
wrapper.appendChild(select);
|
|
602
|
+
return wrapper;
|
|
603
|
+
}
|
|
604
|
+
function renderAuthForm(apiOperator, authValues, authTypeRow) {
|
|
605
|
+
authValues.innerHTML = "";
|
|
606
|
+
authValues.append(authTypeRow);
|
|
607
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Token", "token", "token", "token", true));
|
|
608
|
+
authValues.appendChild(
|
|
609
|
+
createSelect(
|
|
610
|
+
apiOperator,
|
|
611
|
+
"Grant Type",
|
|
612
|
+
"grantType",
|
|
613
|
+
grantTypes,
|
|
614
|
+
"grantType",
|
|
615
|
+
(value) => {
|
|
616
|
+
apiOperator.auth.grantType = value;
|
|
617
|
+
renderAuthForm(apiOperator, authValues, authTypeRow);
|
|
618
|
+
}
|
|
619
|
+
)
|
|
620
|
+
);
|
|
621
|
+
const gt = apiOperator.auth.grantType || "authorization_code";
|
|
622
|
+
if (gt === "authorization_code" || gt === "Implicit") {
|
|
623
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Authorization Endpoint", "authorizationEndpoint", "authorizationEndpoint", "authorizationEndpoint", true));
|
|
624
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Redirect URL", "RedirectURI", "RedirectURI", "redirectURI", true));
|
|
625
|
+
}
|
|
626
|
+
if (gt === "authorization_code" || gt === "client_credentials" || gt === "Resource Owner Password Credentials") {
|
|
627
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Token Endpoint", "TokenEndpoint", "TokenEndpoint", "tokenEndpoint", true));
|
|
628
|
+
}
|
|
629
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Client ID", "ClientID", "ClientID", "clientId", true));
|
|
630
|
+
if (gt === "authorization_code" || gt === "client_credentials" || gt === "Resource Owner Password Credentials") {
|
|
631
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Client Secret", "ClientSecret", "ClientSecret", "clientSecret", true));
|
|
632
|
+
}
|
|
633
|
+
if (gt === "Resource Owner Password Credentials") {
|
|
634
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Username", "Username", "Username", "username", true));
|
|
635
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Password", "Password", "Password", "password", true));
|
|
636
|
+
}
|
|
637
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Scopes", "Scopes", "Scopes", "scopes", true));
|
|
638
|
+
authValues.appendChild(
|
|
639
|
+
createSelect(
|
|
640
|
+
apiOperator,
|
|
641
|
+
"Client Authentication",
|
|
642
|
+
"clientAuthentication",
|
|
643
|
+
clientAuthenticationOpts,
|
|
644
|
+
"clientAuthentication",
|
|
645
|
+
(value) => {
|
|
646
|
+
apiOperator.auth.clientAuthentication = value;
|
|
647
|
+
}
|
|
648
|
+
)
|
|
649
|
+
);
|
|
650
|
+
const buttonWrapper = createElement("div", {}, ["parameter-item"]);
|
|
651
|
+
const generateBtn = createElement("button", {}, ["parameter-button"]);
|
|
652
|
+
generateBtn.type = "button";
|
|
653
|
+
generateBtn.textContent = "Generate Token";
|
|
654
|
+
generateBtn.addEventListener("click", () => generateOAuth2Token(apiOperator));
|
|
655
|
+
buttonWrapper.appendChild(generateBtn);
|
|
656
|
+
authValues.appendChild(buttonWrapper);
|
|
657
|
+
}
|
|
658
|
+
function createSectionRequestBody(apiOperator) {
|
|
506
659
|
const bodySection = document.createElement("div");
|
|
507
660
|
bodySection.setAttribute("data-layer", "request-body-section");
|
|
508
661
|
bodySection.className = "RequestBodySection codigma-apiunit-request-body-section";
|
|
@@ -515,13 +668,108 @@ function createSectionRequestBody(requestBody) {
|
|
|
515
668
|
bodyText.textContent = "Body";
|
|
516
669
|
bodyCnr.appendChild(bodyText);
|
|
517
670
|
bodySection.appendChild(bodyCnr);
|
|
518
|
-
|
|
519
|
-
bodyValue.setAttribute("data-layer", "bodyTextValue");
|
|
520
|
-
bodyValue.className = "Id0CategoryId0NameNamePhotourlsTagsId0NameStatusAvailable codigma-apiunit-parakeyvalues";
|
|
521
|
-
bodyValue.value = JSON.stringify(requestBody);
|
|
522
|
-
bodySection.appendChild(bodyValue);
|
|
671
|
+
renderConsumeSection(apiOperator, bodySection, bodyCnr);
|
|
523
672
|
return bodySection;
|
|
524
673
|
}
|
|
674
|
+
function createConsumeSelect(apiOperator, container, bodyCnr) {
|
|
675
|
+
const wrapper = createElement("div");
|
|
676
|
+
const label = createElement("label");
|
|
677
|
+
label.style.margin = "0 1rem";
|
|
678
|
+
label.textContent = "Content-Type";
|
|
679
|
+
const select = createElement("select");
|
|
680
|
+
select.style.width = "18rem";
|
|
681
|
+
consumeOpts.forEach((opt) => {
|
|
682
|
+
const option = document.createElement("option");
|
|
683
|
+
option.value = opt.value;
|
|
684
|
+
option.textContent = opt.value;
|
|
685
|
+
select.appendChild(option);
|
|
686
|
+
});
|
|
687
|
+
select.value = apiOperator.currentConsume || getCurrentConsume(apiOperator);
|
|
688
|
+
select.addEventListener("change", (e) => {
|
|
689
|
+
const newValue = e.target.value;
|
|
690
|
+
if (apiOperator.currentConsume !== newValue) {
|
|
691
|
+
apiOperator.currentConsume = newValue;
|
|
692
|
+
renderConsumeSection(apiOperator, container, bodyCnr);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
wrapper.appendChild(label);
|
|
696
|
+
wrapper.appendChild(select);
|
|
697
|
+
return wrapper;
|
|
698
|
+
}
|
|
699
|
+
function renderRequestBodyInto(apiOperator, targetDiv) {
|
|
700
|
+
targetDiv.innerHTML = "";
|
|
701
|
+
const ct = apiOperator.currentConsume || getCurrentConsume(apiOperator);
|
|
702
|
+
if (ct === null || ct === "None" || ct === "application/json" || ct === "application/xml" || ct === "text/plain") {
|
|
703
|
+
const mimeType = ct || "None";
|
|
704
|
+
let rawValue = apiOperator.requestBody.content[mimeType];
|
|
705
|
+
if (rawValue == null) {
|
|
706
|
+
rawValue = "";
|
|
707
|
+
apiOperator.requestBody.content[mimeType] = rawValue;
|
|
708
|
+
}
|
|
709
|
+
const textarea = createElement("textarea", {}, []);
|
|
710
|
+
textarea.style.width = "100%";
|
|
711
|
+
textarea.style.height = "200px";
|
|
712
|
+
textarea.style.fontFamily = "monospace";
|
|
713
|
+
textarea.style.fontSize = "14px";
|
|
714
|
+
textarea.placeholder = `Enter ${mimeType} body...`;
|
|
715
|
+
textarea.value = rawValue;
|
|
716
|
+
textarea.addEventListener("input", () => {
|
|
717
|
+
apiOperator.requestBody.content[mimeType] = textarea.value;
|
|
718
|
+
console.log(`Content updated for ${mimeType}:`, textarea.value);
|
|
719
|
+
});
|
|
720
|
+
targetDiv.appendChild(textarea);
|
|
721
|
+
} else if ((ct === "application/x-www-form-urlencoded" || ct === "multipart/form-data") && apiOperator.requestBody.content && Array.isArray(apiOperator.requestBody.content[ct])) {
|
|
722
|
+
const params = apiOperator.requestBody.content[ct];
|
|
723
|
+
params.forEach((param, index) => {
|
|
724
|
+
const item = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
725
|
+
const label = createElement("label", { for: `param-${Date.now()}-${index}` }, ["petId", "codigma-apiunit-send"]);
|
|
726
|
+
label.textContent = `${param.name}:`;
|
|
727
|
+
const input = createElement("input", {
|
|
728
|
+
type: param.uiType || "text",
|
|
729
|
+
// 使用时间戳+索引避免 id 冲突(仅用于 label for)
|
|
730
|
+
id: `param-${Date.now()}-${index}`,
|
|
731
|
+
name: "name"
|
|
732
|
+
}, ["Valuetext", "codigma-apiunit-valuetext"]);
|
|
733
|
+
input.value = param.value || "";
|
|
734
|
+
input.autocomplete = "off";
|
|
735
|
+
input.required = true;
|
|
736
|
+
input.addEventListener("keydown", (e) => {
|
|
737
|
+
setEditStatus(e, true);
|
|
738
|
+
});
|
|
739
|
+
input.addEventListener("input", () => {
|
|
740
|
+
param.value = input.value;
|
|
741
|
+
});
|
|
742
|
+
item.appendChild(label);
|
|
743
|
+
item.appendChild(input);
|
|
744
|
+
targetDiv.appendChild(item);
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function getCurrentConsume(apiOperator) {
|
|
749
|
+
if (!apiOperator.requestBody) {
|
|
750
|
+
apiOperator.requestBody = { content: {} };
|
|
751
|
+
}
|
|
752
|
+
if (!apiOperator.requestBody.content) {
|
|
753
|
+
apiOperator.requestBody.content = {};
|
|
754
|
+
}
|
|
755
|
+
const keys = Object.keys(apiOperator.requestBody.content);
|
|
756
|
+
const ct = apiOperator.currentConsume = keys.length > 0 ? keys[0] : "None";
|
|
757
|
+
return ct;
|
|
758
|
+
}
|
|
759
|
+
function setEditStatus(event, status) {
|
|
760
|
+
console.log("setEditStatus called:", event.key, status);
|
|
761
|
+
}
|
|
762
|
+
function renderConsumeSection(apiOperator, container, bodyCnr) {
|
|
763
|
+
container.innerHTML = "";
|
|
764
|
+
container.appendChild(bodyCnr);
|
|
765
|
+
const wrapperDiv = createElement("div", {}, ["codigma-apiunit-parakeyvalues"]);
|
|
766
|
+
const selectWrapper = createConsumeSelect(apiOperator, container, bodyCnr);
|
|
767
|
+
wrapperDiv.appendChild(selectWrapper);
|
|
768
|
+
const reqBodyContainer = createElement("div", {}, ["codigma-apiunit-request-body-info"]);
|
|
769
|
+
renderRequestBodyInto(apiOperator, reqBodyContainer);
|
|
770
|
+
wrapperDiv.appendChild(reqBodyContainer);
|
|
771
|
+
container.appendChild(wrapperDiv);
|
|
772
|
+
}
|
|
525
773
|
function createSectionResponse(apiOperator) {
|
|
526
774
|
const responseSection = document.createElement("div");
|
|
527
775
|
responseSection.setAttribute("data-layer", "reqresponse");
|
|
@@ -556,6 +804,9 @@ function createTimeStatusElement(apiOperator) {
|
|
|
556
804
|
updateTimeStatus(timeStatus, apiOperator);
|
|
557
805
|
return timeStatus;
|
|
558
806
|
}
|
|
807
|
+
function updateTimeStatus(timeStatus, apiOperator) {
|
|
808
|
+
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
809
|
+
}
|
|
559
810
|
function createRow(parameter) {
|
|
560
811
|
const petIdRow = document.createElement("div");
|
|
561
812
|
petIdRow.setAttribute("data-layer", "keyValue");
|
|
@@ -569,7 +820,6 @@ function createRow(parameter) {
|
|
|
569
820
|
petIdValue.className = "Valuetext codigma-apiunit-valuetext";
|
|
570
821
|
petIdValue.value = parameter["value"] || "";
|
|
571
822
|
petIdValue.addEventListener("input", (e) => {
|
|
572
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
573
823
|
parameter["value"] = e.target.value;
|
|
574
824
|
});
|
|
575
825
|
petIdRow.append(petIdLabel, petIdValue);
|
|
@@ -583,31 +833,24 @@ function createInputElement() {
|
|
|
583
833
|
inputText.setAttribute("autocomplete", "off");
|
|
584
834
|
return inputText;
|
|
585
835
|
}
|
|
586
|
-
function createSelectRow(
|
|
836
|
+
function createSelectRow(name, args) {
|
|
587
837
|
const container = document.createElement("div");
|
|
588
838
|
container.setAttribute("data-layer", "keyValue");
|
|
589
839
|
container.className = "Keyvalue codigma-apiunit-keyvalue";
|
|
590
840
|
const typeLabel = document.createElement("div");
|
|
591
|
-
typeLabel.setAttribute("data-layer",
|
|
841
|
+
typeLabel.setAttribute("data-layer", name);
|
|
592
842
|
typeLabel.className = "type codigma-apiunit-send";
|
|
593
|
-
typeLabel.textContent = "
|
|
843
|
+
typeLabel.textContent = name + ":";
|
|
594
844
|
const selectElement = document.createElement("select");
|
|
595
845
|
selectElement.name = "text-select";
|
|
596
846
|
selectElement.label = "text-select";
|
|
597
847
|
selectElement.setAttribute("data-layer", "valueText");
|
|
598
|
-
|
|
848
|
+
args.forEach((auth) => {
|
|
599
849
|
const option1 = document.createElement("option");
|
|
600
|
-
option1.value = auth["
|
|
601
|
-
option1.textContent = auth["
|
|
850
|
+
option1.value = auth["value"];
|
|
851
|
+
option1.textContent = auth["displayName"] != null || auth["label"] != null ? auth["displayName"] || auth["label"] : auth["value"];
|
|
602
852
|
selectElement.appendChild(option1);
|
|
603
853
|
});
|
|
604
|
-
selectElement.addEventListener("change", function(event) {
|
|
605
|
-
authValues && Array.from(authValues.children).slice(1).forEach((el) => el.remove());
|
|
606
|
-
const auth = auths[event.target.selectedIndex];
|
|
607
|
-
let parameters = auth.parameters || [];
|
|
608
|
-
const authRows = parameters.map((parameter) => createRow(parameter));
|
|
609
|
-
authValues.append(...authRows);
|
|
610
|
-
});
|
|
611
854
|
container.appendChild(typeLabel);
|
|
612
855
|
container.appendChild(selectElement);
|
|
613
856
|
return container;
|
|
@@ -618,58 +861,153 @@ function isPathOrQueryParam(param) {
|
|
|
618
861
|
function isHeaderParam(param) {
|
|
619
862
|
return param.in === "header";
|
|
620
863
|
}
|
|
621
|
-
function
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
864
|
+
async function generateOAuth2Token(apiInfo) {
|
|
865
|
+
const accessToken = await getAccessToken(apiInfo);
|
|
866
|
+
apiInfo.auth.token = accessToken;
|
|
867
|
+
}
|
|
868
|
+
async function getAccessToken(apiInfo) {
|
|
869
|
+
const auth = apiInfo.auth;
|
|
870
|
+
if (auth == null) {
|
|
871
|
+
throw new Error("OAuth2.0\u8BA4\u8BC1\u4FE1\u606F\u672A\u914D\u7F6E");
|
|
872
|
+
}
|
|
873
|
+
const CLIENT_ID = auth.clientId;
|
|
874
|
+
const CLIENT_SECRET = auth.clientSecret;
|
|
875
|
+
const SCOPE = auth.scopes;
|
|
876
|
+
if (apiInfo.auth.grantType == "client_credentials") {
|
|
877
|
+
try {
|
|
878
|
+
console.log("\u6B63\u5728\u83B7\u53D6\u8BBF\u95EE\u4EE4\u724C...");
|
|
879
|
+
const headerParams = {
|
|
880
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
881
|
+
};
|
|
882
|
+
const bodyParams = new URLSearchParams();
|
|
883
|
+
bodyParams.append("grant_type", "client_credentials");
|
|
884
|
+
if (SCOPE) {
|
|
885
|
+
bodyParams.append("scope", SCOPE);
|
|
886
|
+
}
|
|
887
|
+
if (apiInfo.auth.clientAuthentication == "Body") {
|
|
888
|
+
bodyParams.append("client_id", CLIENT_ID);
|
|
889
|
+
bodyParams.append("client_secret", CLIENT_SECRET);
|
|
890
|
+
} else {
|
|
891
|
+
headerParams["Authorization"] = "Basic " + btoa(CLIENT_ID + ":" + CLIENT_SECRET);
|
|
892
|
+
}
|
|
893
|
+
const response = await fetch(auth.tokenEndpoint, {
|
|
894
|
+
method: "POST",
|
|
895
|
+
headers: headerParams,
|
|
896
|
+
body: bodyParams.toString()
|
|
897
|
+
});
|
|
898
|
+
if (!response.ok) {
|
|
899
|
+
const errorData = await response.json().catch(() => ({}));
|
|
900
|
+
throw new Error(`\u83B7\u53D6\u4EE4\u724C\u5931\u8D25: ${response.status} ${response.statusText}. ${JSON.stringify(errorData)}`);
|
|
901
|
+
}
|
|
902
|
+
const tokenData = await response.json();
|
|
903
|
+
console.log("\u4EE4\u724C\u83B7\u53D6\u6210\u529F:", tokenData);
|
|
904
|
+
return tokenData.access_token;
|
|
905
|
+
} catch (error) {
|
|
906
|
+
console.error("\u83B7\u53D6\u8BBF\u95EE\u4EE4\u724C\u65F6\u51FA\u9519:", error);
|
|
907
|
+
throw error;
|
|
908
|
+
}
|
|
909
|
+
} else if (apiInfo.auth.grantType == "Resource Owner Password Credentials") {
|
|
910
|
+
} else if (apiInfo.auth.grantType == "authorization_code") {
|
|
911
|
+
let getUrlParams2 = function() {
|
|
912
|
+
const params = new URLSearchParams(window.location.search);
|
|
913
|
+
return Object.fromEntries(params.entries());
|
|
914
|
+
}, redirectToAuth2 = function() {
|
|
915
|
+
const state = Math.random().toString(36).substring(2);
|
|
916
|
+
const nonce = Math.random().toString(36).substring(2);
|
|
917
|
+
const authUrl = new URL(config.authUrl);
|
|
918
|
+
authUrl.searchParams.append("client_id", config.clientId);
|
|
919
|
+
authUrl.searchParams.append("redirect_uri", config.redirectUri);
|
|
920
|
+
authUrl.searchParams.append("response_type", "code");
|
|
921
|
+
authUrl.searchParams.append("scope", config.scope);
|
|
922
|
+
authUrl.searchParams.append("state", state);
|
|
923
|
+
authUrl.searchParams.append("nonce", nonce);
|
|
924
|
+
authUrl.searchParams.append("access_type", "offline");
|
|
925
|
+
const newTab = window.open(authUrl.toString(), "_blank");
|
|
926
|
+
};
|
|
927
|
+
var getUrlParams = getUrlParams2, redirectToAuth = redirectToAuth2;
|
|
928
|
+
const config = {
|
|
929
|
+
clientId: apiInfo.auth.clientId,
|
|
930
|
+
// 替换为你的 client_id
|
|
931
|
+
clientSecret: apiInfo.auth.clientSecret,
|
|
932
|
+
// 替换为你的 client_secret
|
|
933
|
+
redirectUri: apiInfo.auth.redirectURI,
|
|
934
|
+
// 必须与注册的 redirect_uri 一致
|
|
935
|
+
authUrl: apiInfo.auth.authorizationEndpoint,
|
|
936
|
+
tokenUrl: apiInfo.auth.tokenEndpoint,
|
|
937
|
+
scope: apiInfo.auth.scopes
|
|
938
|
+
// 可选: 'openid profile email' 如果服务支持
|
|
939
|
+
};
|
|
940
|
+
redirectToAuth2();
|
|
941
|
+
} else if (apiInfo.auth.grantType == "Implicit") {
|
|
942
|
+
} else {
|
|
625
943
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
944
|
+
}
|
|
945
|
+
function getBodyEditorContent(apiOperator) {
|
|
946
|
+
const ct = apiOperator.currentConsume || "None";
|
|
947
|
+
return apiOperator.requestBody.content[ct];
|
|
948
|
+
}
|
|
949
|
+
var gotResponse = false;
|
|
950
|
+
var ifSendingRequest = false;
|
|
951
|
+
var requestDuration = "0";
|
|
952
|
+
var responseObj = {};
|
|
953
|
+
function sendRequest(apiOperator, responseSectionRef) {
|
|
954
|
+
const apiInfo = apiOperator;
|
|
955
|
+
let reuqestUrl = getRequestUrl(apiInfo);
|
|
956
|
+
let header = apiInfo["parameterHasFormDataVer2"] ? "application/x-www-form-urlencoded" : apiInfo["parameterHasBody"] ? apiInfo["currentConsume"] : "application/json";
|
|
629
957
|
let headers = {
|
|
630
958
|
"Content-Type": header
|
|
631
959
|
};
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
960
|
+
const headerParas = getHeadersParams(apiInfo, apiInfo.rawApiInfo.parameters || []);
|
|
961
|
+
Object.assign(headers, headerParas);
|
|
962
|
+
addAuthHeader(apiInfo, headers);
|
|
963
|
+
let body;
|
|
964
|
+
if (apiInfo.method.toUpperCase() == "POST" || apiInfo.method.toUpperCase() == "PUT") {
|
|
965
|
+
if (apiInfo["currentConsume"] == "application/json" && apiInfo.requestBody != null) {
|
|
966
|
+
body = getBodyEditorContent(apiOperator);
|
|
967
|
+
} else if (apiInfo["parameterHasFormDataVer2"]) {
|
|
968
|
+
body = getRequestFormData(apiInfo.rawApiInfo);
|
|
969
|
+
} else if (apiInfo["currentConsume"] == "application/x-www-form-urlencoded") {
|
|
970
|
+
for (const key of apiInfo["requestBody"]["content"][apiInfo["currentConsume"]]) {
|
|
971
|
+
if (body == null || body == "") {
|
|
972
|
+
body = key.name + "=" + key.value;
|
|
973
|
+
} else {
|
|
974
|
+
body = body + "&" + key.name + "=" + key.value;
|
|
975
|
+
}
|
|
637
976
|
}
|
|
977
|
+
} else {
|
|
978
|
+
body = "";
|
|
638
979
|
}
|
|
980
|
+
} else {
|
|
981
|
+
body = "";
|
|
639
982
|
}
|
|
640
|
-
|
|
641
|
-
if (apiOperator.custom) {
|
|
642
|
-
if (apiOperator.method.toUpperCase() == "POST" || apiOperator.method.toUpperCase() == "PUT") {
|
|
643
|
-
body = apiOperator.requestBody;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
apiOperator.ifSendingRequest = true;
|
|
983
|
+
ifSendingRequest = true;
|
|
647
984
|
const startTime = Date.now();
|
|
648
985
|
apiOperator.controller = new AbortController();
|
|
649
986
|
const signal = apiOperator.controller.signal;
|
|
650
987
|
const overlayLayerContainer = createRequestOverlayLayer(apiOperator, responseSectionRef);
|
|
651
988
|
fetch(reuqestUrl, {
|
|
652
|
-
method:
|
|
989
|
+
method: apiInfo.method.toUpperCase(),
|
|
653
990
|
headers,
|
|
654
|
-
body
|
|
991
|
+
body,
|
|
655
992
|
signal
|
|
656
993
|
}).then((response) => {
|
|
657
994
|
if (!response.ok) {
|
|
658
|
-
|
|
995
|
+
responseObj = {
|
|
659
996
|
status: response.status,
|
|
660
|
-
statusText: response.statusText
|
|
997
|
+
statusText: response.statusText,
|
|
998
|
+
body: ""
|
|
661
999
|
};
|
|
662
1000
|
const endTime2 = Date.now();
|
|
663
|
-
|
|
664
|
-
|
|
1001
|
+
requestDuration = formatDuration(endTime2 - startTime);
|
|
1002
|
+
ifSendingRequest = false;
|
|
665
1003
|
throw new Error("Network response was not ok.");
|
|
666
1004
|
}
|
|
667
1005
|
const endTime = Date.now();
|
|
668
|
-
|
|
1006
|
+
requestDuration = formatDuration(endTime - startTime);
|
|
669
1007
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
670
1008
|
responsebodyElement.removeChild(overlayLayerContainer);
|
|
671
|
-
|
|
672
|
-
|
|
1009
|
+
ifSendingRequest = false;
|
|
1010
|
+
responseObj = {
|
|
673
1011
|
status: response.status,
|
|
674
1012
|
statusText: response.statusText
|
|
675
1013
|
};
|
|
@@ -684,22 +1022,20 @@ function sendRequest(apiOperator, responseSectionRef) {
|
|
|
684
1022
|
return responseClone.text();
|
|
685
1023
|
});
|
|
686
1024
|
}).then((data) => {
|
|
687
|
-
|
|
1025
|
+
gotResponse = true;
|
|
688
1026
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
689
1027
|
if (typeof data === "object") {
|
|
690
1028
|
console.log("Received JSON:", data);
|
|
691
|
-
|
|
1029
|
+
responseObj.body = JSON.stringify(data, null, 4);
|
|
692
1030
|
} else {
|
|
693
1031
|
console.log("Received text:", data);
|
|
694
|
-
|
|
1032
|
+
responseObj.body = data;
|
|
695
1033
|
}
|
|
1034
|
+
responsebodyElement.textContent = responseObj.body;
|
|
696
1035
|
}).catch((error) => {
|
|
697
1036
|
console.error("There has been a problem with your fetch operation:", error);
|
|
698
1037
|
});
|
|
699
1038
|
}
|
|
700
|
-
function updateTimeStatus(timeStatus, apiOperator) {
|
|
701
|
-
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
702
|
-
}
|
|
703
1039
|
function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
704
1040
|
const container = document.createElement("div");
|
|
705
1041
|
Object.assign(container.style, {
|
|
@@ -742,28 +1078,6 @@ function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
|
742
1078
|
});
|
|
743
1079
|
return container;
|
|
744
1080
|
}
|
|
745
|
-
function checkIfParameter(apiOperator) {
|
|
746
|
-
let hasRequestBody = false;
|
|
747
|
-
let hasRequestFormData = false;
|
|
748
|
-
const parameters = apiOperator.rawApiInfo.parameters;
|
|
749
|
-
if (parameters) {
|
|
750
|
-
for (let index = 0; index < parameters.length; index++) {
|
|
751
|
-
const parameter = parameters[index];
|
|
752
|
-
if (parameter.in == "query" || parameter.in == "path") {
|
|
753
|
-
} else if (parameter.in == "body") {
|
|
754
|
-
hasRequestBody = true;
|
|
755
|
-
parameter.name = parameter.name.charAt(0).toUpperCase() + parameter.name.slice(1);
|
|
756
|
-
} else if (parameter.in == "formData") {
|
|
757
|
-
hasRequestFormData = true;
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
const requestBody = apiOperator.rawApiInfo.requestBody;
|
|
762
|
-
if (requestBody) {
|
|
763
|
-
hasRequestBody = true;
|
|
764
|
-
}
|
|
765
|
-
return { hasRequestBody, hasRequestFormData };
|
|
766
|
-
}
|
|
767
1081
|
function formatDuration(milliseconds) {
|
|
768
1082
|
let totalSeconds = Math.floor(milliseconds / 1e3);
|
|
769
1083
|
let seconds = totalSeconds % 60;
|
|
@@ -776,9 +1090,9 @@ function formatDuration(milliseconds) {
|
|
|
776
1090
|
seconds = seconds.toString().padStart(2, "0");
|
|
777
1091
|
return `${hours}h${minutes}m${seconds}s${millisecondsPart}ms`;
|
|
778
1092
|
}
|
|
779
|
-
function getRequestUrl(
|
|
780
|
-
let reuqestUrl =
|
|
781
|
-
const requestParameters =
|
|
1093
|
+
function getRequestUrl(apiInfo) {
|
|
1094
|
+
let reuqestUrl = apiInfo.url;
|
|
1095
|
+
const requestParameters = apiInfo.rawApiInfo.parameters || [];
|
|
782
1096
|
if (requestParameters == null) {
|
|
783
1097
|
return reuqestUrl;
|
|
784
1098
|
}
|
|
@@ -787,11 +1101,45 @@ function getRequestUrl(apiOperator) {
|
|
|
787
1101
|
reuqestUrl = reuqestUrl.replace("{" + element.name + "}", element.value);
|
|
788
1102
|
}
|
|
789
1103
|
}
|
|
790
|
-
let queryParams = getQueryParams(
|
|
1104
|
+
let queryParams = getQueryParams(apiInfo, requestParameters);
|
|
791
1105
|
reuqestUrl = queryParams.length > 0 ? reuqestUrl + "?" + queryParams.join("&") : reuqestUrl;
|
|
792
1106
|
return reuqestUrl;
|
|
793
1107
|
}
|
|
794
|
-
function
|
|
1108
|
+
function addAuthHeader(apiInfo, headers) {
|
|
1109
|
+
const env = isBrowserEnvironment();
|
|
1110
|
+
if (apiInfo.auth.authType == "Basic Auth" && apiInfo.auth != null) {
|
|
1111
|
+
if (env) {
|
|
1112
|
+
const credentials = btoa(`${apiInfo.auth.username}:${apiInfo.auth.passWord}`);
|
|
1113
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
1114
|
+
} else {
|
|
1115
|
+
const buffer = Buffer.from(`${apiInfo.auth.username}:${apiInfo.auth.passWord}`);
|
|
1116
|
+
const credentials = buffer.toString("base64");
|
|
1117
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
1118
|
+
}
|
|
1119
|
+
} else if (apiInfo.auth.authType == "OAuth 2.0" && apiInfo.auth != null) {
|
|
1120
|
+
if (apiInfo.auth.token != null || apiInfo.auth.token != "") {
|
|
1121
|
+
headers["Authorization"] = `Bearer ${apiInfo.auth.token}`;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
function getHeadersParams(apiInfo, requestParameters) {
|
|
1126
|
+
let headersParams = [];
|
|
1127
|
+
for (const element of requestParameters) {
|
|
1128
|
+
if (element.in == "header") {
|
|
1129
|
+
headersParams[element.name] = element.value;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (apiInfo.customHeaderparameters) {
|
|
1133
|
+
for (let index = 0; index < apiInfo.customHeaderparameters.length; index++) {
|
|
1134
|
+
const paras = apiInfo.customHeaderparameters[index];
|
|
1135
|
+
if (paras.name != "" && paras.value != "" && paras.name != null && paras.value != null) {
|
|
1136
|
+
headersParams[paras.name] = paras.value;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return headersParams;
|
|
1141
|
+
}
|
|
1142
|
+
function getQueryParams(apiInfo, requestParameters) {
|
|
795
1143
|
let queryParams = [];
|
|
796
1144
|
for (const element of requestParameters) {
|
|
797
1145
|
if (element.in == "query") {
|
|
@@ -806,9 +1154,9 @@ function getQueryParams(apiOperator, requestParameters) {
|
|
|
806
1154
|
}
|
|
807
1155
|
}
|
|
808
1156
|
}
|
|
809
|
-
if (
|
|
810
|
-
for (let index = 0; index <
|
|
811
|
-
const paras =
|
|
1157
|
+
if (apiInfo.customQueryparameters) {
|
|
1158
|
+
for (let index = 0; index < apiInfo.customQueryparameters.length; index++) {
|
|
1159
|
+
const paras = apiInfo.customQueryparameters[index];
|
|
812
1160
|
if (paras.name != "" && paras.value != "" && paras.name != null && paras.value != null) {
|
|
813
1161
|
queryParams.push(paras.name + "=" + paras.value);
|
|
814
1162
|
}
|
|
@@ -835,6 +1183,15 @@ function getRequestFormData(rawApiInfo) {
|
|
|
835
1183
|
}
|
|
836
1184
|
return formData;
|
|
837
1185
|
}
|
|
1186
|
+
function isBrowserEnvironment() {
|
|
1187
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
1188
|
+
return true;
|
|
1189
|
+
} else if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
1190
|
+
return false;
|
|
1191
|
+
} else {
|
|
1192
|
+
return false;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
838
1195
|
function createSvg() {
|
|
839
1196
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
840
1197
|
svg.setAttribute("width", "21");
|
|
@@ -853,18 +1210,16 @@ function createSvg() {
|
|
|
853
1210
|
}
|
|
854
1211
|
function parseParaModel(parameterObj, dataDef) {
|
|
855
1212
|
let bodyModel;
|
|
856
|
-
if (parameterObj
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
bodyModel = parseElement(itemObj);
|
|
865
|
-
}
|
|
866
|
-
bodyModel = [bodyModel];
|
|
1213
|
+
if (parameterObj.schema["$ref"]) {
|
|
1214
|
+
bodyModel = parseModel(parameterObj.schema["$ref"], dataDef);
|
|
1215
|
+
} else if (parameterObj.schema["type"] == "array") {
|
|
1216
|
+
const itemObj = parameterObj.schema["items"];
|
|
1217
|
+
if (itemObj["$ref"]) {
|
|
1218
|
+
bodyModel = parseModel(itemObj["$ref"], dataDef);
|
|
1219
|
+
} else if (itemObj["type"]) {
|
|
1220
|
+
bodyModel = parseElement(itemObj);
|
|
867
1221
|
}
|
|
1222
|
+
bodyModel = [bodyModel];
|
|
868
1223
|
}
|
|
869
1224
|
return bodyModel;
|
|
870
1225
|
}
|
|
@@ -895,10 +1250,66 @@ function parseModel(modelDef, apiDef) {
|
|
|
895
1250
|
}
|
|
896
1251
|
return model;
|
|
897
1252
|
}
|
|
1253
|
+
function parseFormDataModel(modelDef, apiDef) {
|
|
1254
|
+
const model = [];
|
|
1255
|
+
const bodyName = modelDef.substring(modelDef.lastIndexOf("/") + 1);
|
|
1256
|
+
const def = apiDef[bodyName];
|
|
1257
|
+
const props = def["properties"];
|
|
1258
|
+
if (props) {
|
|
1259
|
+
for (const key in props) {
|
|
1260
|
+
if (Object.prototype.hasOwnProperty.call(props, key)) {
|
|
1261
|
+
const element = props[key];
|
|
1262
|
+
let modelEle;
|
|
1263
|
+
if (element.hasOwnProperty("items") && element["type"] == "array") {
|
|
1264
|
+
if (element["items"]["$ref"]) {
|
|
1265
|
+
modelEle = [parseModel(element["items"]["$ref"], apiDef)];
|
|
1266
|
+
} else if (element["items"]["type"]) {
|
|
1267
|
+
modelEle = [parseElement(element["items"])];
|
|
1268
|
+
}
|
|
1269
|
+
if (modelEle) {
|
|
1270
|
+
model.push({
|
|
1271
|
+
type: "string",
|
|
1272
|
+
uiType: "text",
|
|
1273
|
+
name: key,
|
|
1274
|
+
value: JSON.stringify(modelEle)
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
} else if (element["type"]) {
|
|
1278
|
+
model.push({
|
|
1279
|
+
type: element["type"],
|
|
1280
|
+
uiType: element["type"] == "integer" || element["type"] == "number" ? "number" : "text",
|
|
1281
|
+
name: key,
|
|
1282
|
+
value: parseElement(element)
|
|
1283
|
+
});
|
|
1284
|
+
} else if (element["$ref"]) {
|
|
1285
|
+
const bodyModel = parseModel(element["$ref"], apiDef);
|
|
1286
|
+
model.push({
|
|
1287
|
+
type: "string",
|
|
1288
|
+
uiType: "text",
|
|
1289
|
+
name: key,
|
|
1290
|
+
value: JSON.stringify(bodyModel)
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return model;
|
|
1297
|
+
}
|
|
1298
|
+
function parseFormDataParaModel(parameterObj, dataDef) {
|
|
1299
|
+
let bodyModel = [];
|
|
1300
|
+
if (parameterObj.schema["$ref"]) {
|
|
1301
|
+
bodyModel = parseFormDataModel(parameterObj.schema["$ref"], dataDef);
|
|
1302
|
+
}
|
|
1303
|
+
return bodyModel;
|
|
1304
|
+
}
|
|
898
1305
|
function parseElement(element) {
|
|
899
1306
|
let elementValue;
|
|
900
1307
|
if (element["type"].includes("integer")) {
|
|
901
|
-
|
|
1308
|
+
if (element["enum"]) {
|
|
1309
|
+
elementValue = element["enum"][0];
|
|
1310
|
+
} else {
|
|
1311
|
+
elementValue = 0;
|
|
1312
|
+
}
|
|
902
1313
|
} else if (element["type"].includes("boolean")) {
|
|
903
1314
|
elementValue = false;
|
|
904
1315
|
} else if (element["type"].includes("string")) {
|
|
@@ -908,16 +1319,29 @@ function parseElement(element) {
|
|
|
908
1319
|
elementValue = "";
|
|
909
1320
|
}
|
|
910
1321
|
}
|
|
1322
|
+
if (element["default"]) {
|
|
1323
|
+
elementValue = element["default"];
|
|
1324
|
+
}
|
|
911
1325
|
if (element["example"]) {
|
|
912
1326
|
elementValue = element["example"];
|
|
913
1327
|
}
|
|
914
1328
|
return elementValue;
|
|
915
1329
|
}
|
|
1330
|
+
function parseElementType(element) {
|
|
1331
|
+
if (element["type"].includes("integer")) {
|
|
1332
|
+
return "integer";
|
|
1333
|
+
} else if (element["type"].includes("boolean")) {
|
|
1334
|
+
return "boolean";
|
|
1335
|
+
} else if (element["type"].includes("string")) {
|
|
1336
|
+
return "string";
|
|
1337
|
+
}
|
|
1338
|
+
return "string";
|
|
1339
|
+
}
|
|
916
1340
|
var HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
917
1341
|
function isHttpMethod(method) {
|
|
918
1342
|
return HTTP_METHODS.includes(method);
|
|
919
1343
|
}
|
|
920
|
-
function
|
|
1344
|
+
function parseOpenApiSpec(openapiSpec, currentServer, serviceName) {
|
|
921
1345
|
const apiOperatorList = [];
|
|
922
1346
|
const pathEntries = [];
|
|
923
1347
|
for (const path in openapiSpec.paths) {
|
|
@@ -938,51 +1362,99 @@ function parseOpenAPI(openapiSpec) {
|
|
|
938
1362
|
}
|
|
939
1363
|
}
|
|
940
1364
|
pathItemEntries.forEach(([method, operation]) => {
|
|
1365
|
+
let url = path;
|
|
1366
|
+
if (currentServer) {
|
|
1367
|
+
url = currentServer.value + "/api/" + serviceName + "/v1" + path;
|
|
1368
|
+
} else if (openapiSpec.servers && openapiSpec.servers.length > 0) {
|
|
1369
|
+
url = openapiSpec.servers[0].url + path;
|
|
1370
|
+
}
|
|
941
1371
|
const apiOperator = {
|
|
942
1372
|
method: method.toUpperCase(),
|
|
943
|
-
url
|
|
944
|
-
rawApiInfo:
|
|
1373
|
+
url,
|
|
1374
|
+
rawApiInfo: operation,
|
|
945
1375
|
requestBody: null,
|
|
946
1376
|
response: {},
|
|
947
|
-
|
|
948
|
-
{
|
|
949
|
-
type: "No Auth"
|
|
950
|
-
},
|
|
951
|
-
{
|
|
952
|
-
type: "Basic Auth",
|
|
953
|
-
parameters: [
|
|
954
|
-
{
|
|
955
|
-
name: "userName",
|
|
956
|
-
value: ""
|
|
957
|
-
},
|
|
958
|
-
{
|
|
959
|
-
name: "password",
|
|
960
|
-
value: ""
|
|
961
|
-
}
|
|
962
|
-
]
|
|
963
|
-
}
|
|
964
|
-
]
|
|
1377
|
+
auth: {}
|
|
965
1378
|
};
|
|
966
1379
|
if (operation) {
|
|
967
|
-
if (
|
|
968
|
-
const
|
|
969
|
-
if (
|
|
1380
|
+
if (apiOperator.rawApiInfo.parameters) {
|
|
1381
|
+
const parameterBody = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "body");
|
|
1382
|
+
if (parameterBody && parameterBody.length > 0) {
|
|
1383
|
+
apiOperator["requestBody"] = {
|
|
1384
|
+
content: {}
|
|
1385
|
+
};
|
|
1386
|
+
apiOperator["consumes"] = apiOperator.rawApiInfo["consumes"];
|
|
1387
|
+
const currentConsume = apiOperator.rawApiInfo["consumes"].length > 0 ? apiOperator.rawApiInfo["consumes"][0] : "application/json";
|
|
1388
|
+
apiOperator["currentConsume"] = currentConsume;
|
|
1389
|
+
let requestBody = parseParaModel(parameterBody[0], openapiSpec["definitions"]);
|
|
1390
|
+
apiOperator["requestBody"]["content"][currentConsume] = JSON.stringify(requestBody, null, 4);
|
|
1391
|
+
apiOperator["parameterHasBody"] = true;
|
|
1392
|
+
} else {
|
|
1393
|
+
for (const parameter of apiOperator.rawApiInfo.parameters) {
|
|
1394
|
+
if (parameter.in == "query" || parameter.in == "header" || parameter.in == "path" || parameter.in == "formData") {
|
|
1395
|
+
if (parameter.type == "integer" || parameter.schema != null && parameter.schema.type == "integer" || parameter.type == "number" || parameter.schema != null && parameter.schema.type == "number") {
|
|
1396
|
+
parameter.uiType = "number";
|
|
1397
|
+
}
|
|
1398
|
+
if (parameter.type == "string" || parameter.schema != null && parameter.schema.type == "string") {
|
|
1399
|
+
parameter.uiType = "text";
|
|
1400
|
+
}
|
|
1401
|
+
if (parameter.type == "boolean" || parameter.schema != null && parameter.schema.type == "boolean") {
|
|
1402
|
+
parameter.uiType = "text";
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
const parameterFormData = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "formData");
|
|
1407
|
+
if (parameterFormData && parameterFormData.length > 0) {
|
|
1408
|
+
apiOperator["parameterHasFormDataVer2"] = true;
|
|
1409
|
+
}
|
|
1410
|
+
for (const param of apiOperator.rawApiInfo.parameters) {
|
|
1411
|
+
const paramSchema = param.schema;
|
|
1412
|
+
if (paramSchema && paramSchema["$ref"]) {
|
|
1413
|
+
const bodyName = paramSchema["$ref"].substring(paramSchema["$ref"].lastIndexOf("/") + 1);
|
|
1414
|
+
if (openapiSpec && openapiSpec["components"] != null && openapiSpec["components"]["schemas"] != null) {
|
|
1415
|
+
const def = openapiSpec["components"] != null ? openapiSpec["components"]["schemas"][bodyName] : { type: "" };
|
|
1416
|
+
param.type = parseElementType(def);
|
|
1417
|
+
param.uiType = param.type == "integer" || param.type == "number" ? "number" : "text";
|
|
1418
|
+
param.value = parseElement(def);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
970
1422
|
}
|
|
971
1423
|
}
|
|
972
|
-
if (
|
|
973
|
-
const
|
|
974
|
-
|
|
1424
|
+
if (apiOperator.rawApiInfo.requestBody) {
|
|
1425
|
+
const content = apiOperator.rawApiInfo.requestBody.content;
|
|
1426
|
+
apiOperator["requestBody"] = {
|
|
1427
|
+
content: {}
|
|
1428
|
+
};
|
|
975
1429
|
for (const key in content) {
|
|
976
1430
|
if (Object.prototype.hasOwnProperty.call(content, key)) {
|
|
977
1431
|
const element = content[key];
|
|
1432
|
+
apiOperator["consumes"]?.push(key);
|
|
978
1433
|
if (element) {
|
|
979
|
-
|
|
980
|
-
|
|
1434
|
+
if (element.schema == void 0) {
|
|
1435
|
+
console.log("pathKey is:", path);
|
|
1436
|
+
console.log("key is:", key);
|
|
1437
|
+
console.log("content is:", content);
|
|
1438
|
+
console.log("Unsupported requestBody schema format:", element);
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
if (key != "application/x-www-form-urlencoded" && key != "multipart/form-data") {
|
|
1442
|
+
let requestBody = parseParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1443
|
+
apiOperator["requestBody"]["content"][key] = JSON.stringify(requestBody, null, 4);
|
|
1444
|
+
} else {
|
|
1445
|
+
let requestFormDataBody = parseFormDataParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1446
|
+
apiOperator["requestBody"]["content"][key] = requestFormDataBody;
|
|
1447
|
+
}
|
|
1448
|
+
apiOperator["parameterHasBody"] = true;
|
|
981
1449
|
}
|
|
982
1450
|
}
|
|
983
1451
|
}
|
|
1452
|
+
if (apiOperator.consumes) {
|
|
1453
|
+
if (apiOperator.consumes.length > 0) {
|
|
1454
|
+
apiOperator["currentConsume"] = apiOperator["consumes"][0];
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
984
1457
|
}
|
|
985
|
-
apiOperator.rawApiInfo = operation;
|
|
986
1458
|
apiOperatorList.push(apiOperator);
|
|
987
1459
|
}
|
|
988
1460
|
});
|