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.js
CHANGED
|
@@ -5,7 +5,6 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
5
5
|
display: inline-flex;
|
|
6
6
|
flex-direction: column;
|
|
7
7
|
gap: 5px;
|
|
8
|
-
height: 100%;
|
|
9
8
|
justify-content: flex-start;
|
|
10
9
|
width: 100%
|
|
11
10
|
}
|
|
@@ -62,7 +61,6 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
62
61
|
display: inline-flex;
|
|
63
62
|
flex-direction: column;
|
|
64
63
|
gap: 8px;
|
|
65
|
-
height: 100%;
|
|
66
64
|
justify-content: flex-start;
|
|
67
65
|
width: 100%
|
|
68
66
|
}
|
|
@@ -188,10 +186,12 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
188
186
|
align-items: center;
|
|
189
187
|
align-self: stretch;
|
|
190
188
|
display: inline-flex;
|
|
191
|
-
height: 114px;
|
|
192
189
|
justify-content: flex-start;
|
|
193
190
|
padding-right: 5px
|
|
194
191
|
}
|
|
192
|
+
.codigma-apiunit-request-body-info {
|
|
193
|
+
align-self: stretch;
|
|
194
|
+
}
|
|
195
195
|
.codigma-apiunit-parakeyvalues {
|
|
196
196
|
align-items: flex-start;
|
|
197
197
|
align-self: stretch;
|
|
@@ -251,9 +251,11 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
251
251
|
}`;
|
|
252
252
|
|
|
253
253
|
// src/api-render-ui.ts
|
|
254
|
-
var ApiRenderer = class {
|
|
254
|
+
var ApiRenderer = class _ApiRenderer {
|
|
255
255
|
options;
|
|
256
256
|
container;
|
|
257
|
+
// 静态标志:记录是否已注入全局样式
|
|
258
|
+
static globalStyleInjected = false;
|
|
257
259
|
constructor(options) {
|
|
258
260
|
this.options = Object.assign({
|
|
259
261
|
mountPoint: document?.body,
|
|
@@ -265,9 +267,12 @@ var ApiRenderer = class {
|
|
|
265
267
|
}
|
|
266
268
|
render(apiSpec, renderUnit = false) {
|
|
267
269
|
const appendInlineStyle = (text) => {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
270
|
+
if (!_ApiRenderer.globalStyleInjected) {
|
|
271
|
+
const styleEl = document.createElement("style");
|
|
272
|
+
styleEl.textContent = text;
|
|
273
|
+
document.head.appendChild(styleEl);
|
|
274
|
+
_ApiRenderer.globalStyleInjected = true;
|
|
275
|
+
}
|
|
271
276
|
};
|
|
272
277
|
appendInlineStyle(GLOBAL_STYLES);
|
|
273
278
|
const elementMap = /* @__PURE__ */ new Map();
|
|
@@ -342,12 +347,47 @@ var ApiRenderer = class {
|
|
|
342
347
|
mountElement.appendChild(this.container);
|
|
343
348
|
}
|
|
344
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
|
+
];
|
|
345
389
|
function renderApiUnit(apiOperator, containerRef, elementMap) {
|
|
346
390
|
return function(evt) {
|
|
347
|
-
console.log("\u70B9\u51FB\u7684API\u64CD\u4F5C\uFF1A");
|
|
348
|
-
console.log("\u65B9\u6CD5:", apiOperator.method);
|
|
349
|
-
console.log("URL:", apiOperator.url);
|
|
350
|
-
console.log("------------------------");
|
|
351
391
|
const currentTarget = evt.currentTarget;
|
|
352
392
|
if (elementMap.has(currentTarget)) {
|
|
353
393
|
const newElement = elementMap.get(currentTarget);
|
|
@@ -378,7 +418,7 @@ function createApiUnit(apiOperator) {
|
|
|
378
418
|
const paramSection = createParamSection(apiOperator);
|
|
379
419
|
const headerSection = createSectionHeader(apiOperator);
|
|
380
420
|
const authSection = createSectionAuth(apiOperator);
|
|
381
|
-
const bodySection = createSectionRequestBody(apiOperator
|
|
421
|
+
const bodySection = createSectionRequestBody(apiOperator);
|
|
382
422
|
reqContent.append(paramSection, headerSection, authSection, bodySection);
|
|
383
423
|
apiContainer.appendChild(reqContent);
|
|
384
424
|
apiContainer.appendChild(responseSection);
|
|
@@ -409,7 +449,6 @@ function createReqOperator(apiOperator) {
|
|
|
409
449
|
reqUrl.className = "Requrl codigma-apiunit-requrl";
|
|
410
450
|
reqUrl.value = apiOperator.url;
|
|
411
451
|
reqUrl.addEventListener("input", (e) => {
|
|
412
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
413
452
|
apiOperator.url = e.target.value;
|
|
414
453
|
});
|
|
415
454
|
reqOperator.appendChild(reqUrl);
|
|
@@ -422,7 +461,6 @@ function createReqOperator(apiOperator) {
|
|
|
422
461
|
sendText.textContent = "Send";
|
|
423
462
|
sendButton.appendChild(sendText);
|
|
424
463
|
sendButton.addEventListener("click", (e) => {
|
|
425
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
426
464
|
const respRef = apiOperator._responseSectionRef || null;
|
|
427
465
|
sendRequest(apiOperator, respRef);
|
|
428
466
|
});
|
|
@@ -489,17 +527,135 @@ function createSectionAuth(apiOperator) {
|
|
|
489
527
|
const authValues = document.createElement("div");
|
|
490
528
|
authValues.setAttribute("data-layer", "paraKeyValues");
|
|
491
529
|
authValues.className = "Parakeyvalues codigma-apiunit-parakeyvalues";
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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);
|
|
499
554
|
authSection.append(authCnr, authValues);
|
|
500
555
|
return authSection;
|
|
501
556
|
}
|
|
502
|
-
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) {
|
|
503
659
|
const bodySection = document.createElement("div");
|
|
504
660
|
bodySection.setAttribute("data-layer", "request-body-section");
|
|
505
661
|
bodySection.className = "RequestBodySection codigma-apiunit-request-body-section";
|
|
@@ -512,13 +668,108 @@ function createSectionRequestBody(requestBody) {
|
|
|
512
668
|
bodyText.textContent = "Body";
|
|
513
669
|
bodyCnr.appendChild(bodyText);
|
|
514
670
|
bodySection.appendChild(bodyCnr);
|
|
515
|
-
|
|
516
|
-
bodyValue.setAttribute("data-layer", "bodyTextValue");
|
|
517
|
-
bodyValue.className = "Id0CategoryId0NameNamePhotourlsTagsId0NameStatusAvailable codigma-apiunit-parakeyvalues";
|
|
518
|
-
bodyValue.value = JSON.stringify(requestBody);
|
|
519
|
-
bodySection.appendChild(bodyValue);
|
|
671
|
+
renderConsumeSection(apiOperator, bodySection, bodyCnr);
|
|
520
672
|
return bodySection;
|
|
521
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
|
+
}
|
|
522
773
|
function createSectionResponse(apiOperator) {
|
|
523
774
|
const responseSection = document.createElement("div");
|
|
524
775
|
responseSection.setAttribute("data-layer", "reqresponse");
|
|
@@ -553,6 +804,9 @@ function createTimeStatusElement(apiOperator) {
|
|
|
553
804
|
updateTimeStatus(timeStatus, apiOperator);
|
|
554
805
|
return timeStatus;
|
|
555
806
|
}
|
|
807
|
+
function updateTimeStatus(timeStatus, apiOperator) {
|
|
808
|
+
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
809
|
+
}
|
|
556
810
|
function createRow(parameter) {
|
|
557
811
|
const petIdRow = document.createElement("div");
|
|
558
812
|
petIdRow.setAttribute("data-layer", "keyValue");
|
|
@@ -566,7 +820,6 @@ function createRow(parameter) {
|
|
|
566
820
|
petIdValue.className = "Valuetext codigma-apiunit-valuetext";
|
|
567
821
|
petIdValue.value = parameter["value"] || "";
|
|
568
822
|
petIdValue.addEventListener("input", (e) => {
|
|
569
|
-
console.log("\u5F53\u524D\u503C:", e.target.value);
|
|
570
823
|
parameter["value"] = e.target.value;
|
|
571
824
|
});
|
|
572
825
|
petIdRow.append(petIdLabel, petIdValue);
|
|
@@ -580,31 +833,24 @@ function createInputElement() {
|
|
|
580
833
|
inputText.setAttribute("autocomplete", "off");
|
|
581
834
|
return inputText;
|
|
582
835
|
}
|
|
583
|
-
function createSelectRow(
|
|
836
|
+
function createSelectRow(name, args) {
|
|
584
837
|
const container = document.createElement("div");
|
|
585
838
|
container.setAttribute("data-layer", "keyValue");
|
|
586
839
|
container.className = "Keyvalue codigma-apiunit-keyvalue";
|
|
587
840
|
const typeLabel = document.createElement("div");
|
|
588
|
-
typeLabel.setAttribute("data-layer",
|
|
841
|
+
typeLabel.setAttribute("data-layer", name);
|
|
589
842
|
typeLabel.className = "type codigma-apiunit-send";
|
|
590
|
-
typeLabel.textContent = "
|
|
843
|
+
typeLabel.textContent = name + ":";
|
|
591
844
|
const selectElement = document.createElement("select");
|
|
592
845
|
selectElement.name = "text-select";
|
|
593
846
|
selectElement.label = "text-select";
|
|
594
847
|
selectElement.setAttribute("data-layer", "valueText");
|
|
595
|
-
|
|
848
|
+
args.forEach((auth) => {
|
|
596
849
|
const option1 = document.createElement("option");
|
|
597
|
-
option1.value = auth["
|
|
598
|
-
option1.textContent = auth["
|
|
850
|
+
option1.value = auth["value"];
|
|
851
|
+
option1.textContent = auth["displayName"] != null || auth["label"] != null ? auth["displayName"] || auth["label"] : auth["value"];
|
|
599
852
|
selectElement.appendChild(option1);
|
|
600
853
|
});
|
|
601
|
-
selectElement.addEventListener("change", function(event) {
|
|
602
|
-
authValues && Array.from(authValues.children).slice(1).forEach((el) => el.remove());
|
|
603
|
-
const auth = auths[event.target.selectedIndex];
|
|
604
|
-
let parameters = auth.parameters || [];
|
|
605
|
-
const authRows = parameters.map((parameter) => createRow(parameter));
|
|
606
|
-
authValues.append(...authRows);
|
|
607
|
-
});
|
|
608
854
|
container.appendChild(typeLabel);
|
|
609
855
|
container.appendChild(selectElement);
|
|
610
856
|
return container;
|
|
@@ -615,58 +861,153 @@ function isPathOrQueryParam(param) {
|
|
|
615
861
|
function isHeaderParam(param) {
|
|
616
862
|
return param.in === "header";
|
|
617
863
|
}
|
|
618
|
-
function
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
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 {
|
|
622
943
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
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";
|
|
626
957
|
let headers = {
|
|
627
958
|
"Content-Type": header
|
|
628
959
|
};
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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
|
+
}
|
|
634
976
|
}
|
|
977
|
+
} else {
|
|
978
|
+
body = "";
|
|
635
979
|
}
|
|
980
|
+
} else {
|
|
981
|
+
body = "";
|
|
636
982
|
}
|
|
637
|
-
|
|
638
|
-
if (apiOperator.custom) {
|
|
639
|
-
if (apiOperator.method.toUpperCase() == "POST" || apiOperator.method.toUpperCase() == "PUT") {
|
|
640
|
-
body = apiOperator.requestBody;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
apiOperator.ifSendingRequest = true;
|
|
983
|
+
ifSendingRequest = true;
|
|
644
984
|
const startTime = Date.now();
|
|
645
985
|
apiOperator.controller = new AbortController();
|
|
646
986
|
const signal = apiOperator.controller.signal;
|
|
647
987
|
const overlayLayerContainer = createRequestOverlayLayer(apiOperator, responseSectionRef);
|
|
648
988
|
fetch(reuqestUrl, {
|
|
649
|
-
method:
|
|
989
|
+
method: apiInfo.method.toUpperCase(),
|
|
650
990
|
headers,
|
|
651
|
-
body
|
|
991
|
+
body,
|
|
652
992
|
signal
|
|
653
993
|
}).then((response) => {
|
|
654
994
|
if (!response.ok) {
|
|
655
|
-
|
|
995
|
+
responseObj = {
|
|
656
996
|
status: response.status,
|
|
657
|
-
statusText: response.statusText
|
|
997
|
+
statusText: response.statusText,
|
|
998
|
+
body: ""
|
|
658
999
|
};
|
|
659
1000
|
const endTime2 = Date.now();
|
|
660
|
-
|
|
661
|
-
|
|
1001
|
+
requestDuration = formatDuration(endTime2 - startTime);
|
|
1002
|
+
ifSendingRequest = false;
|
|
662
1003
|
throw new Error("Network response was not ok.");
|
|
663
1004
|
}
|
|
664
1005
|
const endTime = Date.now();
|
|
665
|
-
|
|
1006
|
+
requestDuration = formatDuration(endTime - startTime);
|
|
666
1007
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
667
1008
|
responsebodyElement.removeChild(overlayLayerContainer);
|
|
668
|
-
|
|
669
|
-
|
|
1009
|
+
ifSendingRequest = false;
|
|
1010
|
+
responseObj = {
|
|
670
1011
|
status: response.status,
|
|
671
1012
|
statusText: response.statusText
|
|
672
1013
|
};
|
|
@@ -681,22 +1022,20 @@ function sendRequest(apiOperator, responseSectionRef) {
|
|
|
681
1022
|
return responseClone.text();
|
|
682
1023
|
});
|
|
683
1024
|
}).then((data) => {
|
|
684
|
-
|
|
1025
|
+
gotResponse = true;
|
|
685
1026
|
const responsebodyElement = responseSectionRef.querySelector('[data-layer="responsebody"]');
|
|
686
1027
|
if (typeof data === "object") {
|
|
687
1028
|
console.log("Received JSON:", data);
|
|
688
|
-
|
|
1029
|
+
responseObj.body = JSON.stringify(data, null, 4);
|
|
689
1030
|
} else {
|
|
690
1031
|
console.log("Received text:", data);
|
|
691
|
-
|
|
1032
|
+
responseObj.body = data;
|
|
692
1033
|
}
|
|
1034
|
+
responsebodyElement.textContent = responseObj.body;
|
|
693
1035
|
}).catch((error) => {
|
|
694
1036
|
console.error("There has been a problem with your fetch operation:", error);
|
|
695
1037
|
});
|
|
696
1038
|
}
|
|
697
|
-
function updateTimeStatus(timeStatus, apiOperator) {
|
|
698
|
-
timeStatus.textContent = `Status: ${apiOperator.response.status || ""} ${apiOperator.response.statusText || ""} Time: ${apiOperator.requestDuration || ""}`;
|
|
699
|
-
}
|
|
700
1039
|
function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
701
1040
|
const container = document.createElement("div");
|
|
702
1041
|
Object.assign(container.style, {
|
|
@@ -739,28 +1078,6 @@ function createRequestOverlayLayer(apiOperator, responseSectionRef) {
|
|
|
739
1078
|
});
|
|
740
1079
|
return container;
|
|
741
1080
|
}
|
|
742
|
-
function checkIfParameter(apiOperator) {
|
|
743
|
-
let hasRequestBody = false;
|
|
744
|
-
let hasRequestFormData = false;
|
|
745
|
-
const parameters = apiOperator.rawApiInfo.parameters;
|
|
746
|
-
if (parameters) {
|
|
747
|
-
for (let index = 0; index < parameters.length; index++) {
|
|
748
|
-
const parameter = parameters[index];
|
|
749
|
-
if (parameter.in == "query" || parameter.in == "path") {
|
|
750
|
-
} else if (parameter.in == "body") {
|
|
751
|
-
hasRequestBody = true;
|
|
752
|
-
parameter.name = parameter.name.charAt(0).toUpperCase() + parameter.name.slice(1);
|
|
753
|
-
} else if (parameter.in == "formData") {
|
|
754
|
-
hasRequestFormData = true;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
const requestBody = apiOperator.rawApiInfo.requestBody;
|
|
759
|
-
if (requestBody) {
|
|
760
|
-
hasRequestBody = true;
|
|
761
|
-
}
|
|
762
|
-
return { hasRequestBody, hasRequestFormData };
|
|
763
|
-
}
|
|
764
1081
|
function formatDuration(milliseconds) {
|
|
765
1082
|
let totalSeconds = Math.floor(milliseconds / 1e3);
|
|
766
1083
|
let seconds = totalSeconds % 60;
|
|
@@ -773,9 +1090,9 @@ function formatDuration(milliseconds) {
|
|
|
773
1090
|
seconds = seconds.toString().padStart(2, "0");
|
|
774
1091
|
return `${hours}h${minutes}m${seconds}s${millisecondsPart}ms`;
|
|
775
1092
|
}
|
|
776
|
-
function getRequestUrl(
|
|
777
|
-
let reuqestUrl =
|
|
778
|
-
const requestParameters =
|
|
1093
|
+
function getRequestUrl(apiInfo) {
|
|
1094
|
+
let reuqestUrl = apiInfo.url;
|
|
1095
|
+
const requestParameters = apiInfo.rawApiInfo.parameters || [];
|
|
779
1096
|
if (requestParameters == null) {
|
|
780
1097
|
return reuqestUrl;
|
|
781
1098
|
}
|
|
@@ -784,11 +1101,45 @@ function getRequestUrl(apiOperator) {
|
|
|
784
1101
|
reuqestUrl = reuqestUrl.replace("{" + element.name + "}", element.value);
|
|
785
1102
|
}
|
|
786
1103
|
}
|
|
787
|
-
let queryParams = getQueryParams(
|
|
1104
|
+
let queryParams = getQueryParams(apiInfo, requestParameters);
|
|
788
1105
|
reuqestUrl = queryParams.length > 0 ? reuqestUrl + "?" + queryParams.join("&") : reuqestUrl;
|
|
789
1106
|
return reuqestUrl;
|
|
790
1107
|
}
|
|
791
|
-
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) {
|
|
792
1143
|
let queryParams = [];
|
|
793
1144
|
for (const element of requestParameters) {
|
|
794
1145
|
if (element.in == "query") {
|
|
@@ -803,9 +1154,9 @@ function getQueryParams(apiOperator, requestParameters) {
|
|
|
803
1154
|
}
|
|
804
1155
|
}
|
|
805
1156
|
}
|
|
806
|
-
if (
|
|
807
|
-
for (let index = 0; index <
|
|
808
|
-
const paras =
|
|
1157
|
+
if (apiInfo.customQueryparameters) {
|
|
1158
|
+
for (let index = 0; index < apiInfo.customQueryparameters.length; index++) {
|
|
1159
|
+
const paras = apiInfo.customQueryparameters[index];
|
|
809
1160
|
if (paras.name != "" && paras.value != "" && paras.name != null && paras.value != null) {
|
|
810
1161
|
queryParams.push(paras.name + "=" + paras.value);
|
|
811
1162
|
}
|
|
@@ -832,6 +1183,15 @@ function getRequestFormData(rawApiInfo) {
|
|
|
832
1183
|
}
|
|
833
1184
|
return formData;
|
|
834
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
|
+
}
|
|
835
1195
|
function createSvg() {
|
|
836
1196
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
837
1197
|
svg.setAttribute("width", "21");
|
|
@@ -850,18 +1210,16 @@ function createSvg() {
|
|
|
850
1210
|
}
|
|
851
1211
|
function parseParaModel(parameterObj, dataDef) {
|
|
852
1212
|
let bodyModel;
|
|
853
|
-
if (parameterObj
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
bodyModel = parseElement(itemObj);
|
|
862
|
-
}
|
|
863
|
-
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);
|
|
864
1221
|
}
|
|
1222
|
+
bodyModel = [bodyModel];
|
|
865
1223
|
}
|
|
866
1224
|
return bodyModel;
|
|
867
1225
|
}
|
|
@@ -892,10 +1250,66 @@ function parseModel(modelDef, apiDef) {
|
|
|
892
1250
|
}
|
|
893
1251
|
return model;
|
|
894
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
|
+
}
|
|
895
1305
|
function parseElement(element) {
|
|
896
1306
|
let elementValue;
|
|
897
1307
|
if (element["type"].includes("integer")) {
|
|
898
|
-
|
|
1308
|
+
if (element["enum"]) {
|
|
1309
|
+
elementValue = element["enum"][0];
|
|
1310
|
+
} else {
|
|
1311
|
+
elementValue = 0;
|
|
1312
|
+
}
|
|
899
1313
|
} else if (element["type"].includes("boolean")) {
|
|
900
1314
|
elementValue = false;
|
|
901
1315
|
} else if (element["type"].includes("string")) {
|
|
@@ -905,11 +1319,24 @@ function parseElement(element) {
|
|
|
905
1319
|
elementValue = "";
|
|
906
1320
|
}
|
|
907
1321
|
}
|
|
1322
|
+
if (element["default"]) {
|
|
1323
|
+
elementValue = element["default"];
|
|
1324
|
+
}
|
|
908
1325
|
if (element["example"]) {
|
|
909
1326
|
elementValue = element["example"];
|
|
910
1327
|
}
|
|
911
1328
|
return elementValue;
|
|
912
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
|
+
}
|
|
913
1340
|
var HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
914
1341
|
function isHttpMethod(method) {
|
|
915
1342
|
return HTTP_METHODS.includes(method);
|
|
@@ -938,48 +1365,90 @@ function parseOpenAPI(openapiSpec) {
|
|
|
938
1365
|
const apiOperator = {
|
|
939
1366
|
method: method.toUpperCase(),
|
|
940
1367
|
url: path,
|
|
941
|
-
rawApiInfo:
|
|
1368
|
+
rawApiInfo: operation,
|
|
942
1369
|
requestBody: null,
|
|
943
1370
|
response: {},
|
|
944
|
-
|
|
945
|
-
{
|
|
946
|
-
type: "No Auth"
|
|
947
|
-
},
|
|
948
|
-
{
|
|
949
|
-
type: "Basic Auth",
|
|
950
|
-
parameters: [
|
|
951
|
-
{
|
|
952
|
-
name: "userName",
|
|
953
|
-
value: ""
|
|
954
|
-
},
|
|
955
|
-
{
|
|
956
|
-
name: "password",
|
|
957
|
-
value: ""
|
|
958
|
-
}
|
|
959
|
-
]
|
|
960
|
-
}
|
|
961
|
-
]
|
|
1371
|
+
auth: {}
|
|
962
1372
|
};
|
|
963
1373
|
if (operation) {
|
|
964
|
-
if (
|
|
965
|
-
const
|
|
966
|
-
if (
|
|
1374
|
+
if (apiOperator.rawApiInfo.parameters) {
|
|
1375
|
+
const parameterBody = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "body");
|
|
1376
|
+
if (parameterBody && parameterBody.length > 0) {
|
|
1377
|
+
apiOperator["requestBody"] = {
|
|
1378
|
+
content: {}
|
|
1379
|
+
};
|
|
1380
|
+
apiOperator["consumes"] = apiOperator.rawApiInfo["consumes"];
|
|
1381
|
+
const currentConsume = apiOperator.rawApiInfo["consumes"].length > 0 ? apiOperator.rawApiInfo["consumes"][0] : "application/json";
|
|
1382
|
+
apiOperator["currentConsume"] = currentConsume;
|
|
1383
|
+
let requestBody = parseParaModel(parameterBody[0], openapiSpec["definitions"]);
|
|
1384
|
+
apiOperator["requestBody"]["content"][currentConsume] = JSON.stringify(requestBody, null, 4);
|
|
1385
|
+
apiOperator["parameterHasBody"] = true;
|
|
1386
|
+
} else {
|
|
1387
|
+
for (const parameter of apiOperator.rawApiInfo.parameters) {
|
|
1388
|
+
if (parameter.in == "query" || parameter.in == "header" || parameter.in == "path" || parameter.in == "formData") {
|
|
1389
|
+
if (parameter.type == "integer" || parameter.schema != null && parameter.schema.type == "integer" || parameter.type == "number" || parameter.schema != null && parameter.schema.type == "number") {
|
|
1390
|
+
parameter.uiType = "number";
|
|
1391
|
+
}
|
|
1392
|
+
if (parameter.type == "string" || parameter.schema != null && parameter.schema.type == "string") {
|
|
1393
|
+
parameter.uiType = "text";
|
|
1394
|
+
}
|
|
1395
|
+
if (parameter.type == "boolean" || parameter.schema != null && parameter.schema.type == "boolean") {
|
|
1396
|
+
parameter.uiType = "text";
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const parameterFormData = apiOperator.rawApiInfo.parameters.filter((val) => val.in == "formData");
|
|
1401
|
+
if (parameterFormData && parameterFormData.length > 0) {
|
|
1402
|
+
apiOperator["parameterHasFormDataVer2"] = true;
|
|
1403
|
+
}
|
|
1404
|
+
for (const param of apiOperator.rawApiInfo.parameters) {
|
|
1405
|
+
const paramSchema = param.schema;
|
|
1406
|
+
if (paramSchema && paramSchema["$ref"]) {
|
|
1407
|
+
const bodyName = paramSchema["$ref"].substring(paramSchema["$ref"].lastIndexOf("/") + 1);
|
|
1408
|
+
if (openapiSpec && openapiSpec["components"] != null && openapiSpec["components"]["schemas"] != null) {
|
|
1409
|
+
const def = openapiSpec["components"] != null ? openapiSpec["components"]["schemas"][bodyName] : { type: "" };
|
|
1410
|
+
param.type = parseElementType(def);
|
|
1411
|
+
param.uiType = param.type == "integer" || param.type == "number" ? "number" : "text";
|
|
1412
|
+
param.value = parseElement(def);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
967
1416
|
}
|
|
968
1417
|
}
|
|
969
|
-
if (
|
|
970
|
-
const
|
|
971
|
-
|
|
1418
|
+
if (apiOperator.rawApiInfo.requestBody) {
|
|
1419
|
+
const content = apiOperator.rawApiInfo.requestBody.content;
|
|
1420
|
+
apiOperator["requestBody"] = {
|
|
1421
|
+
content: {}
|
|
1422
|
+
};
|
|
972
1423
|
for (const key in content) {
|
|
973
1424
|
if (Object.prototype.hasOwnProperty.call(content, key)) {
|
|
974
1425
|
const element = content[key];
|
|
1426
|
+
apiOperator["consumes"]?.push(key);
|
|
975
1427
|
if (element) {
|
|
976
|
-
|
|
977
|
-
|
|
1428
|
+
if (element.schema == void 0) {
|
|
1429
|
+
console.log("pathKey is:", path);
|
|
1430
|
+
console.log("key is:", key);
|
|
1431
|
+
console.log("content is:", content);
|
|
1432
|
+
console.log("Unsupported requestBody schema format:", element);
|
|
1433
|
+
continue;
|
|
1434
|
+
}
|
|
1435
|
+
if (key != "application/x-www-form-urlencoded" && key != "multipart/form-data") {
|
|
1436
|
+
let requestBody = parseParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1437
|
+
apiOperator["requestBody"]["content"][key] = JSON.stringify(requestBody, null, 4);
|
|
1438
|
+
} else {
|
|
1439
|
+
let requestFormDataBody = parseFormDataParaModel(element, openapiSpec["components"]["schemas"]);
|
|
1440
|
+
apiOperator["requestBody"]["content"][key] = requestFormDataBody;
|
|
1441
|
+
}
|
|
1442
|
+
apiOperator["parameterHasBody"] = true;
|
|
978
1443
|
}
|
|
979
1444
|
}
|
|
980
1445
|
}
|
|
1446
|
+
if (apiOperator.consumes) {
|
|
1447
|
+
if (apiOperator.consumes.length > 0) {
|
|
1448
|
+
apiOperator["currentConsume"] = apiOperator["consumes"][0];
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
981
1451
|
}
|
|
982
|
-
apiOperator.rawApiInfo = operation;
|
|
983
1452
|
apiOperatorList.push(apiOperator);
|
|
984
1453
|
}
|
|
985
1454
|
});
|