api-render-ui 1.1.0 → 1.1.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/dist/index.cjs +614 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +614 -145
- 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 -3
- package/src/api-render-ui.ts +880 -170
- package/src/inlined-styles.ts +3 -3
- package/src/main.ts +0 -10
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,6 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
31
31
|
display: inline-flex;
|
|
32
32
|
flex-direction: column;
|
|
33
33
|
gap: 5px;
|
|
34
|
-
height: 100%;
|
|
35
34
|
justify-content: flex-start;
|
|
36
35
|
width: 100%
|
|
37
36
|
}
|
|
@@ -88,7 +87,6 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
88
87
|
display: inline-flex;
|
|
89
88
|
flex-direction: column;
|
|
90
89
|
gap: 8px;
|
|
91
|
-
height: 100%;
|
|
92
90
|
justify-content: flex-start;
|
|
93
91
|
width: 100%
|
|
94
92
|
}
|
|
@@ -214,10 +212,12 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
214
212
|
align-items: center;
|
|
215
213
|
align-self: stretch;
|
|
216
214
|
display: inline-flex;
|
|
217
|
-
height: 114px;
|
|
218
215
|
justify-content: flex-start;
|
|
219
216
|
padding-right: 5px
|
|
220
217
|
}
|
|
218
|
+
.codigma-apiunit-request-body-info {
|
|
219
|
+
align-self: stretch;
|
|
220
|
+
}
|
|
221
221
|
.codigma-apiunit-parakeyvalues {
|
|
222
222
|
align-items: flex-start;
|
|
223
223
|
align-self: stretch;
|
|
@@ -277,9 +277,11 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
277
277
|
}`;
|
|
278
278
|
|
|
279
279
|
// src/api-render-ui.ts
|
|
280
|
-
var ApiRenderer = class {
|
|
280
|
+
var ApiRenderer = class _ApiRenderer {
|
|
281
281
|
options;
|
|
282
282
|
container;
|
|
283
|
+
// 静态标志:记录是否已注入全局样式
|
|
284
|
+
static globalStyleInjected = false;
|
|
283
285
|
constructor(options) {
|
|
284
286
|
this.options = Object.assign({
|
|
285
287
|
mountPoint: document?.body,
|
|
@@ -291,9 +293,12 @@ var ApiRenderer = class {
|
|
|
291
293
|
}
|
|
292
294
|
render(apiSpec, renderUnit = false) {
|
|
293
295
|
const appendInlineStyle = (text) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
if (!_ApiRenderer.globalStyleInjected) {
|
|
297
|
+
const styleEl = document.createElement("style");
|
|
298
|
+
styleEl.textContent = text;
|
|
299
|
+
document.head.appendChild(styleEl);
|
|
300
|
+
_ApiRenderer.globalStyleInjected = true;
|
|
301
|
+
}
|
|
297
302
|
};
|
|
298
303
|
appendInlineStyle(GLOBAL_STYLES);
|
|
299
304
|
const elementMap = /* @__PURE__ */ new Map();
|
|
@@ -368,12 +373,47 @@ var ApiRenderer = class {
|
|
|
368
373
|
mountElement.appendChild(this.container);
|
|
369
374
|
}
|
|
370
375
|
};
|
|
376
|
+
var auths = [
|
|
377
|
+
{
|
|
378
|
+
value: "No Auth"
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
value: "Basic Auth",
|
|
382
|
+
parameters: [
|
|
383
|
+
{
|
|
384
|
+
name: "userName",
|
|
385
|
+
value: ""
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: "password",
|
|
389
|
+
value: ""
|
|
390
|
+
}
|
|
391
|
+
]
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
value: "OAuth 2.0"
|
|
395
|
+
}
|
|
396
|
+
];
|
|
397
|
+
var grantTypes = [
|
|
398
|
+
{ value: "authorization_code" },
|
|
399
|
+
{ value: "Implicit" },
|
|
400
|
+
{ value: "Resource Owner Password Credentials" },
|
|
401
|
+
{ value: "client_credentials" }
|
|
402
|
+
];
|
|
403
|
+
var clientAuthenticationOpts = [
|
|
404
|
+
{ value: "Headers", displayName: "Send credentials in headers" },
|
|
405
|
+
{ value: "Body", displayName: "Send credentials in body" }
|
|
406
|
+
];
|
|
407
|
+
var consumeOpts = [
|
|
408
|
+
{ value: "None" },
|
|
409
|
+
{ value: "application/json" },
|
|
410
|
+
{ value: "application/xml" },
|
|
411
|
+
{ value: "application/x-www-form-urlencoded" },
|
|
412
|
+
{ value: "multipart/form-data" },
|
|
413
|
+
{ value: "text/plain" }
|
|
414
|
+
];
|
|
371
415
|
function renderApiUnit(apiOperator, containerRef, elementMap) {
|
|
372
416
|
return function(evt) {
|
|
373
|
-
console.log("\u70B9\u51FB\u7684API\u64CD\u4F5C\uFF1A");
|
|
374
|
-
console.log("\u65B9\u6CD5:", apiOperator.method);
|
|
375
|
-
console.log("URL:", apiOperator.url);
|
|
376
|
-
console.log("------------------------");
|
|
377
417
|
const currentTarget = evt.currentTarget;
|
|
378
418
|
if (elementMap.has(currentTarget)) {
|
|
379
419
|
const newElement = elementMap.get(currentTarget);
|
|
@@ -404,7 +444,7 @@ function createApiUnit(apiOperator) {
|
|
|
404
444
|
const paramSection = createParamSection(apiOperator);
|
|
405
445
|
const headerSection = createSectionHeader(apiOperator);
|
|
406
446
|
const authSection = createSectionAuth(apiOperator);
|
|
407
|
-
const bodySection = createSectionRequestBody(apiOperator
|
|
447
|
+
const bodySection = createSectionRequestBody(apiOperator);
|
|
408
448
|
reqContent.append(paramSection, headerSection, authSection, bodySection);
|
|
409
449
|
apiContainer.appendChild(reqContent);
|
|
410
450
|
apiContainer.appendChild(responseSection);
|
|
@@ -435,7 +475,6 @@ function createReqOperator(apiOperator) {
|
|
|
435
475
|
reqUrl.className = "Requrl codigma-apiunit-requrl";
|
|
436
476
|
reqUrl.value = apiOperator.url;
|
|
437
477
|
reqUrl.addEventListener("input", (e) => {
|
|
438
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
439
478
|
apiOperator.url = e.target.value;
|
|
440
479
|
});
|
|
441
480
|
reqOperator.appendChild(reqUrl);
|
|
@@ -448,7 +487,6 @@ function createReqOperator(apiOperator) {
|
|
|
448
487
|
sendText.textContent = "Send";
|
|
449
488
|
sendButton.appendChild(sendText);
|
|
450
489
|
sendButton.addEventListener("click", (e) => {
|
|
451
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
452
490
|
const respRef = apiOperator._responseSectionRef || null;
|
|
453
491
|
sendRequest(apiOperator, respRef);
|
|
454
492
|
});
|
|
@@ -515,17 +553,135 @@ function createSectionAuth(apiOperator) {
|
|
|
515
553
|
const authValues = document.createElement("div");
|
|
516
554
|
authValues.setAttribute("data-layer", "paraKeyValues");
|
|
517
555
|
authValues.className = "Parakeyvalues codigma-apiunit-parakeyvalues";
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
556
|
+
const authTypeRow = createSelectRow("Authorization Type", auths);
|
|
557
|
+
authTypeRow.children[1].addEventListener("change", function(event) {
|
|
558
|
+
authValues && Array.from(authValues.children).slice(1).forEach((el) => el.remove());
|
|
559
|
+
const auth = auths[event.target.selectedIndex];
|
|
560
|
+
if (auth.value == "No Auth") {
|
|
561
|
+
} else if (auth.value == "Basic Auth") {
|
|
562
|
+
apiOperator.auth = [
|
|
563
|
+
{
|
|
564
|
+
name: "userName",
|
|
565
|
+
value: ""
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
name: "password",
|
|
569
|
+
value: ""
|
|
570
|
+
}
|
|
571
|
+
];
|
|
572
|
+
const authRows = apiOperator.auth.map((parameter) => createRow(parameter));
|
|
573
|
+
authValues.append(...authRows);
|
|
574
|
+
} else if (auth.value == "OAuth 2.0") {
|
|
575
|
+
apiOperator.auth = {};
|
|
576
|
+
renderAuthForm(apiOperator, authValues, authTypeRow);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
authValues.append(authTypeRow);
|
|
525
580
|
authSection.append(authCnr, authValues);
|
|
526
581
|
return authSection;
|
|
527
582
|
}
|
|
528
|
-
function
|
|
583
|
+
function createElement(tag, props = {}, classes = []) {
|
|
584
|
+
const el = document.createElement(tag);
|
|
585
|
+
Object.entries(props).forEach(([key, value]) => el.setAttribute(key, value));
|
|
586
|
+
if (classes.length) el.classList.add(...classes);
|
|
587
|
+
return el;
|
|
588
|
+
}
|
|
589
|
+
function createLabeledInput(apiOperator, labelText, inputId, inputName, modelKey, required = false) {
|
|
590
|
+
const wrapper = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
591
|
+
const label = createElement("label", { for: inputId }, ["type", "codigma-apiunit-send"]);
|
|
592
|
+
label.textContent = labelText + ":";
|
|
593
|
+
const input = createElement("input", {
|
|
594
|
+
type: "text",
|
|
595
|
+
id: inputId,
|
|
596
|
+
name: inputName,
|
|
597
|
+
autocomplete: "off",
|
|
598
|
+
...required ? { required: "true" } : {}
|
|
599
|
+
}, ["Valuetext", "codigma-apiunit-valuetext"]);
|
|
600
|
+
input.value = apiOperator.auth[modelKey] || "";
|
|
601
|
+
input.addEventListener("input", (e) => {
|
|
602
|
+
apiOperator.auth[modelKey] = e.target.value;
|
|
603
|
+
});
|
|
604
|
+
wrapper.appendChild(label);
|
|
605
|
+
wrapper.appendChild(input);
|
|
606
|
+
return wrapper;
|
|
607
|
+
}
|
|
608
|
+
function createSelect(apiOperator, labelText, selectId, options, modelKey, changeHandler) {
|
|
609
|
+
const wrapper = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
610
|
+
const label = createElement("label", { for: selectId }, ["type", "codigma-apiunit-send"]);
|
|
611
|
+
label.textContent = labelText + ":";
|
|
612
|
+
const select = createElement("select", {
|
|
613
|
+
id: selectId,
|
|
614
|
+
name: selectId
|
|
615
|
+
}, []);
|
|
616
|
+
options.forEach((opt) => {
|
|
617
|
+
const option = createElement("option", { value: opt.value });
|
|
618
|
+
option.textContent = opt.displayName || opt.value;
|
|
619
|
+
select.appendChild(option);
|
|
620
|
+
});
|
|
621
|
+
select.value = apiOperator.auth[modelKey] || options[0]?.value || "";
|
|
622
|
+
select.addEventListener("change", (e) => {
|
|
623
|
+
const val = e.target.value;
|
|
624
|
+
changeHandler(val);
|
|
625
|
+
});
|
|
626
|
+
wrapper.appendChild(label);
|
|
627
|
+
wrapper.appendChild(select);
|
|
628
|
+
return wrapper;
|
|
629
|
+
}
|
|
630
|
+
function renderAuthForm(apiOperator, authValues, authTypeRow) {
|
|
631
|
+
authValues.innerHTML = "";
|
|
632
|
+
authValues.append(authTypeRow);
|
|
633
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Token", "token", "token", "token", true));
|
|
634
|
+
authValues.appendChild(
|
|
635
|
+
createSelect(
|
|
636
|
+
apiOperator,
|
|
637
|
+
"Grant Type",
|
|
638
|
+
"grantType",
|
|
639
|
+
grantTypes,
|
|
640
|
+
"grantType",
|
|
641
|
+
(value) => {
|
|
642
|
+
apiOperator.auth.grantType = value;
|
|
643
|
+
renderAuthForm(apiOperator, authValues, authTypeRow);
|
|
644
|
+
}
|
|
645
|
+
)
|
|
646
|
+
);
|
|
647
|
+
const gt = apiOperator.auth.grantType || "authorization_code";
|
|
648
|
+
if (gt === "authorization_code" || gt === "Implicit") {
|
|
649
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Authorization Endpoint", "authorizationEndpoint", "authorizationEndpoint", "authorizationEndpoint", true));
|
|
650
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Redirect URL", "RedirectURI", "RedirectURI", "redirectURI", true));
|
|
651
|
+
}
|
|
652
|
+
if (gt === "authorization_code" || gt === "client_credentials" || gt === "Resource Owner Password Credentials") {
|
|
653
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Token Endpoint", "TokenEndpoint", "TokenEndpoint", "tokenEndpoint", true));
|
|
654
|
+
}
|
|
655
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Client ID", "ClientID", "ClientID", "clientId", true));
|
|
656
|
+
if (gt === "authorization_code" || gt === "client_credentials" || gt === "Resource Owner Password Credentials") {
|
|
657
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Client Secret", "ClientSecret", "ClientSecret", "clientSecret", true));
|
|
658
|
+
}
|
|
659
|
+
if (gt === "Resource Owner Password Credentials") {
|
|
660
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Username", "Username", "Username", "username", true));
|
|
661
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Password", "Password", "Password", "password", true));
|
|
662
|
+
}
|
|
663
|
+
authValues.appendChild(createLabeledInput(apiOperator, "Scopes", "Scopes", "Scopes", "scopes", true));
|
|
664
|
+
authValues.appendChild(
|
|
665
|
+
createSelect(
|
|
666
|
+
apiOperator,
|
|
667
|
+
"Client Authentication",
|
|
668
|
+
"clientAuthentication",
|
|
669
|
+
clientAuthenticationOpts,
|
|
670
|
+
"clientAuthentication",
|
|
671
|
+
(value) => {
|
|
672
|
+
apiOperator.auth.clientAuthentication = value;
|
|
673
|
+
}
|
|
674
|
+
)
|
|
675
|
+
);
|
|
676
|
+
const buttonWrapper = createElement("div", {}, ["parameter-item"]);
|
|
677
|
+
const generateBtn = createElement("button", {}, ["parameter-button"]);
|
|
678
|
+
generateBtn.type = "button";
|
|
679
|
+
generateBtn.textContent = "Generate Token";
|
|
680
|
+
generateBtn.addEventListener("click", () => generateOAuth2Token(apiOperator));
|
|
681
|
+
buttonWrapper.appendChild(generateBtn);
|
|
682
|
+
authValues.appendChild(buttonWrapper);
|
|
683
|
+
}
|
|
684
|
+
function createSectionRequestBody(apiOperator) {
|
|
529
685
|
const bodySection = document.createElement("div");
|
|
530
686
|
bodySection.setAttribute("data-layer", "request-body-section");
|
|
531
687
|
bodySection.className = "RequestBodySection codigma-apiunit-request-body-section";
|
|
@@ -538,13 +694,108 @@ function createSectionRequestBody(requestBody) {
|
|
|
538
694
|
bodyText.textContent = "Body";
|
|
539
695
|
bodyCnr.appendChild(bodyText);
|
|
540
696
|
bodySection.appendChild(bodyCnr);
|
|
541
|
-
|
|
542
|
-
bodyValue.setAttribute("data-layer", "bodyTextValue");
|
|
543
|
-
bodyValue.className = "Id0CategoryId0NameNamePhotourlsTagsId0NameStatusAvailable codigma-apiunit-parakeyvalues";
|
|
544
|
-
bodyValue.value = JSON.stringify(requestBody);
|
|
545
|
-
bodySection.appendChild(bodyValue);
|
|
697
|
+
renderConsumeSection(apiOperator, bodySection, bodyCnr);
|
|
546
698
|
return bodySection;
|
|
547
699
|
}
|
|
700
|
+
function createConsumeSelect(apiOperator, container, bodyCnr) {
|
|
701
|
+
const wrapper = createElement("div");
|
|
702
|
+
const label = createElement("label");
|
|
703
|
+
label.style.margin = "0 1rem";
|
|
704
|
+
label.textContent = "Content-Type";
|
|
705
|
+
const select = createElement("select");
|
|
706
|
+
select.style.width = "18rem";
|
|
707
|
+
consumeOpts.forEach((opt) => {
|
|
708
|
+
const option = document.createElement("option");
|
|
709
|
+
option.value = opt.value;
|
|
710
|
+
option.textContent = opt.value;
|
|
711
|
+
select.appendChild(option);
|
|
712
|
+
});
|
|
713
|
+
select.value = apiOperator.currentConsume || getCurrentConsume(apiOperator);
|
|
714
|
+
select.addEventListener("change", (e) => {
|
|
715
|
+
const newValue = e.target.value;
|
|
716
|
+
if (apiOperator.currentConsume !== newValue) {
|
|
717
|
+
apiOperator.currentConsume = newValue;
|
|
718
|
+
renderConsumeSection(apiOperator, container, bodyCnr);
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
wrapper.appendChild(label);
|
|
722
|
+
wrapper.appendChild(select);
|
|
723
|
+
return wrapper;
|
|
724
|
+
}
|
|
725
|
+
function renderRequestBodyInto(apiOperator, targetDiv) {
|
|
726
|
+
targetDiv.innerHTML = "";
|
|
727
|
+
const ct = apiOperator.currentConsume || getCurrentConsume(apiOperator);
|
|
728
|
+
if (ct === null || ct === "None" || ct === "application/json" || ct === "application/xml" || ct === "text/plain") {
|
|
729
|
+
const mimeType = ct || "None";
|
|
730
|
+
let rawValue = apiOperator.requestBody.content[mimeType];
|
|
731
|
+
if (rawValue == null) {
|
|
732
|
+
rawValue = "";
|
|
733
|
+
apiOperator.requestBody.content[mimeType] = rawValue;
|
|
734
|
+
}
|
|
735
|
+
const textarea = createElement("textarea", {}, []);
|
|
736
|
+
textarea.style.width = "100%";
|
|
737
|
+
textarea.style.height = "200px";
|
|
738
|
+
textarea.style.fontFamily = "monospace";
|
|
739
|
+
textarea.style.fontSize = "14px";
|
|
740
|
+
textarea.placeholder = `Enter ${mimeType} body...`;
|
|
741
|
+
textarea.value = rawValue;
|
|
742
|
+
textarea.addEventListener("input", () => {
|
|
743
|
+
apiOperator.requestBody.content[mimeType] = textarea.value;
|
|
744
|
+
console.log(`Content updated for ${mimeType}:`, textarea.value);
|
|
745
|
+
});
|
|
746
|
+
targetDiv.appendChild(textarea);
|
|
747
|
+
} else if ((ct === "application/x-www-form-urlencoded" || ct === "multipart/form-data") && apiOperator.requestBody.content && Array.isArray(apiOperator.requestBody.content[ct])) {
|
|
748
|
+
const params = apiOperator.requestBody.content[ct];
|
|
749
|
+
params.forEach((param, index) => {
|
|
750
|
+
const item = createElement("div", {}, ["Keyvalue", "codigma-apiunit-keyvalue"]);
|
|
751
|
+
const label = createElement("label", { for: `param-${Date.now()}-${index}` }, ["petId", "codigma-apiunit-send"]);
|
|
752
|
+
label.textContent = `${param.name}:`;
|
|
753
|
+
const input = createElement("input", {
|
|
754
|
+
type: param.uiType || "text",
|
|
755
|
+
// 使用时间戳+索引避免 id 冲突(仅用于 label for)
|
|
756
|
+
id: `param-${Date.now()}-${index}`,
|
|
757
|
+
name: "name"
|
|
758
|
+
}, ["Valuetext", "codigma-apiunit-valuetext"]);
|
|
759
|
+
input.value = param.value || "";
|
|
760
|
+
input.autocomplete = "off";
|
|
761
|
+
input.required = true;
|
|
762
|
+
input.addEventListener("keydown", (e) => {
|
|
763
|
+
setEditStatus(e, true);
|
|
764
|
+
});
|
|
765
|
+
input.addEventListener("input", () => {
|
|
766
|
+
param.value = input.value;
|
|
767
|
+
});
|
|
768
|
+
item.appendChild(label);
|
|
769
|
+
item.appendChild(input);
|
|
770
|
+
targetDiv.appendChild(item);
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
function getCurrentConsume(apiOperator) {
|
|
775
|
+
if (!apiOperator.requestBody) {
|
|
776
|
+
apiOperator.requestBody = { content: {} };
|
|
777
|
+
}
|
|
778
|
+
if (!apiOperator.requestBody.content) {
|
|
779
|
+
apiOperator.requestBody.content = {};
|
|
780
|
+
}
|
|
781
|
+
const keys = Object.keys(apiOperator.requestBody.content);
|
|
782
|
+
const ct = apiOperator.currentConsume = keys.length > 0 ? keys[0] : "None";
|
|
783
|
+
return ct;
|
|
784
|
+
}
|
|
785
|
+
function setEditStatus(event, status) {
|
|
786
|
+
console.log("setEditStatus called:", event.key, status);
|
|
787
|
+
}
|
|
788
|
+
function renderConsumeSection(apiOperator, container, bodyCnr) {
|
|
789
|
+
container.innerHTML = "";
|
|
790
|
+
container.appendChild(bodyCnr);
|
|
791
|
+
const wrapperDiv = createElement("div", {}, ["codigma-apiunit-parakeyvalues"]);
|
|
792
|
+
const selectWrapper = createConsumeSelect(apiOperator, container, bodyCnr);
|
|
793
|
+
wrapperDiv.appendChild(selectWrapper);
|
|
794
|
+
const reqBodyContainer = createElement("div", {}, ["codigma-apiunit-request-body-info"]);
|
|
795
|
+
renderRequestBodyInto(apiOperator, reqBodyContainer);
|
|
796
|
+
wrapperDiv.appendChild(reqBodyContainer);
|
|
797
|
+
container.appendChild(wrapperDiv);
|
|
798
|
+
}
|
|
548
799
|
function createSectionResponse(apiOperator) {
|
|
549
800
|
const responseSection = document.createElement("div");
|
|
550
801
|
responseSection.setAttribute("data-layer", "reqresponse");
|
|
@@ -579,6 +830,9 @@ function createTimeStatusElement(apiOperator) {
|
|
|
579
830
|
updateTimeStatus(timeStatus, apiOperator);
|
|
580
831
|
return timeStatus;
|
|
581
832
|
}
|
|
833
|
+
function updateTimeStatus(timeStatus, apiOperator) {
|
|
834
|
+
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
835
|
+
}
|
|
582
836
|
function createRow(parameter) {
|
|
583
837
|
const petIdRow = document.createElement("div");
|
|
584
838
|
petIdRow.setAttribute("data-layer", "keyValue");
|
|
@@ -592,7 +846,6 @@ function createRow(parameter) {
|
|
|
592
846
|
petIdValue.className = "Valuetext codigma-apiunit-valuetext";
|
|
593
847
|
petIdValue.value = parameter["value"] || "";
|
|
594
848
|
petIdValue.addEventListener("input", (e) => {
|
|
595
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
596
849
|
parameter["value"] = e.target.value;
|
|
597
850
|
});
|
|
598
851
|
petIdRow.append(petIdLabel, petIdValue);
|
|
@@ -606,31 +859,24 @@ function createInputElement() {
|
|
|
606
859
|
inputText.setAttribute("autocomplete", "off");
|
|
607
860
|
return inputText;
|
|
608
861
|
}
|
|
609
|
-
function createSelectRow(
|
|
862
|
+
function createSelectRow(name, args) {
|
|
610
863
|
const container = document.createElement("div");
|
|
611
864
|
container.setAttribute("data-layer", "keyValue");
|
|
612
865
|
container.className = "Keyvalue codigma-apiunit-keyvalue";
|
|
613
866
|
const typeLabel = document.createElement("div");
|
|
614
|
-
typeLabel.setAttribute("data-layer",
|
|
867
|
+
typeLabel.setAttribute("data-layer", name);
|
|
615
868
|
typeLabel.className = "type codigma-apiunit-send";
|
|
616
|
-
typeLabel.textContent = "
|
|
869
|
+
typeLabel.textContent = name + ":";
|
|
617
870
|
const selectElement = document.createElement("select");
|
|
618
871
|
selectElement.name = "text-select";
|
|
619
872
|
selectElement.label = "text-select";
|
|
620
873
|
selectElement.setAttribute("data-layer", "valueText");
|
|
621
|
-
|
|
874
|
+
args.forEach((auth) => {
|
|
622
875
|
const option1 = document.createElement("option");
|
|
623
|
-
option1.value = auth["
|
|
624
|
-
option1.textContent = auth["
|
|
876
|
+
option1.value = auth["value"];
|
|
877
|
+
option1.textContent = auth["displayName"] != null || auth["label"] != null ? auth["displayName"] || auth["label"] : auth["value"];
|
|
625
878
|
selectElement.appendChild(option1);
|
|
626
879
|
});
|
|
627
|
-
selectElement.addEventListener("change", function(event) {
|
|
628
|
-
authValues && Array.from(authValues.children).slice(1).forEach((el) => el.remove());
|
|
629
|
-
const auth = auths[event.target.selectedIndex];
|
|
630
|
-
let parameters = auth.parameters || [];
|
|
631
|
-
const authRows = parameters.map((parameter) => createRow(parameter));
|
|
632
|
-
authValues.append(...authRows);
|
|
633
|
-
});
|
|
634
880
|
container.appendChild(typeLabel);
|
|
635
881
|
container.appendChild(selectElement);
|
|
636
882
|
return container;
|
|
@@ -641,58 +887,153 @@ function isPathOrQueryParam(param) {
|
|
|
641
887
|
function isHeaderParam(param) {
|
|
642
888
|
return param.in === "header";
|
|
643
889
|
}
|
|
644
|
-
function
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
890
|
+
async function generateOAuth2Token(apiInfo) {
|
|
891
|
+
const accessToken = await getAccessToken(apiInfo);
|
|
892
|
+
apiInfo.auth.token = accessToken;
|
|
893
|
+
}
|
|
894
|
+
async function getAccessToken(apiInfo) {
|
|
895
|
+
const auth = apiInfo.auth;
|
|
896
|
+
if (auth == null) {
|
|
897
|
+
throw new Error("OAuth2.0\u8BA4\u8BC1\u4FE1\u606F\u672A\u914D\u7F6E");
|
|
898
|
+
}
|
|
899
|
+
const CLIENT_ID = auth.clientId;
|
|
900
|
+
const CLIENT_SECRET = auth.clientSecret;
|
|
901
|
+
const SCOPE = auth.scopes;
|
|
902
|
+
if (apiInfo.auth.grantType == "client_credentials") {
|
|
903
|
+
try {
|
|
904
|
+
console.log("\u6B63\u5728\u83B7\u53D6\u8BBF\u95EE\u4EE4\u724C...");
|
|
905
|
+
const headerParams = {
|
|
906
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
907
|
+
};
|
|
908
|
+
const bodyParams = new URLSearchParams();
|
|
909
|
+
bodyParams.append("grant_type", "client_credentials");
|
|
910
|
+
if (SCOPE) {
|
|
911
|
+
bodyParams.append("scope", SCOPE);
|
|
912
|
+
}
|
|
913
|
+
if (apiInfo.auth.clientAuthentication == "Body") {
|
|
914
|
+
bodyParams.append("client_id", CLIENT_ID);
|
|
915
|
+
bodyParams.append("client_secret", CLIENT_SECRET);
|
|
916
|
+
} else {
|
|
917
|
+
headerParams["Authorization"] = "Basic " + btoa(CLIENT_ID + ":" + CLIENT_SECRET);
|
|
918
|
+
}
|
|
919
|
+
const response = await fetch(auth.tokenEndpoint, {
|
|
920
|
+
method: "POST",
|
|
921
|
+
headers: headerParams,
|
|
922
|
+
body: bodyParams.toString()
|
|
923
|
+
});
|
|
924
|
+
if (!response.ok) {
|
|
925
|
+
const errorData = await response.json().catch(() => ({}));
|
|
926
|
+
throw new Error(`\u83B7\u53D6\u4EE4\u724C\u5931\u8D25: ${response.status} ${response.statusText}. ${JSON.stringify(errorData)}`);
|
|
927
|
+
}
|
|
928
|
+
const tokenData = await response.json();
|
|
929
|
+
console.log("\u4EE4\u724C\u83B7\u53D6\u6210\u529F:", tokenData);
|
|
930
|
+
return tokenData.access_token;
|
|
931
|
+
} catch (error) {
|
|
932
|
+
console.error("\u83B7\u53D6\u8BBF\u95EE\u4EE4\u724C\u65F6\u51FA\u9519:", error);
|
|
933
|
+
throw error;
|
|
934
|
+
}
|
|
935
|
+
} else if (apiInfo.auth.grantType == "Resource Owner Password Credentials") {
|
|
936
|
+
} else if (apiInfo.auth.grantType == "authorization_code") {
|
|
937
|
+
let getUrlParams2 = function() {
|
|
938
|
+
const params = new URLSearchParams(window.location.search);
|
|
939
|
+
return Object.fromEntries(params.entries());
|
|
940
|
+
}, redirectToAuth2 = function() {
|
|
941
|
+
const state = Math.random().toString(36).substring(2);
|
|
942
|
+
const nonce = Math.random().toString(36).substring(2);
|
|
943
|
+
const authUrl = new URL(config.authUrl);
|
|
944
|
+
authUrl.searchParams.append("client_id", config.clientId);
|
|
945
|
+
authUrl.searchParams.append("redirect_uri", config.redirectUri);
|
|
946
|
+
authUrl.searchParams.append("response_type", "code");
|
|
947
|
+
authUrl.searchParams.append("scope", config.scope);
|
|
948
|
+
authUrl.searchParams.append("state", state);
|
|
949
|
+
authUrl.searchParams.append("nonce", nonce);
|
|
950
|
+
authUrl.searchParams.append("access_type", "offline");
|
|
951
|
+
const newTab = window.open(authUrl.toString(), "_blank");
|
|
952
|
+
};
|
|
953
|
+
var getUrlParams = getUrlParams2, redirectToAuth = redirectToAuth2;
|
|
954
|
+
const config = {
|
|
955
|
+
clientId: apiInfo.auth.clientId,
|
|
956
|
+
// 替换为你的 client_id
|
|
957
|
+
clientSecret: apiInfo.auth.clientSecret,
|
|
958
|
+
// 替换为你的 client_secret
|
|
959
|
+
redirectUri: apiInfo.auth.redirectURI,
|
|
960
|
+
// 必须与注册的 redirect_uri 一致
|
|
961
|
+
authUrl: apiInfo.auth.authorizationEndpoint,
|
|
962
|
+
tokenUrl: apiInfo.auth.tokenEndpoint,
|
|
963
|
+
scope: apiInfo.auth.scopes
|
|
964
|
+
// 可选: 'openid profile email' 如果服务支持
|
|
965
|
+
};
|
|
966
|
+
redirectToAuth2();
|
|
967
|
+
} else if (apiInfo.auth.grantType == "Implicit") {
|
|
968
|
+
} else {
|
|
648
969
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
970
|
+
}
|
|
971
|
+
function getBodyEditorContent(apiOperator) {
|
|
972
|
+
const ct = apiOperator.currentConsume || "None";
|
|
973
|
+
return apiOperator.requestBody.content[ct];
|
|
974
|
+
}
|
|
975
|
+
var gotResponse = false;
|
|
976
|
+
var ifSendingRequest = false;
|
|
977
|
+
var requestDuration = "0";
|
|
978
|
+
var responseObj = {};
|
|
979
|
+
function sendRequest(apiOperator, responseSectionRef) {
|
|
980
|
+
const apiInfo = apiOperator;
|
|
981
|
+
let reuqestUrl = getRequestUrl(apiInfo);
|
|
982
|
+
let header = apiInfo["parameterHasFormDataVer2"] ? "application/x-www-form-urlencoded" : apiInfo["parameterHasBody"] ? apiInfo["currentConsume"] : "application/json";
|
|
652
983
|
let headers = {
|
|
653
984
|
"Content-Type": header
|
|
654
985
|
};
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
986
|
+
const headerParas = getHeadersParams(apiInfo, apiInfo.rawApiInfo.parameters || []);
|
|
987
|
+
Object.assign(headers, headerParas);
|
|
988
|
+
addAuthHeader(apiInfo, headers);
|
|
989
|
+
let body;
|
|
990
|
+
if (apiInfo.method.toUpperCase() == "POST" || apiInfo.method.toUpperCase() == "PUT") {
|
|
991
|
+
if (apiInfo["currentConsume"] == "application/json" && apiInfo.requestBody != null) {
|
|
992
|
+
body = getBodyEditorContent(apiOperator);
|
|
993
|
+
} else if (apiInfo["parameterHasFormDataVer2"]) {
|
|
994
|
+
body = getRequestFormData(apiInfo.rawApiInfo);
|
|
995
|
+
} else if (apiInfo["currentConsume"] == "application/x-www-form-urlencoded") {
|
|
996
|
+
for (const key of apiInfo["requestBody"]["content"][apiInfo["currentConsume"]]) {
|
|
997
|
+
if (body == null || body == "") {
|
|
998
|
+
body = key.name + "=" + key.value;
|
|
999
|
+
} else {
|
|
1000
|
+
body = body + "&" + key.name + "=" + key.value;
|
|
1001
|
+
}
|
|
660
1002
|
}
|
|
1003
|
+
} else {
|
|
1004
|
+
body = "";
|
|
661
1005
|
}
|
|
1006
|
+
} else {
|
|
1007
|
+
body = "";
|
|
662
1008
|
}
|
|
663
|
-
|
|
664
|
-
if (apiOperator.custom) {
|
|
665
|
-
if (apiOperator.method.toUpperCase() == "POST" || apiOperator.method.toUpperCase() == "PUT") {
|
|
666
|
-
body = apiOperator.requestBody;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
apiOperator.ifSendingRequest = true;
|
|
1009
|
+
ifSendingRequest = true;
|
|
670
1010
|
const startTime = Date.now();
|
|
671
1011
|
apiOperator.controller = new AbortController();
|
|
672
1012
|
const signal = apiOperator.controller.signal;
|
|
673
1013
|
const overlayLayerContainer = createRequestOverlayLayer(apiOperator, responseSectionRef);
|
|
674
1014
|
fetch(reuqestUrl, {
|
|
675
|
-
method:
|
|
1015
|
+
method: apiInfo.method.toUpperCase(),
|
|
676
1016
|
headers,
|
|
677
|
-
body
|
|
1017
|
+
body,
|
|
678
1018
|
signal
|
|
679
1019
|
}).then((response) => {
|
|
680
1020
|
if (!response.ok) {
|
|
681
|
-
|
|
1021
|
+
responseObj = {
|
|
682
1022
|
status: response.status,
|
|
683
|
-
statusText: response.statusText
|
|
1023
|
+
statusText: response.statusText,
|
|
1024
|
+
body: ""
|
|
684
1025
|
};
|
|
685
1026
|
const endTime2 = Date.now();
|
|
686
|
-
|
|
687
|
-
|
|
1027
|
+
requestDuration = formatDuration(endTime2 - startTime);
|
|
1028
|
+
ifSendingRequest = false;
|
|
688
1029
|
throw new Error("Network response was not ok.");
|
|
689
1030
|
}
|
|
690
1031
|
const endTime = Date.now();
|
|
691
|
-
|
|
1032
|
+
requestDuration = formatDuration(endTime - startTime);
|
|
692
1033
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
693
1034
|
responsebodyElement.removeChild(overlayLayerContainer);
|
|
694
|
-
|
|
695
|
-
|
|
1035
|
+
ifSendingRequest = false;
|
|
1036
|
+
responseObj = {
|
|
696
1037
|
status: response.status,
|
|
697
1038
|
statusText: response.statusText
|
|
698
1039
|
};
|
|
@@ -707,22 +1048,20 @@ function sendRequest(apiOperator, responseSectionRef) {
|
|
|
707
1048
|
return responseClone.text();
|
|
708
1049
|
});
|
|
709
1050
|
}).then((data) => {
|
|
710
|
-
|
|
1051
|
+
gotResponse = true;
|
|
711
1052
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
712
1053
|
if (typeof data === "object") {
|
|
713
1054
|
console.log("Received JSON:", data);
|
|
714
|
-
|
|
1055
|
+
responseObj.body = JSON.stringify(data, null, 4);
|
|
715
1056
|
} else {
|
|
716
1057
|
console.log("Received text:", data);
|
|
717
|
-
|
|
1058
|
+
responseObj.body = data;
|
|
718
1059
|
}
|
|
1060
|
+
responsebodyElement.textContent = responseObj.body;
|
|
719
1061
|
}).catch((error) => {
|
|
720
1062
|
console.error("There has been a problem with your fetch operation:", error);
|
|
721
1063
|
});
|
|
722
1064
|
}
|
|
723
|
-
function updateTimeStatus(timeStatus, apiOperator) {
|
|
724
|
-
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
725
|
-
}
|
|
726
1065
|
function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
727
1066
|
const container = document.createElement("div");
|
|
728
1067
|
Object.assign(container.style, {
|
|
@@ -765,28 +1104,6 @@ function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
|
765
1104
|
});
|
|
766
1105
|
return container;
|
|
767
1106
|
}
|
|
768
|
-
function checkIfParameter(apiOperator) {
|
|
769
|
-
let hasRequestBody = false;
|
|
770
|
-
let hasRequestFormData = false;
|
|
771
|
-
const parameters = apiOperator.rawApiInfo.parameters;
|
|
772
|
-
if (parameters) {
|
|
773
|
-
for (let index = 0; index < parameters.length; index++) {
|
|
774
|
-
const parameter = parameters[index];
|
|
775
|
-
if (parameter.in == "query" || parameter.in == "path") {
|
|
776
|
-
} else if (parameter.in == "body") {
|
|
777
|
-
hasRequestBody = true;
|
|
778
|
-
parameter.name = parameter.name.charAt(0).toUpperCase() + parameter.name.slice(1);
|
|
779
|
-
} else if (parameter.in == "formData") {
|
|
780
|
-
hasRequestFormData = true;
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
const requestBody = apiOperator.rawApiInfo.requestBody;
|
|
785
|
-
if (requestBody) {
|
|
786
|
-
hasRequestBody = true;
|
|
787
|
-
}
|
|
788
|
-
return { hasRequestBody, hasRequestFormData };
|
|
789
|
-
}
|
|
790
1107
|
function formatDuration(milliseconds) {
|
|
791
1108
|
let totalSeconds = Math.floor(milliseconds / 1e3);
|
|
792
1109
|
let seconds = totalSeconds % 60;
|
|
@@ -799,9 +1116,9 @@ function formatDuration(milliseconds) {
|
|
|
799
1116
|
seconds = seconds.toString().padStart(2, "0");
|
|
800
1117
|
return `${hours}h${minutes}m${seconds}s${millisecondsPart}ms`;
|
|
801
1118
|
}
|
|
802
|
-
function getRequestUrl(
|
|
803
|
-
let reuqestUrl =
|
|
804
|
-
const requestParameters =
|
|
1119
|
+
function getRequestUrl(apiInfo) {
|
|
1120
|
+
let reuqestUrl = apiInfo.url;
|
|
1121
|
+
const requestParameters = apiInfo.rawApiInfo.parameters || [];
|
|
805
1122
|
if (requestParameters == null) {
|
|
806
1123
|
return reuqestUrl;
|
|
807
1124
|
}
|
|
@@ -810,11 +1127,45 @@ function getRequestUrl(apiOperator) {
|
|
|
810
1127
|
reuqestUrl = reuqestUrl.replace("{" + element.name + "}", element.value);
|
|
811
1128
|
}
|
|
812
1129
|
}
|
|
813
|
-
let queryParams = getQueryParams(
|
|
1130
|
+
let queryParams = getQueryParams(apiInfo, requestParameters);
|
|
814
1131
|
reuqestUrl = queryParams.length > 0 ? reuqestUrl + "?" + queryParams.join("&") : reuqestUrl;
|
|
815
1132
|
return reuqestUrl;
|
|
816
1133
|
}
|
|
817
|
-
function
|
|
1134
|
+
function addAuthHeader(apiInfo, headers) {
|
|
1135
|
+
const env = isBrowserEnvironment();
|
|
1136
|
+
if (apiInfo.auth.authType == "Basic Auth" && apiInfo.auth != null) {
|
|
1137
|
+
if (env) {
|
|
1138
|
+
const credentials = btoa(`${apiInfo.auth.username}:${apiInfo.auth.passWord}`);
|
|
1139
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
1140
|
+
} else {
|
|
1141
|
+
const buffer = Buffer.from(`${apiInfo.auth.username}:${apiInfo.auth.passWord}`);
|
|
1142
|
+
const credentials = buffer.toString("base64");
|
|
1143
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
1144
|
+
}
|
|
1145
|
+
} else if (apiInfo.auth.authType == "OAuth 2.0" && apiInfo.auth != null) {
|
|
1146
|
+
if (apiInfo.auth.token != null || apiInfo.auth.token != "") {
|
|
1147
|
+
headers["Authorization"] = `Bearer ${apiInfo.auth.token}`;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
function getHeadersParams(apiInfo, requestParameters) {
|
|
1152
|
+
let headersParams = [];
|
|
1153
|
+
for (const element of requestParameters) {
|
|
1154
|
+
if (element.in == "header") {
|
|
1155
|
+
headersParams[element.name] = element.value;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
if (apiInfo.customHeaderparameters) {
|
|
1159
|
+
for (let index = 0; index < apiInfo.customHeaderparameters.length; index++) {
|
|
1160
|
+
const paras = apiInfo.customHeaderparameters[index];
|
|
1161
|
+
if (paras.name != "" && paras.value != "" && paras.name != null && paras.value != null) {
|
|
1162
|
+
headersParams[paras.name] = paras.value;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return headersParams;
|
|
1167
|
+
}
|
|
1168
|
+
function getQueryParams(apiInfo, requestParameters) {
|
|
818
1169
|
let queryParams = [];
|
|
819
1170
|
for (const element of requestParameters) {
|
|
820
1171
|
if (element.in == "query") {
|
|
@@ -829,9 +1180,9 @@ function getQueryParams(apiOperator, requestParameters) {
|
|
|
829
1180
|
}
|
|
830
1181
|
}
|
|
831
1182
|
}
|
|
832
|
-
if (
|
|
833
|
-
for (let index = 0; index <
|
|
834
|
-
const paras =
|
|
1183
|
+
if (apiInfo.customQueryparameters) {
|
|
1184
|
+
for (let index = 0; index < apiInfo.customQueryparameters.length; index++) {
|
|
1185
|
+
const paras = apiInfo.customQueryparameters[index];
|
|
835
1186
|
if (paras.name != "" && paras.value != "" && paras.name != null && paras.value != null) {
|
|
836
1187
|
queryParams.push(paras.name + "=" + paras.value);
|
|
837
1188
|
}
|
|
@@ -858,6 +1209,15 @@ function getRequestFormData(rawApiInfo) {
|
|
|
858
1209
|
}
|
|
859
1210
|
return formData;
|
|
860
1211
|
}
|
|
1212
|
+
function isBrowserEnvironment() {
|
|
1213
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
1214
|
+
return true;
|
|
1215
|
+
} else if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
1216
|
+
return false;
|
|
1217
|
+
} else {
|
|
1218
|
+
return false;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
861
1221
|
function createSvg() {
|
|
862
1222
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
863
1223
|
svg.setAttribute("width", "21");
|
|
@@ -876,18 +1236,16 @@ function createSvg() {
|
|
|
876
1236
|
}
|
|
877
1237
|
function parseParaModel(parameterObj, dataDef) {
|
|
878
1238
|
let bodyModel;
|
|
879
|
-
if (parameterObj
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
bodyModel = parseElement(itemObj);
|
|
888
|
-
}
|
|
889
|
-
bodyModel = [bodyModel];
|
|
1239
|
+
if (parameterObj.schema["$ref"]) {
|
|
1240
|
+
bodyModel = parseModel(parameterObj.schema["$ref"], dataDef);
|
|
1241
|
+
} else if (parameterObj.schema["type"] == "array") {
|
|
1242
|
+
const itemObj = parameterObj.schema["items"];
|
|
1243
|
+
if (itemObj["$ref"]) {
|
|
1244
|
+
bodyModel = parseModel(itemObj["$ref"], dataDef);
|
|
1245
|
+
} else if (itemObj["type"]) {
|
|
1246
|
+
bodyModel = parseElement(itemObj);
|
|
890
1247
|
}
|
|
1248
|
+
bodyModel = [bodyModel];
|
|
891
1249
|
}
|
|
892
1250
|
return bodyModel;
|
|
893
1251
|
}
|
|
@@ -918,10 +1276,66 @@ function parseModel(modelDef, apiDef) {
|
|
|
918
1276
|
}
|
|
919
1277
|
return model;
|
|
920
1278
|
}
|
|
1279
|
+
function parseFormDataModel(modelDef, apiDef) {
|
|
1280
|
+
const model = [];
|
|
1281
|
+
const bodyName = modelDef.substring(modelDef.lastIndexOf("/") + 1);
|
|
1282
|
+
const def = apiDef[bodyName];
|
|
1283
|
+
const props = def["properties"];
|
|
1284
|
+
if (props) {
|
|
1285
|
+
for (const key in props) {
|
|
1286
|
+
if (Object.prototype.hasOwnProperty.call(props, key)) {
|
|
1287
|
+
const element = props[key];
|
|
1288
|
+
let modelEle;
|
|
1289
|
+
if (element.hasOwnProperty("items") && element["type"] == "array") {
|
|
1290
|
+
if (element["items"]["$ref"]) {
|
|
1291
|
+
modelEle = [parseModel(element["items"]["$ref"], apiDef)];
|
|
1292
|
+
} else if (element["items"]["type"]) {
|
|
1293
|
+
modelEle = [parseElement(element["items"])];
|
|
1294
|
+
}
|
|
1295
|
+
if (modelEle) {
|
|
1296
|
+
model.push({
|
|
1297
|
+
type: "string",
|
|
1298
|
+
uiType: "text",
|
|
1299
|
+
name: key,
|
|
1300
|
+
value: JSON.stringify(modelEle)
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
} else if (element["type"]) {
|
|
1304
|
+
model.push({
|
|
1305
|
+
type: element["type"],
|
|
1306
|
+
uiType: element["type"] == "integer" || element["type"] == "number" ? "number" : "text",
|
|
1307
|
+
name: key,
|
|
1308
|
+
value: parseElement(element)
|
|
1309
|
+
});
|
|
1310
|
+
} else if (element["$ref"]) {
|
|
1311
|
+
const bodyModel = parseModel(element["$ref"], apiDef);
|
|
1312
|
+
model.push({
|
|
1313
|
+
type: "string",
|
|
1314
|
+
uiType: "text",
|
|
1315
|
+
name: key,
|
|
1316
|
+
value: JSON.stringify(bodyModel)
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return model;
|
|
1323
|
+
}
|
|
1324
|
+
function parseFormDataParaModel(parameterObj, dataDef) {
|
|
1325
|
+
let bodyModel = [];
|
|
1326
|
+
if (parameterObj.schema["$ref"]) {
|
|
1327
|
+
bodyModel = parseFormDataModel(parameterObj.schema["$ref"], dataDef);
|
|
1328
|
+
}
|
|
1329
|
+
return bodyModel;
|
|
1330
|
+
}
|
|
921
1331
|
function parseElement(element) {
|
|
922
1332
|
let elementValue;
|
|
923
1333
|
if (element["type"].includes("integer")) {
|
|
924
|
-
|
|
1334
|
+
if (element["enum"]) {
|
|
1335
|
+
elementValue = element["enum"][0];
|
|
1336
|
+
} else {
|
|
1337
|
+
elementValue = 0;
|
|
1338
|
+
}
|
|
925
1339
|
} else if (element["type"].includes("boolean")) {
|
|
926
1340
|
elementValue = false;
|
|
927
1341
|
} else if (element["type"].includes("string")) {
|
|
@@ -931,11 +1345,24 @@ function parseElement(element) {
|
|
|
931
1345
|
elementValue = "";
|
|
932
1346
|
}
|
|
933
1347
|
}
|
|
1348
|
+
if (element["default"]) {
|
|
1349
|
+
elementValue = element["default"];
|
|
1350
|
+
}
|
|
934
1351
|
if (element["example"]) {
|
|
935
1352
|
elementValue = element["example"];
|
|
936
1353
|
}
|
|
937
1354
|
return elementValue;
|
|
938
1355
|
}
|
|
1356
|
+
function parseElementType(element) {
|
|
1357
|
+
if (element["type"].includes("integer")) {
|
|
1358
|
+
return "integer";
|
|
1359
|
+
} else if (element["type"].includes("boolean")) {
|
|
1360
|
+
return "boolean";
|
|
1361
|
+
} else if (element["type"].includes("string")) {
|
|
1362
|
+
return "string";
|
|
1363
|
+
}
|
|
1364
|
+
return "string";
|
|
1365
|
+
}
|
|
939
1366
|
var HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
940
1367
|
function isHttpMethod(method) {
|
|
941
1368
|
return HTTP_METHODS.includes(method);
|
|
@@ -964,48 +1391,90 @@ function parseOpenAPI(openapiSpec) {
|
|
|
964
1391
|
const apiOperator = {
|
|
965
1392
|
method: method.toUpperCase(),
|
|
966
1393
|
url: path,
|
|
967
|
-
rawApiInfo:
|
|
1394
|
+
rawApiInfo: operation,
|
|
968
1395
|
requestBody: null,
|
|
969
1396
|
response: {},
|
|
970
|
-
|
|
971
|
-
{
|
|
972
|
-
type: "No Auth"
|
|
973
|
-
},
|
|
974
|
-
{
|
|
975
|
-
type: "Basic Auth",
|
|
976
|
-
parameters: [
|
|
977
|
-
{
|
|
978
|
-
name: "userName",
|
|
979
|
-
value: ""
|
|
980
|
-
},
|
|
981
|
-
{
|
|
982
|
-
name: "password",
|
|
983
|
-
value: ""
|
|
984
|
-
}
|
|
985
|
-
]
|
|
986
|
-
}
|
|
987
|
-
]
|
|
1397
|
+
auth: {}
|
|
988
1398
|
};
|
|
989
1399
|
if (operation) {
|
|
990
|
-
if (
|
|
991
|
-
const
|
|
992
|
-
if (
|
|
1400
|
+
if (apiOperator.rawApiInfo.parameters) {
|
|
1401
|
+
const parameterBody = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "body");
|
|
1402
|
+
if (parameterBody && parameterBody.length > 0) {
|
|
1403
|
+
apiOperator["requestBody"] = {
|
|
1404
|
+
content: {}
|
|
1405
|
+
};
|
|
1406
|
+
apiOperator["consumes"] = apiOperator.rawApiInfo["consumes"];
|
|
1407
|
+
const currentConsume = apiOperator.rawApiInfo["consumes"].length > 0 ? apiOperator.rawApiInfo["consumes"][0] : "application/json";
|
|
1408
|
+
apiOperator["currentConsume"] = currentConsume;
|
|
1409
|
+
let requestBody = parseParaModel(parameterBody[0], openapiSpec["definitions"]);
|
|
1410
|
+
apiOperator["requestBody"]["content"][currentConsume] = JSON.stringify(requestBody, null, 4);
|
|
1411
|
+
apiOperator["parameterHasBody"] = true;
|
|
1412
|
+
} else {
|
|
1413
|
+
for (const parameter of apiOperator.rawApiInfo.parameters) {
|
|
1414
|
+
if (parameter.in == "query" || parameter.in == "header" || parameter.in == "path" || parameter.in == "formData") {
|
|
1415
|
+
if (parameter.type == "integer" || parameter.schema != null && parameter.schema.type == "integer" || parameter.type == "number" || parameter.schema != null && parameter.schema.type == "number") {
|
|
1416
|
+
parameter.uiType = "number";
|
|
1417
|
+
}
|
|
1418
|
+
if (parameter.type == "string" || parameter.schema != null && parameter.schema.type == "string") {
|
|
1419
|
+
parameter.uiType = "text";
|
|
1420
|
+
}
|
|
1421
|
+
if (parameter.type == "boolean" || parameter.schema != null && parameter.schema.type == "boolean") {
|
|
1422
|
+
parameter.uiType = "text";
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const parameterFormData = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "formData");
|
|
1427
|
+
if (parameterFormData && parameterFormData.length > 0) {
|
|
1428
|
+
apiOperator["parameterHasFormDataVer2"] = true;
|
|
1429
|
+
}
|
|
1430
|
+
for (const param of apiOperator.rawApiInfo.parameters) {
|
|
1431
|
+
const paramSchema = param.schema;
|
|
1432
|
+
if (paramSchema && paramSchema["$ref"]) {
|
|
1433
|
+
const bodyName = paramSchema["$ref"].substring(paramSchema["$ref"].lastIndexOf("/") + 1);
|
|
1434
|
+
if (openapiSpec && openapiSpec["components"] != null && openapiSpec["components"]["schemas"] != null) {
|
|
1435
|
+
const def = openapiSpec["components"] != null ? openapiSpec["components"]["schemas"][bodyName] : { type: "" };
|
|
1436
|
+
param.type = parseElementType(def);
|
|
1437
|
+
param.uiType = param.type == "integer" || param.type == "number" ? "number" : "text";
|
|
1438
|
+
param.value = parseElement(def);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
993
1442
|
}
|
|
994
1443
|
}
|
|
995
|
-
if (
|
|
996
|
-
const
|
|
997
|
-
|
|
1444
|
+
if (apiOperator.rawApiInfo.requestBody) {
|
|
1445
|
+
const content = apiOperator.rawApiInfo.requestBody.content;
|
|
1446
|
+
apiOperator["requestBody"] = {
|
|
1447
|
+
content: {}
|
|
1448
|
+
};
|
|
998
1449
|
for (const key in content) {
|
|
999
1450
|
if (Object.prototype.hasOwnProperty.call(content, key)) {
|
|
1000
1451
|
const element = content[key];
|
|
1452
|
+
apiOperator["consumes"]?.push(key);
|
|
1001
1453
|
if (element) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1454
|
+
if (element.schema == void 0) {
|
|
1455
|
+
console.log("pathKey is:", path);
|
|
1456
|
+
console.log("key is:", key);
|
|
1457
|
+
console.log("content is:", content);
|
|
1458
|
+
console.log("Unsupported requestBody schema format:", element);
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
if (key != "application/x-www-form-urlencoded" && key != "multipart/form-data") {
|
|
1462
|
+
let requestBody = parseParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1463
|
+
apiOperator["requestBody"]["content"][key] = JSON.stringify(requestBody, null, 4);
|
|
1464
|
+
} else {
|
|
1465
|
+
let requestFormDataBody = parseFormDataParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1466
|
+
apiOperator["requestBody"]["content"][key] = requestFormDataBody;
|
|
1467
|
+
}
|
|
1468
|
+
apiOperator["parameterHasBody"] = true;
|
|
1004
1469
|
}
|
|
1005
1470
|
}
|
|
1006
1471
|
}
|
|
1472
|
+
if (apiOperator.consumes) {
|
|
1473
|
+
if (apiOperator.consumes.length > 0) {
|
|
1474
|
+
apiOperator["currentConsume"] = apiOperator["consumes"][0];
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1007
1477
|
}
|
|
1008
|
-
apiOperator.rawApiInfo = operation;
|
|
1009
1478
|
apiOperatorList.push(apiOperator);
|
|
1010
1479
|
}
|
|
1011
1480
|
});
|