|
1 | | -import { HTTPError, Request, request } from 'koajax'; |
2 | | -import { DataObject, toggle } from 'mobx-restful'; |
| 1 | +import { SignedLink } from '@kaiyuanshe/openhackathon-service'; |
| 2 | +import { toggle } from 'mobx-restful'; |
3 | 3 | import { FileModel } from 'mobx-restful-table'; |
| 4 | +import { blobOf, uniqueID } from 'web-utility'; |
4 | 5 |
|
5 | 6 | import sessionStore from '../User/Session'; |
6 | | -import { ErrorBaseData, UploadUrl } from './index'; |
7 | 7 |
|
8 | | -export class AzureFileModel extends FileModel { |
9 | | - static async uploadBlob<T = void>( |
10 | | - fullPath: string, |
11 | | - method: Request['method'] = 'PUT', |
12 | | - body?: any, |
13 | | - headers: DataObject = {}, |
14 | | - ) { |
15 | | - headers['x-ms-blob-type'] = 'BlockBlob'; |
16 | | - |
17 | | - const { response } = request<T>({ |
18 | | - path: fullPath, |
19 | | - method, |
20 | | - body, |
21 | | - headers, |
22 | | - }); |
23 | | - const { headers: header, body: data } = await response; |
24 | | - |
25 | | - if (!data || !('traceId' in (data as DataObject))) return data!; |
26 | | - |
27 | | - const { status, title, detail } = data as unknown as ErrorBaseData; |
28 | | - |
29 | | - throw new HTTPError( |
30 | | - detail || title, |
31 | | - { method, path: fullPath, headers, body }, |
32 | | - { status, statusText: title, headers: header, body: data }, |
33 | | - ); |
34 | | - } |
| 8 | +export class S3FileModel extends FileModel { |
| 9 | + client = sessionStore.client; |
35 | 10 |
|
36 | 11 | @toggle('uploading') |
37 | | - async upload(file: File) { |
38 | | - const { type, name } = file; |
39 | | - |
40 | | - const { body } = await sessionStore.client.post<UploadUrl>( |
41 | | - `user/generateFileUrl`, |
42 | | - { filename: name }, |
| 12 | + async upload(file: string | Blob) { |
| 13 | + if (typeof file === 'string') { |
| 14 | + const name = file.split('/').pop()!; |
| 15 | + |
| 16 | + file = new File([await blobOf(file)], name); |
| 17 | + } |
| 18 | + const { body } = await this.client.post<SignedLink>( |
| 19 | + `file/signed-link/${file instanceof File ? file.name : uniqueID()}`, |
43 | 20 | ); |
44 | | - const parts = body!.uploadUrl.split('/'); |
45 | | - |
46 | | - const path = parts.slice(0, -1).join('/'), |
47 | | - [fileName, data] = parts.at(-1)!.split('?'); |
48 | | - |
49 | | - const URI_Put = `${path}/${encodeURIComponent(fileName)}?${data}`; |
| 21 | + await this.client.put(body!.putLink, file, { 'Content-Type': file.type }); |
50 | 22 |
|
51 | | - await AzureFileModel.uploadBlob(URI_Put, 'PUT', file, { |
52 | | - 'Content-Type': type, |
53 | | - }); |
54 | | - |
55 | | - const { origin, pathname } = new URL(body!.url); |
| 23 | + return super.upload(body!.getLink); |
| 24 | + } |
56 | 25 |
|
57 | | - const URI_Get = `${ |
58 | | - origin + pathname.split('/').slice(0, -1).join('/') |
59 | | - }/${encodeURIComponent(fileName)}`; |
| 26 | + @toggle('uploading') |
| 27 | + async delete(link: string) { |
| 28 | + await this.client.delete(`file/${link.replace(`${this.client.baseURI}/file/`, '')}`); |
60 | 29 |
|
61 | | - return super.upload(URI_Get); |
| 30 | + await super.delete(link); |
62 | 31 | } |
63 | 32 | } |
64 | 33 |
|
65 | | -export default new AzureFileModel(); |
| 34 | +export default new S3FileModel(); |
0 commit comments