-
Notifications
You must be signed in to change notification settings - Fork 42
/
adapter.ts
110 lines (105 loc) · 3.42 KB
/
adapter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { EventBus } from 'vtils'
import { fileToBase64File, readBase64File } from './utils'
import { IBackgroundHttpRequestFileBody, IHttpRequestListenerPayload, IHttpResponseListenerPayload, YApiXHTTPRequestOptions } from './types'
import { YAPIX } from './consts'
let counter = 0
const bus = new EventBus<{
response: (payload: IHttpResponseListenerPayload) => any,
}>()
document.addEventListener(YAPIX.HTTP_RESPONSE_LISTENER_TYPE, e => {
const payload: IHttpResponseListenerPayload = JSON.parse(JSON.stringify((e as any).detail || {}))
bus.emit('response', payload)
})
interface CrossRequestPayload {
url: string,
method: string,
files: Record<string, string | undefined>,
headers: Record<string, string>,
data: any,
caseId: number,
taskId: number,
timeout: number,
error: (res: any, headers: any, data: any) => any,
success: (res: any, headers: any, data: any) => any,
}
// ==== 适配 YApi 官方实现 ====
(window as any).crossRequest = async function (payload: CrossRequestPayload) {
const contentType = payload.headers['Content-Type']
|| payload.headers['content-type']
|| payload.headers['Content-type']
const requestBodyType: YApiXHTTPRequestOptions['requestBodyType'] = (
payload.data == null
? undefined
: contentType === 'application/x-www-form-urlencoded'
? 'form'
: contentType === 'multipart/form-data'
? 'file'
: contentType === 'application/json'
? 'json'
: 'raw'
)
const requestBody: YApiXHTTPRequestOptions['requestBody'] = (
requestBodyType !== 'file'
? payload.data
: {
[YAPIX.FILE_BODY_KEY]: true,
...(payload.data || {}),
...Object.fromEntries(await Promise.all(
Object.entries(payload.files || {}).map(async ([key, value]) => {
return [
key,
value && await fileToBase64File(
document.querySelector<HTMLInputElement>(`#${value}`)!.files![0],
),
] as const
}),
)),
} as IBackgroundHttpRequestFileBody
)
const requestId = `${location.href}____${counter++}`
const off = bus.on('response', async ({ id, response }) => {
if (id === requestId) {
const YApiResponse = {
header: response.headers,
status: response.status,
statusText: response.statusText,
body: await readBase64File(
response.base64File,
'text',
(response.headers['content-type'] || '').match(/charset=(.*)\b/i)?.[1] || 'utf-8',
),
// NOTE: YApi-X 预览用
async getBodyAsDataUrl() {
return readBase64File(response.base64File, 'dataUrl')
},
}
const YApiData = {
req: payload,
res: YApiResponse,
runTime: new Date().getTime(),
}
if (response.ok) {
payload.success(YApiResponse.body, YApiResponse.header, YApiData)
}
else {
payload.error(YApiResponse.statusText, YApiResponse.header, YApiData)
}
off()
}
})
document.dispatchEvent(new CustomEvent(YAPIX.HTTP_REQUEST_LISTENER_TYPE, {
detail: {
id: requestId,
options: {
url: payload.url,
method: payload.method,
headers: {
...payload.headers,
'Content-Type': contentType,
},
requestBodyType: requestBodyType,
requestBody: requestBody,
},
} as IHttpRequestListenerPayload,
}))
}