Skip to content

Commit 5ac0f10

Browse files
committed
feat(mwcp): FetchService.postFile()
1 parent 5131000 commit 5ac0f10

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

packages/midway-component-fetch/src/lib/fetch.service.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import assert from 'node:assert'
3+
import type { Blob as NodeBlob } from 'node:buffer'
4+
25
import {
36
type AsyncContextManager,
47
ApplicationContext,
@@ -91,6 +94,25 @@ export class FetchService {
9194
return this.fetch(opts)
9295
}
9396

97+
postFile<T extends ResponseData>(
98+
input: string,
99+
file: File | Blob | NodeBlob,
100+
options?: Omit<FetchOptions, 'url' | 'method' | 'body' | 'data' | 'contentType' | 'processData'>,
101+
): Promise<T> {
102+
103+
assert(file, 'file is empty, should be Buffer or Blob')
104+
105+
const opts = {
106+
...options,
107+
url: input,
108+
method: 'POST',
109+
data: file,
110+
processData: false,
111+
contentType: false,
112+
} as FetchOptions
113+
return this.fetch(opts)
114+
}
115+
94116
// #region protected
95117

96118
protected prepareTrace(options: FetchOptions): void {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Blob as NodeBlob } from 'node:buffer'
2+
import { readFile } from 'node:fs/promises'
3+
import { join } from 'node:path'
4+
5+
import { genCurrentDirname } from '@waiting/shared-core'
6+
7+
8+
const currDir = genCurrentDirname(import.meta.url)
9+
10+
const fileName = 'loading-1.gif'
11+
const fileType = 'image/gif'
12+
const imgPath = join(currDir, '../images', fileName)
13+
const buf = await readFile(imgPath)
14+
export const imgBlob = typeof Blob === 'undefined'
15+
? new NodeBlob([buf], { type: fileType })
16+
: new Blob([buf], { type: fileType })
17+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { UploadFileInfo } from '@midwayjs/busboy'
2+
3+
4+
export interface UploadRet {
5+
fields: Record<string, string>
6+
files: UploadFileInfo[]
7+
traceId: string
8+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import assert from 'node:assert'
2+
3+
import type { AssertsOptions } from '@mwcp/otel'
4+
import {
5+
assertsSpan,
6+
assertRootSpan,
7+
retrieveTraceInfoFromRemote,
8+
sortSpans,
9+
assertJaegerParentSpanArray,
10+
} from '@mwcp/otel'
11+
import { fileShortPath } from '@waiting/shared-core'
12+
13+
import { FetchService } from '##/index.js'
14+
import { apiBase, apiMethod } from '#@/api-test.js'
15+
import { testConfig } from '#@/root.config.js'
16+
17+
import { imgBlob } from './100.data.js'
18+
import type { UploadRet } from './100.types.js'
19+
20+
21+
describe(fileShortPath(import.meta.url), () => {
22+
23+
const path = `${apiBase.upload}/${apiMethod.hello}`
24+
25+
it('postFile()', async () => {
26+
const { app, host } = testConfig
27+
const fetchService = await app.getApplicationContext().getAsync(FetchService)
28+
29+
const url = `${host}${path.slice(1)}`
30+
const resp = await fetchService.postFile<UploadRet>(url, imgBlob)
31+
assert(resp)
32+
assert(resp.traceId)
33+
34+
const [info] = await retrieveTraceInfoFromRemote(resp.traceId, 2)
35+
assert(info)
36+
const traceId = info.traceID
37+
const { spans } = info
38+
const [rootSpan, span1] = sortSpans(spans)
39+
assert(rootSpan)
40+
assert(span1)
41+
42+
assertJaegerParentSpanArray([
43+
{ parentSpan: rootSpan, childSpan: span1 },
44+
])
45+
46+
assertRootSpan({
47+
path,
48+
span: rootSpan,
49+
traceId,
50+
operationName: `HTTP POST ${url.slice(7)}`,
51+
mergeDefaultLogs: false,
52+
mergeDefaultTags: false,
53+
tags: {
54+
'caller.class': 'FetchComponent',
55+
'caller.method': 'fetch2',
56+
'http.method': 'POST',
57+
// 'http.resp.Content-Length': '227',
58+
'http.resp.content-type': 'application/json; charset=utf-8',
59+
'http.url': url,
60+
'span.kind': 'client',
61+
},
62+
logs: [
63+
{ event: 'fetch.start', method: 'POST', url },
64+
{ event: 'prepare-request-data' },
65+
{ event: 'request-start' },
66+
{ event: 'request-finish' },
67+
{ event: 'handle-redirect-finish' },
68+
{ event: 'process-response-start' },
69+
{ event: 'process-response-finish' },
70+
{ event: 'fetch.finish', method: 'POST', url },
71+
],
72+
})
73+
74+
const opt1: AssertsOptions = {
75+
traceId,
76+
operationName: `HTTP POST ${path}`,
77+
tags: {
78+
'http.method': 'POST',
79+
'http.request.header.content_type': 'image/gif',
80+
'http.request.header.user_agent': 'undici',
81+
'http.route': path,
82+
'http.target': path,
83+
'span.kind': 'server',
84+
},
85+
}
86+
assertsSpan(span1, opt1)
87+
})
88+
89+
90+
})
91+
92+

0 commit comments

Comments
 (0)