js-uploader
Version:
A JavaScript library for file upload
468 lines (449 loc) โข 15.8 kB
text/typescript
import { Uploader } from './uploader'
import { AjaxResponse, EventType, FileChunk, Obj, OSSProvider, UploadFile, UploadTask } from './interface'
import $ = require('jquery')
import { UploaderOptions } from './index'
import { ajax } from 'rxjs/ajax'
import { Observable } from 'rxjs'
import { FileStore } from './uploader/modules'
import S3 = require('aws-sdk/clients/s3')
let s3Client: S3 = new S3({
apiVersion: '2006-03-01',
computeChecksums: false,
region: 'ap-southeast-1',
accessKeyId: 'AKIAXIHZT77HYYIWAYOC',
secretAccessKey: '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',
convertResponseTypes: false,
maxRetries: 3,
retryDelayOptions: { base: 1000 },
s3ForcePathStyle: false,
signatureVersion: 'v4',
logger: console,
})
const s3Client1: S3 = new S3({
// apiVersion: '2006-03-01',
computeChecksums: true,
region: 'cn-south-1',
endpoint: 'http://s3-cn-south-1.qiniucs.com',
accessKeyId: 'RiBF4yjXwDtBtMXAzj44Adwc0PDb3n_thaivKchC',
secretAccessKey: 'XIcu9yyCexnaKhfB0Dyy1P-xsn_hfFA7gVZ4IVyo',
convertResponseTypes: false,
maxRetries: 3,
retryDelayOptions: { base: 1000 },
s3ForcePathStyle: true,
// signatureVersion: 'v4',
logger: console,
})
function a() {
// s3Client.listParts(
// {
// Bucket: 'slimdoc-test',
// Key: 'test.txt',
// UploadId: '5fdf39ed86a1cb246a1b943f',
// },
// console.log,
// )
// s3Client.listMultipartUploads({ Bucket: 'slimdoc-test' }, console.log)
let Bucket = 'lllllliu'
s3Client.createMultipartUpload(
{
Bucket,
Key: 'test.txt',
},
(err, res) => {
console.log('๐ ~ file: test.ts ~ line 61 ~ a ~ res', res)
s3Client.uploadPart(
{
UploadId: res.UploadId!,
Bucket,
Key: 'test.txt',
PartNumber: 1,
Body: '1213141425',
},
(err, res1) => {
console.log('๐ ~ file: test.ts ~ line 86 ~ a ~ res', res1)
s3Client.listParts(
{
Bucket,
Key: 'test.txt',
UploadId: res.UploadId!,
},
(err, res2) => {
s3Client.completeMultipartUpload(
{
UploadId: res.UploadId!,
Bucket,
Key: 'test.txt',
MultipartUpload: { Parts: res2.Parts?.map(({ ETag, PartNumber }) => ({ ETag, PartNumber })) },
},
console.log,
)
},
)
},
)
},
)
}
// a()
console.log('aaaaaaaaaaaaaaaaaaaa', a)
console.log('๐ ~ file: test.ts ~ line 11 ~ s3Client', s3Client)
let tokenMap = {}
const uploader = Uploader.create({
ossOptions: {
enable: () => false,
provider: OSSProvider.Qiniu,
keyGenerator(file: UploadFile) {
console.log('objectKeyGenerator -> objectKeyGenerator', arguments)
return tokenMap[file.id].key
},
uptokenGenerator(file: UploadFile) {
console.log('uptokenGenerator -> uptokenGenerator', arguments)
let url = 'http://saas.test.work.zving.com/server/companys/f05dd7da36ba4e238f9c1f053c2e76e3/oss/client/uptoken'
let headers = {
CMPID: 'f05dd7da36ba4e238f9c1f053c2e76e3',
GUID: '787845727d8345289a9bdc97de6e8556',
TOKEN:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJlY20gY2xpZW50IiwiaXNzIjoienZpbmciLCJjbGFpbURlZmF1bHRLZXkiOiJ4aWFvNSIsImV4cCI6MTYxMjUyMDMyMCwiaWF0IjoxNjExOTE1NTIwLCJqdGkiOiI2YjIyMjI1ZTcwNzM0YmY2OTUyMDgyZTUxNGE0ZWJkYiJ9.Ylic1H0OxOvahHT_bNgBL8xoQ5NRSBmylQfQBYsCUkA',
}
url = `${url}?fileName=${file.name}&fileSize=${file.size}&relativePath=${file.relativePath}`
let ob$: Observable<{ key: string; token: string }> = ajax.getJSON(url, headers)
return ob$.toPromise().then((res) => {
console.log('uptokenGenerator -> res', res)
tokenMap[file.id] = res
return res.token
})
},
},
requestOptions: {
// url: (task: UploadTask, upfile: UploadFile, chunk: FileChunk) => {
// return new Promise((resolve, reject) => {
// console.log('๐ ~ requestOptions - url ', task, upfile, chunk)
// setTimeout(() => {
// resolve('http://ecm.test.work.zving.com/catalogs/4751/files/upload')
// }, 1000)
// })
// // console.log('๐ ~ requestOptions - url ', task, upfile, chunk)
// // return 'http://ecm.test.work.zving.com/catalogs/4751/files/upload'
// },
url: 'http://ecm.test.work.zving.com/catalogs/4751/files/upload',
// headers: (task: UploadTask, upfile: UploadFile, chunk: FileChunk) => {
// return new Promise((resolve, reject) => {
// console.log('๐ ~ requestOptions - headers ', task, upfile, chunk)
// setTimeout(() => {
// resolve({
// CMPID: 'f05dd7da36ba4e238f9c1f053c2e76e3',
// TOKEN:
// 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJlY20gY2xpZW50IiwiaXNzIjoienZpbmciLCJjbGFpbURlZmF1bHRLZXkiOiJsaXVsZWkwMSIsImV4cCI6MTYwODk2NjA4NiwiaWF0IjoxNjA4MzYxMjg2LCJqdGkiOiI3MzVmZjZmZGQxODk0YzAxOWU3MmEzNTI0NjQ4MTRiZCJ9.e1hCx-hT1Lg16otoR0vctHez12GlCSUHdpuBbP6nDYs',
// GUID: 'b1da407ce0a5408b847f4151d41783ff',
// })
// }, 1000)
// })
// },
headers: {
CMPID: 'f05dd7da36ba4e238f9c1f053c2e76e3',
TOKEN:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJlY20gY2xpZW50IiwiaXNzIjoienZpbmciLCJjbGFpbURlZmF1bHRLZXkiOiJsaXVsZWkwMSIsImV4cCI6MTYwODk2NjA4NiwiaWF0IjoxNjA4MzYxMjg2LCJqdGkiOiI3MzVmZjZmZGQxODk0YzAxOWU3MmEzNTI0NjQ4MTRiZCJ9.e1hCx-hT1Lg16otoR0vctHez12GlCSUHdpuBbP6nDYs',
GUID: 'b1da407ce0a5408b847f4151d41783ff',
},
body: (task: UploadTask, uploadfile: UploadFile, chunk: FileChunk, baseParams: Obj) => {
return new Promise((resolve, reject) => {
console.log('๐ ~ requestOptions - headers ', task, uploadfile, chunk, baseParams)
setTimeout(() => {
resolve(
Object.assign(baseParams, {
chunkNumber: baseParams.chunkIndex + 1,
identifier: uploadfile.id,
filename: uploadfile.name,
totalChunks: uploadfile.chunkIDList?.length,
}),
)
}, 1000)
})
// return Object.assign(baseParams, {
// chunkNumber: baseParams.chunkIndex + 1,
// identifier: uploadfile.id,
// filename: uploadfile.name,
// totalChunks: uploadfile.chunkIDList?.length,
// })
},
},
singleFileTask: true,
computeFileHash: true,
computeChunkHash: true,
autoUpload: false,
maxRetryTimes: 3,
retryInterval: 3000,
resumable: false,
chunked: true,
chunkSize: 4 * 1024 ** 2,
chunkConcurrency: 2,
taskConcurrency: 2,
skipFileWhenUploadError: false,
skipTaskWhenUploadError: false,
filePicker: [
{ $el: document.querySelector('#fileInput') as HTMLInputElement, directory: false, multiple: true },
{ $el: document.querySelector('#fileInput1') as HTMLInputElement, directory: true, multiple: true },
],
fileDragger: {
$el: document.body,
onDragenter: (e) => {
// console.log('๐ ~ onDragenter ~ e', e)
},
onDragleave: (e) => {
// console.log('๐ ~ onDragleave ~ e', e)
},
onDrop: (e) => {
console.log('๐ ~ onDrop ~ e', e)
},
},
fileFilter(name, file) {
console.log('๐ ~ fileFilter ', arguments)
return !/\.DS_Store/.test(name)
},
readFileFn(task: UploadTask, upfile: UploadFile, start?: number, end?: number) {
console.log('๐ ~ readFileFn', arguments)
return new Promise((resolve, reject) => {
resolve(upfile.raw!.slice(start, end))
})
},
requestBodyProcessFn(task: UploadTask, upfile: UploadFile, chunk: FileChunk, params: Obj) {
return new Promise((resolve) => {
console.log('๐ ~ requestBodyProcessFn ', arguments)
setTimeout(() => {
const formData = new FormData()
Object.keys(params).forEach((k) => formData.append(k, params[k]))
resolve(formData)
}, 1000)
})
},
beforeFilesAdd(files: File[]) {
return new Promise((resolve) => {
console.log('๐ ~ beforeFilesAdd ', arguments)
setTimeout(() => {
resolve('')
})
})
},
filesAdded(files: UploadFile[]) {
return new Promise((resolve) => {
console.log('๐ ~ filesAdded ', arguments)
files.forEach((file) => {
file.extraInfo = {
now: Date.now(),
}
})
setTimeout(() => {
resolve('')
})
})
},
beforeTasksAdd(tasks: UploadTask[]) {
return new Promise((resolve) => {
console.log('๐ ~ beforeTasksAdd ', arguments)
tasks.forEach((task) => {
task.extraInfo = {
now: Date.now(),
}
})
setTimeout(() => {
resolve('')
})
})
},
beforeTaskStart(task: UploadTask) {
return new Promise((resolve) => {
console.log('๐ ~ beforeTaskStart ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
beforeFileUploadStart(task: UploadTask, file: UploadFile) {
return new Promise((resolve) => {
console.log('๐ ~ beforeFileUploadStart ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
beforeFileHashCompute(task: UploadTask, file: UploadFile) {
return new Promise((resolve) => {
console.log('๐ ~ beforeFileHashCompute ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
fileHashComputed(task: UploadTask, file: UploadFile, hash: string) {
return new Promise((resolve) => {
console.log('๐ ~ fileHashComputed ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
beforeFileRead(task: UploadTask, file: UploadFile, chunk: FileChunk) {
return new Promise((resolve) => {
console.log('๐ ~ beforeFileRead ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
fileReaded(task: UploadTask, file: UploadFile, chunk: FileChunk, data: Blob) {
return new Promise((resolve) => {
console.log('๐ ~ fileReaded ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
beforeUploadRequestSend(task: UploadTask, file: UploadFile, chunk: FileChunk, requestParams: Obj) {
return new Promise((resolve) => {
console.log('๐ ~ beforeUploadRequestSend ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
beforeUploadResponseProcess(task: UploadTask, file: UploadFile, chunk: FileChunk, response: AjaxResponse) {
return new Promise((resolve) => {
console.log('๐ ~ beforeUploadResponseProcess ', arguments)
setTimeout(() => {
resolve('')
}, 1000)
})
},
})
const taskMap = {}
const appendHtml = (task: UploadTask) => {
taskMap[task.id] = task
let html = `
<div id="${task.id}" style="margin:10px;padding:10px;border:1px solid;width;100%">
<div style="width:100%;display:flex;text-align:center">
<div style="width:30%;text-align:left">${task.name}</div>
<div style="width:5%;text-align:left">${task.type}</div>
<div style="width:10%;text-align:left">${task.fileSize}</div>
<div style="width:10%" class="task-progress">${task.progress}</div>
<div style="width:10%" class="task-status">${task.status}</div>
<div style="width:30%">
<button class="uploadBtn" taskID="${task.id}">upload</button>
<button class="pauseBtn" taskID="${task.id}">pause</button>
<button class="resumeBtn" taskID="${task.id}">resume</button>
<button class="retryBtn" taskID="${task.id}">retry</button>
<button class="cancelBtn" taskID="${task.id}">cancel</button>
</div>
</div>
</div>
`
requestAnimationFrame((_) => {
$('#task-container').append(html)
setTimeout(() => {
$(`#${task.id} .uploadBtn`).on('click', (e: JQuery.ClickEvent) => {
console.log('๐ ~ file: test.ts ~ line 175 ~ e', e)
console.log('๐ ~ file: test.ts ~ line 175 ~ e', e)
let taskID = $(e.target).attr('taskID') as string
let task = taskMap[taskID]
uploader.upload(task)
})
$(`#${task.id} .pauseBtn`).on('click', (e: JQuery.ClickEvent) => {
let taskID = $(e.target).attr('taskID') as string
let task = taskMap[taskID]
uploader.pause(task)
})
$(`#${task.id} .resumeBtn`).on('click', (e: JQuery.ClickEvent) => {
let taskID = $(e.target).attr('taskID') as string
let task = taskMap[taskID]
uploader.resume(task)
})
$(`#${task.id} .retryBtn`).on('click', (e: JQuery.ClickEvent) => {
let taskID = $(e.target).attr('taskID') as string
let task = taskMap[taskID]
uploader.retry(task)
})
$(`#${task.id} .cancelBtn`).on('click', (e: JQuery.ClickEvent) => {
let taskID = $(e.target).attr('taskID') as string
let task = taskMap[taskID]
uploader.cancel(task)
})
})
})
}
uploader.on('task-created', (task: UploadTask) => {
console.log(`ๅ็งฐ๏ผ${task.name}`, `ๆไปถๅคงๅฐ๏ผ${task.fileSize}`, `็ถๆ๏ผ${task.status}`)
})
uploader.on('task-progress', (task: UploadTask, file: UploadFile, progress: number) => {
console.log(`ๅฝๅไธไผ ไปปๅก๏ผ${task.name}`)
console.log(`ๅฝๅไธไผ ๆไปถ๏ผ${file.name}`)
console.log(`ไปปๅก่ฟๅบฆ๏ผ${progress}`)
})
uploader.on('task-error', (task: UploadTask, err: Error) => {
console.log(`ไปปๅกๅบ้๏ผ${task.name}`)
console.error(err)
})
uploader.on('task-complete', (task: UploadTask) => {
console.log(`ไปปๅกๅฎๆ๏ผ${task.name}`)
})
uploader.on(EventType.TaskCreated, appendHtml)
uploader.on(EventType.TaskRestore, appendHtml)
uploader.on(EventType.TaskUploadStart, (task: UploadTask) => {
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.TaskWaiting, (task: UploadTask) => {
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.TaskProgress, (task: UploadTask, file: UploadFile, progress: number) => {
// console.log('===TaskProgress', progress)
$(`#${task.id} .task-progress`).html(String(task.progress))
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.TaskComplete, (task: UploadTask) => {
// console.log('===TaskComplete', task)
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.TaskPause, (task: UploadTask) => {
// console.log('===TaskPaused', task)
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.TaskCancel, (task: UploadTask) => {
// console.log('===TaskCanceled', task)
$(`#${task.id}`).remove()
})
uploader.on(EventType.TaskError, (task: UploadTask) => {
$(`#${task.id} .task-status`).html(task.status)
})
uploader.on(EventType.Complete, () => {
// console.warn('Complete--------------------------------------------------------------------')
// uploader.clear()
})
uploader.on(EventType.FileComplete, (...args) => {
// console.log('===FileComplete', ...args)
})
setTimeout(() => {
$('#uploadBtn')?.on('click', () => {
console.log('begin upload')
uploader.upload()
})
$('#pauseBtn')?.on('click', () => {
console.log('pause upload')
uploader.pause()
})
$('#resumeBtn')?.on('click', () => {
console.log('resume upload')
uploader.resume()
})
$('#retryBtn')?.on('click', () => {
console.log('retry upload')
uploader.retry()
})
$('#cancelBtn')?.on('click', () => {
console.log('cancel upload')
uploader.cancel()
})
})
Object.assign(window, { up: uploader, store: FileStore })
Object.values(EventType).forEach((evt) => {
uploader.on(evt, function () {
console.warn(evt, arguments)
})
})