@@ -10,31 +10,47 @@ const baseUrl = useQueryParamOrStorage({ name: 'url', storageName: 'api-tester:u
10
10
const method = useQueryParamOrStorage ({ name: ' method' , storageName: ' api-tester:m' , defaultValue: ' POST' });
11
11
const queryParams = useQueryParamOrStorage <KeyValuePair []>({ name: ' params' , storageName: ' api-tester:params' , defaultValue: [] });
12
12
const headers = useQueryParamOrStorage <KeyValuePair []>({ name: ' headers' , storageName: ' api-tester:headers' , defaultValue: [] });
13
+ const contentType = useQueryParamOrStorage ({ name: ' ct' , storageName: ' api-tester:ct' , defaultValue: ' application/json' });
13
14
const body = useQueryParamOrStorage ({ name: ' body' , storageName: ' api-tester:body' , defaultValue: ' ' });
15
+ const noCORS = ref (false );
14
16
const apiCallResult = ref ();
15
17
16
18
const inprogress = ref (false );
17
19
async function callAPI() {
18
20
const url = new URL (baseUrl .value );
19
21
for (const kv of queryParams .value ) {
22
+ if (! kv .key ) {
23
+ continue ;
24
+ }
20
25
url .searchParams .append (kv .key , kv .value || ' ' );
21
26
}
22
27
const queryHeaders = [] as [string , string ][];
23
28
for (const kv of headers .value ) {
29
+ if (! kv .key ) {
30
+ continue ;
31
+ }
24
32
queryHeaders .push ([kv .key , kv .value || ' ' ]);
25
33
}
34
+ queryHeaders .push ([' Content-Type' , contentType .value || ' ' ]);
26
35
27
36
try {
28
37
const response = await fetch (url , {
29
38
method: method .value ,
30
39
headers: queryHeaders ,
31
- body: body .value ,
40
+ body: (method .value === ' GET' || method .value === ' HEAD' ) ? null : body .value ,
41
+ mode: noCORS .value ? ' no-cors' : ' cors' ,
32
42
});
33
43
44
+ let responseText = await response .text ();
45
+ try {
46
+ responseText = JSON .stringify (JSON .parse (responseText ), null , 2 );
47
+ }
48
+ catch (_ ) {
49
+ }
34
50
apiCallResult .value = {
35
51
code: response .status ,
36
52
error: ' ' ,
37
- result: await response . text () ,
53
+ result: responseText ,
38
54
};
39
55
}
40
56
catch (err : any ) {
@@ -45,11 +61,18 @@ async function callAPI() {
45
61
};
46
62
}
47
63
}
64
+
65
+ function emptyKeyPair() {
66
+ return {
67
+ key: ' ' ,
68
+ value: ' ' ,
69
+ };
70
+ }
48
71
</script >
49
72
50
73
<template >
51
74
<div >
52
- <c-card title =" " >
75
+ <c-card title =" API Calling " >
53
76
<c-input-text
54
77
v-model:value =" baseUrl"
55
78
label =" Base API Url"
@@ -61,36 +84,44 @@ async function callAPI() {
61
84
v-model:value =" method"
62
85
label =" HTTP Method:"
63
86
:options =" ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']"
87
+ mb-2
64
88
/>
65
89
66
90
<c-card title =" Headers" mb-2 >
67
- <n-dynamic-input v-model:value =" headers" >
91
+ <n-dynamic-input v-model:value =" headers" :on-create = " emptyKeyPair " >
68
92
<template #create-button-default >
69
93
Add a new HTTP Header
70
94
</template >
71
95
<template #default =" { value } " >
72
- <div style = " display : flex ; align-items : center ; width : 100 % " >
73
- <n -input v-model:value =" value.key" type =" text" />
74
- <n -input v-model:value =" value.value" type =" text" />
96
+ <div v-if = " value " w-100 flex justify- center gap-2 >
97
+ <c -input-text v-model:value =" value.key" placeholder = " Header Name " type =" text" />
98
+ <c -input-text v-model:value =" value.value" placeholder = " Value " type =" text" />
75
99
</div >
76
100
</template >
77
101
</n-dynamic-input >
102
+ <c-select
103
+ v-model:value =" contentType"
104
+ label =" Content-Type:"
105
+ :options =" ['application/json', 'text/plain']"
106
+ mt-2
107
+ />
78
108
</c-card >
79
109
80
110
<c-card title =" Query Parameters" mb-2 >
81
- <n-dynamic-input v-model:value =" queryParams" >
111
+ <n-dynamic-input v-model:value =" queryParams" :on-create = " emptyKeyPair " >
82
112
<template #create-button-default >
83
- Add a new HTTP Header
113
+ Add a new Query Parameter
84
114
</template >
85
115
<template #default =" { value } " >
86
- <div style = " display : flex ; align-items : center ; width : 100 % " >
87
- <n -input v-model:value =" value.key" type =" text" />
88
- <n -input v-model:value =" value.value" type =" text" />
116
+ <div v-if = " value " w-100 flex justify- center gap-2 >
117
+ <c -input-text v-model:value =" value.key" placeholder = " Param Name " type =" text" />
118
+ <c -input-text v-model:value =" value.value" placeholder = " Value " type =" text" />
89
119
</div >
90
120
</template >
91
121
</n-dynamic-input >
92
122
</c-card >
93
123
<c-input-text
124
+ v-if =" method !== 'GET' && method !== 'HEAD'"
94
125
v-model:value =" body"
95
126
label =" Body"
96
127
placeholder =" HTTP Query body"
@@ -99,20 +130,26 @@ async function callAPI() {
99
130
mb-2
100
131
/>
101
132
102
- <c-button secondary @click =" callAPI" >
103
- Call API
104
- </c-button >
133
+ <n-checkbox v-model:checked =" noCORS" >
134
+ No CORS
135
+ </n-checkbox >
136
+
137
+ <div mt-5 flex justify-center >
138
+ <c-button secondary @click =" callAPI" >
139
+ Call API
140
+ </c-button >
141
+ </div >
105
142
</c-card >
106
143
<n-spin
107
144
v-if =" inprogress"
108
145
size =" small"
109
146
/>
110
- <c-alert v-if =" !inprogress && apiCallResult.code !== 200" type =" error" mt-12 title =" Error while calling API" >
147
+ <c-alert v-if =" !inprogress && apiCallResult && apiCallResult .code !== 200" type =" error" mt-12 title =" Error while calling API" >
111
148
<p ><strong >Status code = {{ apiCallResult.code }}</strong ></p >
112
- <TextareaCopyable :value =" apiCallResult.error" />
149
+ <TextareaCopyable :value =" apiCallResult.error" copy-placement = " none " />
113
150
</c-alert >
114
- <c-card v-if =" !inprogress && apiCallResult.code === 200" mt-12 title =" API Call result" >
115
- <TextareaCopyable :value =" apiCallResult.result" />
151
+ <c-card v-if =" !inprogress && apiCallResult && apiCallResult .code === 200" mt-12 title =" API Call result" >
152
+ <TextareaCopyable :value =" apiCallResult.result" word-wrap />
116
153
</c-card >
117
154
</div >
118
155
</template >
0 commit comments