w-converhp 2.0.8 → 2.0.11
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 +164 -6
- 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 +162 -4
- package/src/WConverhpServer.mjs +257 -70
- package/src/mergeFiles.mjs +16 -105
- package/src/mergeFiles.wk.umd.js +1 -1
- package/srv.mjs +39 -1
- 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
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
|
|
46
46
|
<section>
|
|
47
47
|
<article>
|
|
48
|
-
<pre class="prettyprint source linenums"><code>import
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
+
import fs from 'fs'
|
|
50
|
+
import axios from 'axios'
|
|
49
51
|
import get from 'lodash-es/get.js'
|
|
50
52
|
import isWindow from 'wsemi/src/isWindow.mjs'
|
|
51
53
|
import genPm from 'wsemi/src/genPm.mjs'
|
|
@@ -66,6 +68,8 @@ import obj2u8arr from 'wsemi/src/obj2u8arr.mjs'
|
|
|
66
68
|
import u8arr2obj from 'wsemi/src/u8arr2obj.mjs'
|
|
67
69
|
import pmConvertResolve from 'wsemi/src/pmConvertResolve.mjs'
|
|
68
70
|
import now2strp from 'wsemi/src/now2strp.mjs'
|
|
71
|
+
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
72
|
+
import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
|
|
69
73
|
|
|
70
74
|
|
|
71
75
|
/**
|
|
@@ -177,6 +181,35 @@ import now2strp from 'wsemi/src/now2strp.mjs'
|
|
|
177
181
|
* }
|
|
178
182
|
* uploadLargeFile()
|
|
179
183
|
*
|
|
184
|
+
* function downloadLargeFile() {
|
|
185
|
+
* let core = async() => {
|
|
186
|
+
*
|
|
187
|
+
* await wo.download('id-for-file',
|
|
188
|
+
* function ({ prog, p, m }) {
|
|
189
|
+
* // console.log('client web: download: prog', prog, p, m)
|
|
190
|
+
* if (m === 'download') {
|
|
191
|
+
* console.log('client web: download: prog', prog)
|
|
192
|
+
* }
|
|
193
|
+
* },
|
|
194
|
+
* {
|
|
195
|
+
* fdDownload: './',
|
|
196
|
+
* })
|
|
197
|
+
* .then(function(res) {
|
|
198
|
+
* console.log('client web: download: then', res)
|
|
199
|
+
* ms.push({ 'download output': res })
|
|
200
|
+
* })
|
|
201
|
+
* .catch(function (err) {
|
|
202
|
+
* console.log('client web: download: catch', err)
|
|
203
|
+
* })
|
|
204
|
+
*
|
|
205
|
+
* console.log('ms', ms)
|
|
206
|
+
*
|
|
207
|
+
* }
|
|
208
|
+
* core()
|
|
209
|
+
* }
|
|
210
|
+
*
|
|
211
|
+
* downloadLargeFile()
|
|
212
|
+
*
|
|
180
213
|
*/
|
|
181
214
|
function WConverhpClient(opt) {
|
|
182
215
|
|
|
@@ -301,6 +334,9 @@ function WConverhpClient(opt) {
|
|
|
301
334
|
else if (type === 'slicemerge') {
|
|
302
335
|
urlUse = `${url}slcm`
|
|
303
336
|
}
|
|
337
|
+
else if (type === 'download') {
|
|
338
|
+
urlUse = `${url}dw`
|
|
339
|
+
}
|
|
304
340
|
else {
|
|
305
341
|
throw new Error(`invalid type[${type}]`)
|
|
306
342
|
}
|
|
@@ -375,6 +411,9 @@ function WConverhpClient(opt) {
|
|
|
375
411
|
let rt = 'blob'
|
|
376
412
|
if (env === 'nodejs') {
|
|
377
413
|
rt = 'arraybuffer' //nodejs下沒有blob, 只能設定'json', 'arraybuffer', 'document', 'json', 'text', 'stream'
|
|
414
|
+
if (type === 'download') {
|
|
415
|
+
rt = 'stream' //nodejs download模式採用stream接收
|
|
416
|
+
}
|
|
378
417
|
}
|
|
379
418
|
// console.log('rt', rt)
|
|
380
419
|
|
|
@@ -432,11 +471,115 @@ function WConverhpClient(opt) {
|
|
|
432
471
|
}
|
|
433
472
|
// console.log('s', s)
|
|
434
473
|
|
|
474
|
+
//getFilenameByHeader
|
|
475
|
+
let getFilenameByHeader = (contentDisposition) => {
|
|
476
|
+
let fn = 'unknow'
|
|
477
|
+
try {
|
|
478
|
+
let reg = /filename="(.+?)"/
|
|
479
|
+
let matches = reg.exec(contentDisposition)
|
|
480
|
+
fn = matches ? matches[1] : 'unknown'
|
|
481
|
+
}
|
|
482
|
+
catch (err) {}
|
|
483
|
+
return fn
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
//downloadStream
|
|
487
|
+
let downloadStream = (res) => {
|
|
488
|
+
// console.log('res.headers', res.headers)
|
|
489
|
+
|
|
490
|
+
//pm
|
|
491
|
+
let pm = genPm()
|
|
492
|
+
|
|
493
|
+
//returnType
|
|
494
|
+
let returnType = get(res, `headers['return-type']`, '')
|
|
495
|
+
// console.log('returnType', returnType)
|
|
496
|
+
|
|
497
|
+
//returnMsg
|
|
498
|
+
let returnMsg = get(res, `headers['return-msg']`, '')
|
|
499
|
+
// console.log('returnMsg', returnMsg)
|
|
500
|
+
|
|
501
|
+
//check
|
|
502
|
+
if (returnType === 'error') {
|
|
503
|
+
pm.reject(returnMsg)
|
|
504
|
+
return pm
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
//contentDisposition
|
|
508
|
+
let contentDisposition = get(res, `headers['content-disposition']`, '')
|
|
509
|
+
// console.log('contentDisposition', contentDisposition)
|
|
510
|
+
|
|
511
|
+
//filename
|
|
512
|
+
let filename = getFilenameByHeader(contentDisposition)
|
|
513
|
+
// console.log('filename', filename)
|
|
514
|
+
|
|
515
|
+
//streamRecv
|
|
516
|
+
let streamRecv = get(res, 'data')
|
|
517
|
+
|
|
518
|
+
if (env === 'browser') {
|
|
519
|
+
|
|
520
|
+
//通過createObjectURL與a元素下載
|
|
521
|
+
let url = URL.createObjectURL(streamRecv)
|
|
522
|
+
let a = document.createElement('a')
|
|
523
|
+
a.href = url
|
|
524
|
+
a.download = filename // 動態設置檔名
|
|
525
|
+
document.body.appendChild(a)
|
|
526
|
+
a.click()
|
|
527
|
+
a.remove()
|
|
528
|
+
URL.revokeObjectURL(url)
|
|
529
|
+
|
|
530
|
+
pm.resolve(filename)
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
|
|
534
|
+
//fdDownload, 只有後端下載才使用fdDownload
|
|
535
|
+
let fdDownload = get(opt, 'fdDownload', '')
|
|
536
|
+
if (!fsIsFolder(fdDownload)) {
|
|
537
|
+
fsCreateFolder(fdDownload)
|
|
538
|
+
}
|
|
539
|
+
// console.log('fdDownload', fdDownload)
|
|
540
|
+
|
|
541
|
+
//fp
|
|
542
|
+
let fp = path.resolve(fdDownload, filename)
|
|
543
|
+
// console.log('fp', fp)
|
|
544
|
+
|
|
545
|
+
//streamWriter
|
|
546
|
+
let streamWriter = fs.createWriteStream(fp)
|
|
547
|
+
|
|
548
|
+
//pipe
|
|
549
|
+
streamRecv.pipe(streamWriter)
|
|
550
|
+
|
|
551
|
+
//finish
|
|
552
|
+
streamWriter.on('finish', () => {
|
|
553
|
+
pm.resolve(fp)
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
//error
|
|
557
|
+
streamWriter.on('error', (err) => {
|
|
558
|
+
pm.reject(err)
|
|
559
|
+
})
|
|
560
|
+
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return pm
|
|
564
|
+
}
|
|
565
|
+
|
|
435
566
|
//axios
|
|
436
567
|
axios(s)
|
|
437
568
|
.then(async (res) => {
|
|
438
569
|
// console.log('axios then', res)
|
|
439
570
|
|
|
571
|
+
//check download
|
|
572
|
+
if (type === 'download') {
|
|
573
|
+
await downloadStream(res)
|
|
574
|
+
.then((_res) => {
|
|
575
|
+
pm.resolve(_res)
|
|
576
|
+
})
|
|
577
|
+
.catch((_err) => {
|
|
578
|
+
pm.reject(_err)
|
|
579
|
+
})
|
|
580
|
+
return
|
|
581
|
+
}
|
|
582
|
+
|
|
440
583
|
//bb
|
|
441
584
|
let bb = get(res, 'data')
|
|
442
585
|
// console.log('bb', bb)
|
|
@@ -473,7 +616,7 @@ function WConverhpClient(opt) {
|
|
|
473
616
|
|
|
474
617
|
})
|
|
475
618
|
.catch(async (res) => {
|
|
476
|
-
//console.log('axios catch', res.toJSON())
|
|
619
|
+
// console.log('axios catch', res.toJSON())
|
|
477
620
|
//Network Error除可能是網路斷線之外, 可能被瀏覽器外掛封鎖阻擋, 亦可能因硬碟空間不足(<4g)無法下載被瀏覽器拒絕
|
|
478
621
|
|
|
479
622
|
//data
|
|
@@ -507,6 +650,7 @@ function WConverhpClient(opt) {
|
|
|
507
650
|
if (data === 'Network Error') {
|
|
508
651
|
data = `Network Error. Make sure your space of hard drive is large enough or blocking by browser plugins.`
|
|
509
652
|
}
|
|
653
|
+
// console.log('data', data)
|
|
510
654
|
|
|
511
655
|
pm.reject(data)
|
|
512
656
|
})
|
|
@@ -583,7 +727,7 @@ function WConverhpClient(opt) {
|
|
|
583
727
|
}
|
|
584
728
|
if (n === 0) {
|
|
585
729
|
try {
|
|
586
|
-
n = bb.length //for Uint8Array
|
|
730
|
+
n = bb.length //for Uint8Array //後端用fs讀有檔案大小上限, 除非改傳入檔名用stream讀, 否則無法支援超大檔
|
|
587
731
|
n = cint(n)
|
|
588
732
|
}
|
|
589
733
|
catch (err) {}
|
|
@@ -591,9 +735,9 @@ function WConverhpClient(opt) {
|
|
|
591
735
|
if (n === 0) {
|
|
592
736
|
// eeEmit('error', `can not get size of bb`)
|
|
593
737
|
// return Promise.reject(`can not get size of bb`)
|
|
594
|
-
n = 1
|
|
738
|
+
n = 1 //最小給1, 使能支援無大小檔案上傳
|
|
595
739
|
}
|
|
596
|
-
console.log('n', n)
|
|
740
|
+
// console.log('n', n)
|
|
597
741
|
|
|
598
742
|
//chunkTotal
|
|
599
743
|
let chunkTotal = Math.ceil(n / sizeSlice)
|
|
@@ -744,9 +888,23 @@ function WConverhpClient(opt) {
|
|
|
744
888
|
return sendDataSlice(tempId, bb, cbProgress)
|
|
745
889
|
}
|
|
746
890
|
|
|
891
|
+
//download
|
|
892
|
+
async function download(fileId, cbProgress, opt = {}) {
|
|
893
|
+
|
|
894
|
+
//msg
|
|
895
|
+
let msg = { fileId }
|
|
896
|
+
|
|
897
|
+
//send download
|
|
898
|
+
let resMg = await send('download', msg, { ...opt, dataType: 'json', cbProgress })
|
|
899
|
+
// console.log('resMg', resMg)
|
|
900
|
+
|
|
901
|
+
return resMg
|
|
902
|
+
}
|
|
903
|
+
|
|
747
904
|
//save
|
|
748
905
|
ee.execute = execute
|
|
749
906
|
ee.upload = upload
|
|
907
|
+
ee.download = download
|
|
750
908
|
|
|
751
909
|
return ee
|
|
752
910
|
}
|
|
@@ -767,7 +925,7 @@ export default WConverhpClient
|
|
|
767
925
|
<br class="clear">
|
|
768
926
|
|
|
769
927
|
<footer>
|
|
770
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on
|
|
928
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Tue Apr 08 2025 09:12:35 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
771
929
|
</footer>
|
|
772
930
|
|
|
773
931
|
<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 09:12:35 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
713
713
|
</footer>
|
|
714
714
|
|
|
715
715
|
<script>prettyPrint();</script>
|