w-converhp 2.0.10 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -1
- package/dist/w-converhp-client.umd.js +2 -2
- package/dist/w-converhp-client.umd.js.map +1 -1
- package/dist/w-converhp-server.umd.js +2 -2
- package/dist/w-converhp-server.umd.js.map +1 -1
- package/docs/WConverhpClient.html +3 -3
- package/docs/WConverhpClient.mjs.html +177 -4
- package/docs/WConverhpServer.html +3 -3
- package/docs/WConverhpServer.mjs.html +258 -71
- package/docs/index.html +1 -1
- package/package.json +3 -3
- package/sclc.mjs +4 -2
- package/scld.mjs +54 -0
- package/src/WConverhpClient.mjs +176 -3
- package/src/WConverhpServer.mjs +257 -70
- package/src/mergeFiles.mjs +16 -105
- package/src/mergeFiles.wk.umd.js +1 -1
- package/srv.mjs +38 -0
- package/test/1mb.7z +0 -0
- package/test/downloadLargeFile.test.mjs +166 -0
- package/test/executeWithFile.test.mjs +1 -1
- package/test/uploadLargeFile.test.mjs +5 -5
- package/web.html +28 -1
|
@@ -66,6 +66,8 @@ import obj2u8arr from 'wsemi/src/obj2u8arr.mjs'
|
|
|
66
66
|
import u8arr2obj from 'wsemi/src/u8arr2obj.mjs'
|
|
67
67
|
import pmConvertResolve from 'wsemi/src/pmConvertResolve.mjs'
|
|
68
68
|
import now2strp from 'wsemi/src/now2strp.mjs'
|
|
69
|
+
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
70
|
+
import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
|
|
69
71
|
|
|
70
72
|
|
|
71
73
|
/**
|
|
@@ -177,6 +179,35 @@ import now2strp from 'wsemi/src/now2strp.mjs'
|
|
|
177
179
|
* }
|
|
178
180
|
* uploadLargeFile()
|
|
179
181
|
*
|
|
182
|
+
* function downloadLargeFile() {
|
|
183
|
+
* let core = async() => {
|
|
184
|
+
*
|
|
185
|
+
* await wo.download('id-for-file',
|
|
186
|
+
* function ({ prog, p, m }) {
|
|
187
|
+
* // console.log('client web: download: prog', prog, p, m)
|
|
188
|
+
* if (m === 'download') {
|
|
189
|
+
* console.log('client web: download: prog', prog)
|
|
190
|
+
* }
|
|
191
|
+
* },
|
|
192
|
+
* {
|
|
193
|
+
* fdDownload: './',
|
|
194
|
+
* })
|
|
195
|
+
* .then(function(res) {
|
|
196
|
+
* console.log('client web: download: then', res)
|
|
197
|
+
* ms.push({ 'download output': res })
|
|
198
|
+
* })
|
|
199
|
+
* .catch(function (err) {
|
|
200
|
+
* console.log('client web: download: catch', err)
|
|
201
|
+
* })
|
|
202
|
+
*
|
|
203
|
+
* console.log('ms', ms)
|
|
204
|
+
*
|
|
205
|
+
* }
|
|
206
|
+
* core()
|
|
207
|
+
* }
|
|
208
|
+
*
|
|
209
|
+
* downloadLargeFile()
|
|
210
|
+
*
|
|
180
211
|
*/
|
|
181
212
|
function WConverhpClient(opt) {
|
|
182
213
|
|
|
@@ -301,6 +332,9 @@ function WConverhpClient(opt) {
|
|
|
301
332
|
else if (type === 'slicemerge') {
|
|
302
333
|
urlUse = `${url}slcm`
|
|
303
334
|
}
|
|
335
|
+
else if (type === 'download') {
|
|
336
|
+
urlUse = `${url}dw`
|
|
337
|
+
}
|
|
304
338
|
else {
|
|
305
339
|
throw new Error(`invalid type[${type}]`)
|
|
306
340
|
}
|
|
@@ -375,6 +409,9 @@ function WConverhpClient(opt) {
|
|
|
375
409
|
let rt = 'blob'
|
|
376
410
|
if (env === 'nodejs') {
|
|
377
411
|
rt = 'arraybuffer' //nodejs下沒有blob, 只能設定'json', 'arraybuffer', 'document', 'json', 'text', 'stream'
|
|
412
|
+
if (type === 'download') {
|
|
413
|
+
rt = 'stream' //nodejs download模式採用stream接收
|
|
414
|
+
}
|
|
378
415
|
}
|
|
379
416
|
// console.log('rt', rt)
|
|
380
417
|
|
|
@@ -432,11 +469,132 @@ function WConverhpClient(opt) {
|
|
|
432
469
|
}
|
|
433
470
|
// console.log('s', s)
|
|
434
471
|
|
|
472
|
+
//getFilenameByHeader
|
|
473
|
+
let getFilenameByHeader = (contentDisposition) => {
|
|
474
|
+
let fn = 'unknow'
|
|
475
|
+
try {
|
|
476
|
+
let reg = /filename="(.+?)"/
|
|
477
|
+
let matches = reg.exec(contentDisposition)
|
|
478
|
+
fn = matches ? matches[1] : 'unknown'
|
|
479
|
+
}
|
|
480
|
+
catch (err) {}
|
|
481
|
+
return fn
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
//downloadStream
|
|
485
|
+
let downloadStream = async (res) => {
|
|
486
|
+
// console.log('res.headers', res.headers)
|
|
487
|
+
|
|
488
|
+
//pm
|
|
489
|
+
let pm = genPm()
|
|
490
|
+
|
|
491
|
+
//returnType
|
|
492
|
+
let returnType = get(res, `headers['return-type']`, '')
|
|
493
|
+
// console.log('returnType', returnType)
|
|
494
|
+
|
|
495
|
+
//returnMsg
|
|
496
|
+
let returnMsg = get(res, `headers['return-msg']`, '')
|
|
497
|
+
// console.log('returnMsg', returnMsg)
|
|
498
|
+
|
|
499
|
+
//check
|
|
500
|
+
if (returnType === 'error') {
|
|
501
|
+
pm.reject(returnMsg)
|
|
502
|
+
return pm
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
//contentDisposition
|
|
506
|
+
let contentDisposition = get(res, `headers['content-disposition']`, '')
|
|
507
|
+
// console.log('contentDisposition', contentDisposition)
|
|
508
|
+
|
|
509
|
+
//filename
|
|
510
|
+
let filename = getFilenameByHeader(contentDisposition)
|
|
511
|
+
// console.log('filename', filename)
|
|
512
|
+
|
|
513
|
+
//streamRecv
|
|
514
|
+
let streamRecv = get(res, 'data')
|
|
515
|
+
|
|
516
|
+
if (env === 'browser') {
|
|
517
|
+
|
|
518
|
+
//通過createObjectURL與a元素下載
|
|
519
|
+
try {
|
|
520
|
+
let url = URL.createObjectURL(streamRecv)
|
|
521
|
+
let a = document.createElement('a')
|
|
522
|
+
a.href = url
|
|
523
|
+
a.download = filename // 動態設置檔名
|
|
524
|
+
document.body.appendChild(a)
|
|
525
|
+
a.click()
|
|
526
|
+
a.remove()
|
|
527
|
+
URL.revokeObjectURL(url)
|
|
528
|
+
pm.resolve(filename)
|
|
529
|
+
}
|
|
530
|
+
catch (err) {
|
|
531
|
+
console.log(err)
|
|
532
|
+
pm.reject(err)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
|
|
538
|
+
try {
|
|
539
|
+
|
|
540
|
+
//path, fs
|
|
541
|
+
let path = await import('path')
|
|
542
|
+
let fs = await import('fs')
|
|
543
|
+
|
|
544
|
+
//fdDownload, 只有後端下載才使用fdDownload
|
|
545
|
+
let fdDownload = get(opt, 'fdDownload', '')
|
|
546
|
+
if (!fsIsFolder(fdDownload)) {
|
|
547
|
+
fsCreateFolder(fdDownload)
|
|
548
|
+
}
|
|
549
|
+
// console.log('fdDownload', fdDownload)
|
|
550
|
+
|
|
551
|
+
//fp
|
|
552
|
+
let fp = path.resolve(fdDownload, filename)
|
|
553
|
+
// console.log('fp', fp)
|
|
554
|
+
|
|
555
|
+
//streamWriter
|
|
556
|
+
let streamWriter = fs.createWriteStream(fp)
|
|
557
|
+
|
|
558
|
+
//pipe
|
|
559
|
+
streamRecv.pipe(streamWriter)
|
|
560
|
+
|
|
561
|
+
//finish
|
|
562
|
+
streamWriter.on('finish', () => {
|
|
563
|
+
pm.resolve(fp)
|
|
564
|
+
})
|
|
565
|
+
|
|
566
|
+
//error
|
|
567
|
+
streamWriter.on('error', (err) => {
|
|
568
|
+
pm.reject(err)
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
}
|
|
572
|
+
catch (err) {
|
|
573
|
+
pm.reject(err)
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return pm
|
|
579
|
+
}
|
|
580
|
+
|
|
435
581
|
//axios
|
|
436
582
|
axios(s)
|
|
437
583
|
.then(async (res) => {
|
|
438
584
|
// console.log('axios then', res)
|
|
439
585
|
|
|
586
|
+
//check download
|
|
587
|
+
if (type === 'download') {
|
|
588
|
+
await downloadStream(res)
|
|
589
|
+
.then((_res) => {
|
|
590
|
+
pm.resolve(_res)
|
|
591
|
+
})
|
|
592
|
+
.catch((_err) => {
|
|
593
|
+
pm.reject(_err)
|
|
594
|
+
})
|
|
595
|
+
return
|
|
596
|
+
}
|
|
597
|
+
|
|
440
598
|
//bb
|
|
441
599
|
let bb = get(res, 'data')
|
|
442
600
|
// console.log('bb', bb)
|
|
@@ -473,7 +631,7 @@ function WConverhpClient(opt) {
|
|
|
473
631
|
|
|
474
632
|
})
|
|
475
633
|
.catch(async (res) => {
|
|
476
|
-
//console.log('axios catch', res.toJSON())
|
|
634
|
+
// console.log('axios catch', res.toJSON())
|
|
477
635
|
//Network Error除可能是網路斷線之外, 可能被瀏覽器外掛封鎖阻擋, 亦可能因硬碟空間不足(<4g)無法下載被瀏覽器拒絕
|
|
478
636
|
|
|
479
637
|
//data
|
|
@@ -507,6 +665,7 @@ function WConverhpClient(opt) {
|
|
|
507
665
|
if (data === 'Network Error') {
|
|
508
666
|
data = `Network Error. Make sure your space of hard drive is large enough or blocking by browser plugins.`
|
|
509
667
|
}
|
|
668
|
+
// console.log('data', data)
|
|
510
669
|
|
|
511
670
|
pm.reject(data)
|
|
512
671
|
})
|
|
@@ -583,7 +742,7 @@ function WConverhpClient(opt) {
|
|
|
583
742
|
}
|
|
584
743
|
if (n === 0) {
|
|
585
744
|
try {
|
|
586
|
-
n = bb.length //for Uint8Array
|
|
745
|
+
n = bb.length //for Uint8Array //後端用fs讀有檔案大小上限, 除非改傳入檔名用stream讀, 否則無法支援超大檔
|
|
587
746
|
n = cint(n)
|
|
588
747
|
}
|
|
589
748
|
catch (err) {}
|
|
@@ -591,7 +750,7 @@ function WConverhpClient(opt) {
|
|
|
591
750
|
if (n === 0) {
|
|
592
751
|
// eeEmit('error', `can not get size of bb`)
|
|
593
752
|
// return Promise.reject(`can not get size of bb`)
|
|
594
|
-
n = 1
|
|
753
|
+
n = 1 //最小給1, 使能支援無大小檔案上傳
|
|
595
754
|
}
|
|
596
755
|
// console.log('n', n)
|
|
597
756
|
|
|
@@ -744,9 +903,23 @@ function WConverhpClient(opt) {
|
|
|
744
903
|
return sendDataSlice(tempId, bb, cbProgress)
|
|
745
904
|
}
|
|
746
905
|
|
|
906
|
+
//download
|
|
907
|
+
async function download(fileId, cbProgress, opt = {}) {
|
|
908
|
+
|
|
909
|
+
//msg
|
|
910
|
+
let msg = { fileId }
|
|
911
|
+
|
|
912
|
+
//send download
|
|
913
|
+
let resMg = await send('download', msg, { ...opt, dataType: 'json', cbProgress })
|
|
914
|
+
// console.log('resMg', resMg)
|
|
915
|
+
|
|
916
|
+
return resMg
|
|
917
|
+
}
|
|
918
|
+
|
|
747
919
|
//save
|
|
748
920
|
ee.execute = execute
|
|
749
921
|
ee.upload = upload
|
|
922
|
+
ee.download = download
|
|
750
923
|
|
|
751
924
|
return ee
|
|
752
925
|
}
|
|
@@ -767,7 +940,7 @@ export default WConverhpClient
|
|
|
767
940
|
<br class="clear">
|
|
768
941
|
|
|
769
942
|
<footer>
|
|
770
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on
|
|
943
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Tue Apr 08 2025 12:28:45 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
771
944
|
</footer>
|
|
772
945
|
|
|
773
946
|
<script>prettyPrint();</script>
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
|
|
81
81
|
<dt class="tag-source">Source:</dt>
|
|
82
82
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
83
|
-
<a href="WConverhpServer.mjs.html">WConverhpServer.mjs</a>, <a href="WConverhpServer.mjs.html#
|
|
83
|
+
<a href="WConverhpServer.mjs.html">WConverhpServer.mjs</a>, <a href="WConverhpServer.mjs.html#line158">line 158</a>
|
|
84
84
|
</li></ul></dd>
|
|
85
85
|
|
|
86
86
|
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
|
|
128
128
|
<h5 class="h5-examples">Example</h5>
|
|
129
129
|
|
|
130
|
-
<pre class="prettyprint"><code>import _ from 'lodash-es'
|
|
131
130
|
port: 8080,
|
|
132
131
|
apiName: 'api',
|
|
133
132
|
pathStaticFiles: '.', //要存取專案資料夾下web.html, 故不能給dist
|
|
134
133
|
verifyConn: () => {
|
|
135
134
|
return true
|
|
136
135
|
},
|
|
137
136
|
// console.log(`Server[port:${opt.port}]: execute`, func, input)
|
|
138
137
|
console.log(`Server[port:${opt.port}]: execute`, func)
|
|
139
138
|
try {
|
|
140
139
|
if (func === 'add') {
|
|
141
140
|
if (_.get(input, 'p.d.u8a', null)) {
|
|
142
141
|
console.log('input.p.d.u8a', input.p.d.u8a)
|
|
143
142
|
}
|
|
144
143
|
let r = {
|
|
145
144
|
_add: input.p.a + input.p.b,
|
|
146
145
|
_data: [11, 22.22, 'abc', { x: '21', y: 65.43, z: 'test中文' }],
|
|
147
146
|
_bin: {
|
|
148
147
|
name: 'zdata.b2',
|
|
149
148
|
u8a: new Uint8Array([66, 97, 115]),
|
|
150
149
|
// name: '100mb.7z',
|
|
151
150
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\100mb.7z')),
|
|
152
151
|
// name: '500mb.7z',
|
|
153
152
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\500mb.7z')),
|
|
154
153
|
// name: '1000mb.7z',
|
|
155
154
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\1000mb.7z')),
|
|
156
155
|
},
|
|
157
156
|
}
|
|
158
157
|
pm.resolve(r)
|
|
159
158
|
}
|
|
160
159
|
else {
|
|
161
160
|
console.log('invalid func')
|
|
162
161
|
pm.reject('invalid func')
|
|
163
162
|
}
|
|
164
163
|
}
|
|
165
164
|
catch (err) {
|
|
166
165
|
console.log('execute error', err)
|
|
167
166
|
pm.reject('execute error')
|
|
168
167
|
}
|
|
169
168
|
console.log(`Server[port:${opt.port}]: upload`, input)
|
|
170
169
|
try {
|
|
171
170
|
let output = input
|
|
172
171
|
pm.resolve(output)
|
|
173
172
|
}
|
|
174
173
|
catch (err) {
|
|
175
174
|
console.log('upload error', err)
|
|
176
175
|
pm.reject('upload error')
|
|
177
176
|
}
|
|
178
177
|
// console.log(`Server[port:${opt.port}]: handler`, data)
|
|
178
|
+
<pre class="prettyprint"><code>import _ from 'lodash-es'
|
|
179
179
|
port: 8080,
|
|
180
180
|
apiName: 'api',
|
|
181
181
|
pathStaticFiles: '.', //要存取專案資料夾下web.html, 故不能給dist
|
|
182
182
|
verifyConn: () => {
|
|
183
183
|
return true
|
|
184
184
|
},
|
|
185
185
|
// console.log(`Server[port:${opt.port}]: execute`, func, input)
|
|
186
186
|
console.log(`Server[port:${opt.port}]: execute`, func)
|
|
187
187
|
try {
|
|
188
188
|
if (func === 'add') {
|
|
189
189
|
if (_.get(input, 'p.d.u8a', null)) {
|
|
190
190
|
console.log('input.p.d.u8a', input.p.d.u8a)
|
|
191
191
|
}
|
|
192
192
|
let r = {
|
|
193
193
|
_add: input.p.a + input.p.b,
|
|
194
194
|
_data: [11, 22.22, 'abc', { x: '21', y: 65.43, z: 'test中文' }],
|
|
195
195
|
_bin: {
|
|
196
196
|
name: 'zdata.b2',
|
|
197
197
|
u8a: new Uint8Array([66, 97, 115]),
|
|
198
198
|
// name: '100mb.7z',
|
|
199
199
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\100mb.7z')),
|
|
200
200
|
// name: '500mb.7z',
|
|
201
201
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\500mb.7z')),
|
|
202
202
|
// name: '1000mb.7z',
|
|
203
203
|
// u8a: new Uint8Array(fs.readFileSync('D:\\開源-JS-006-2-w-converhp\\_temp\\1000mb.7z')),
|
|
204
204
|
},
|
|
205
205
|
}
|
|
206
206
|
pm.resolve(r)
|
|
207
207
|
}
|
|
208
208
|
else {
|
|
209
209
|
console.log('invalid func')
|
|
210
210
|
pm.reject('invalid func')
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
catch (err) {
|
|
214
214
|
console.log('execute error', err)
|
|
215
215
|
pm.reject('execute error')
|
|
216
216
|
}
|
|
217
217
|
console.log(`Server[port:${opt.port}]: upload`, input)
|
|
218
218
|
try {
|
|
219
219
|
let output = input
|
|
220
220
|
pm.resolve(output)
|
|
221
221
|
}
|
|
222
222
|
catch (err) {
|
|
223
223
|
console.log('upload error', err)
|
|
224
224
|
pm.reject('upload error')
|
|
225
225
|
}
|
|
226
226
|
console.log(`Server[port:${opt.port}]: download`, input)
|
|
227
227
|
try {
|
|
228
228
|
ms.push({ 'download': input })
|
|
229
229
|
//fp
|
|
230
230
|
let fp = `./test/1mb.7z`
|
|
231
231
|
//streamRead
|
|
232
232
|
let streamRead = fs.createReadStream(fp)
|
|
233
233
|
//fileName
|
|
234
234
|
let fileName = `1mb.7z`
|
|
235
235
|
//fileSize
|
|
236
236
|
let stats = fs.statSync(fp)
|
|
237
237
|
let fileSize = stats.size
|
|
238
238
|
//fileType
|
|
239
239
|
let fileType = 'application/x-7z-compressed'
|
|
240
240
|
//output
|
|
241
241
|
let output = {
|
|
242
242
|
streamRead,
|
|
243
243
|
fileName,
|
|
244
244
|
fileSize,
|
|
245
245
|
fileType,
|
|
246
246
|
}
|
|
247
247
|
pm.resolve(output)
|
|
248
248
|
}
|
|
249
249
|
catch (err) {
|
|
250
250
|
console.log('download error', err)
|
|
251
251
|
pm.reject('download error')
|
|
252
252
|
}
|
|
253
253
|
// console.log(`Server[port:${opt.port}]: handler`, data)
|
|
254
254
|
|
|
255
255
|
|
|
256
256
|
|
|
@@ -709,7 +709,7 @@
|
|
|
709
709
|
<br class="clear">
|
|
710
710
|
|
|
711
711
|
<footer>
|
|
712
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on
|
|
712
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Tue Apr 08 2025 12:28:45 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
713
713
|
</footer>
|
|
714
714
|
|
|
715
715
|
<script>prettyPrint();</script>
|