You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.6 KiB
173 lines
4.6 KiB
import * as utils from '../utils'
|
|
import {normalizeUploadConfig} from '../utils'
|
|
import {Config, InternalConfig, UploadInfo} from '../upload'
|
|
|
|
interface UpHosts {
|
|
data: {
|
|
up: {
|
|
acc: {
|
|
main: string[]
|
|
backup: string[]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function getUpHosts(accessKey: string, bucketName: string, protocol: InternalConfig['upprotocol']): Promise<UpHosts> {
|
|
const params = new URLSearchParams({ak: accessKey, bucket: bucketName})
|
|
const url = `${protocol}://api.qiniu.com/v2/query?${params}`
|
|
return utils.request(url, {method: 'GET'})
|
|
}
|
|
|
|
/**
|
|
* @param bucket 空间名
|
|
* @param key 目标文件名
|
|
* @param uploadInfo 上传信息
|
|
*/
|
|
function getBaseUrl(bucket: string, key: string | null | undefined, uploadInfo: UploadInfo) {
|
|
const {url, id} = uploadInfo
|
|
return `${url}/buckets/${bucket}/objects/${key != null ? utils.urlSafeBase64Encode(key) : '~'}/uploads/${id}`
|
|
}
|
|
|
|
export interface InitPartsData {
|
|
/** 该文件的上传 id, 后续该文件其他各个块的上传,已上传块的废弃,已上传块的合成文件,都需要该 id */
|
|
uploadId: string
|
|
/** uploadId 的过期时间 */
|
|
expireAt: number
|
|
}
|
|
|
|
/**
|
|
* @param token 上传鉴权凭证
|
|
* @param bucket 上传空间
|
|
* @param key 目标文件名
|
|
* @param uploadUrl 上传地址
|
|
*/
|
|
export function initUploadParts(
|
|
token: string,
|
|
bucket: string,
|
|
key: string | null | undefined,
|
|
uploadUrl: string
|
|
): utils.Response<InitPartsData> {
|
|
const url = `${uploadUrl}/buckets/${bucket}/objects/${key != null ? utils.urlSafeBase64Encode(key) : '~'}/uploads`
|
|
return utils.request<InitPartsData>(
|
|
url,
|
|
{
|
|
method: 'POST',
|
|
headers: utils.getAuthHeaders(token)
|
|
}
|
|
)
|
|
}
|
|
|
|
export interface UploadChunkData {
|
|
etag: string
|
|
md5: string
|
|
}
|
|
|
|
/**
|
|
* @param token 上传鉴权凭证
|
|
* @param index 当前 chunk 的索引
|
|
* @param uploadInfo 上传信息
|
|
* @param options 请求参数
|
|
*/
|
|
export function uploadChunk(
|
|
token: string,
|
|
key: string | null | undefined,
|
|
index: number,
|
|
uploadInfo: UploadInfo,
|
|
options: Partial<utils.RequestOptions & { md5: string }>
|
|
): utils.Response<UploadChunkData> {
|
|
const bucket = utils.getPutPolicy(token).bucketName
|
|
const url = getBaseUrl(bucket, key, uploadInfo) + `/${index}`
|
|
const headers = utils.getHeadersForChunkUpload(token)
|
|
if (options.md5) headers['Content-MD5'] = options.md5
|
|
|
|
return utils.request<UploadChunkData>(url, {
|
|
...options,
|
|
method: 'PUT',
|
|
headers
|
|
})
|
|
}
|
|
|
|
export type UploadCompleteData = any
|
|
|
|
/**
|
|
* @param token 上传鉴权凭证
|
|
* @param key 目标文件名
|
|
* @param uploadInfo 上传信息
|
|
* @param options 请求参数
|
|
*/
|
|
export function uploadComplete(
|
|
token: string,
|
|
key: string | null | undefined,
|
|
uploadInfo: UploadInfo,
|
|
options: Partial<utils.RequestOptions>
|
|
): utils.Response<UploadCompleteData> {
|
|
const bucket = utils.getPutPolicy(token).bucketName
|
|
const url = getBaseUrl(bucket, key, uploadInfo)
|
|
return utils.request<UploadCompleteData>(url, {
|
|
...options,
|
|
method: 'POST',
|
|
headers: utils.getHeadersForMkFile(token)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @param token 上传鉴权凭证
|
|
* @param key 目标文件名
|
|
* @param uploadInfo 上传信息
|
|
*/
|
|
export function deleteUploadedChunks(
|
|
token: string,
|
|
key: string | null | undefined,
|
|
uploadinfo: UploadInfo
|
|
): utils.Response<void> {
|
|
const bucket = utils.getPutPolicy(token).bucketName
|
|
const url = getBaseUrl(bucket, key, uploadinfo)
|
|
return utils.request(
|
|
url,
|
|
{
|
|
method: 'DELETE',
|
|
headers: utils.getAuthHeaders(token)
|
|
}
|
|
)
|
|
}
|
|
|
|
/**
|
|
* @param {string} url
|
|
* @param {FormData} data
|
|
* @param {Partial<utils.RequestOptions>} options
|
|
* @returns Promise
|
|
* @description 直传接口
|
|
*/
|
|
export function direct(
|
|
url: string,
|
|
data: FormData,
|
|
options: Partial<utils.RequestOptions>
|
|
): Promise<UploadCompleteData> {
|
|
return utils.request<UploadCompleteData>(url, {
|
|
method: 'POST',
|
|
body: data,
|
|
...options
|
|
})
|
|
}
|
|
|
|
export type UploadUrlConfig = Partial<Pick<Config, 'upprotocol' | 'uphost' | 'region' | 'useCdnDomain'>>
|
|
|
|
/**
|
|
* @param {UploadUrlConfig} config
|
|
* @param {string} token
|
|
* @returns Promise
|
|
* @description 获取上传 url
|
|
*/
|
|
export async function getUploadUrl(_config: UploadUrlConfig, token: string): Promise<string> {
|
|
const config = normalizeUploadConfig(_config)
|
|
const protocol = config.upprotocol
|
|
|
|
if (config.uphost.length > 0) {
|
|
return `${protocol}://${config.uphost[0]}`
|
|
}
|
|
const putPolicy = utils.getPutPolicy(token)
|
|
const res = await getUpHosts(putPolicy.assessKey, putPolicy.bucketName, protocol)
|
|
const hosts = res.data.up.acc.main
|
|
return `${protocol}://${hosts[0]}`
|
|
}
|
|
|