w-converhp 2.0.1 → 2.0.2

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.
@@ -1,6 +1,4 @@
1
1
  import axios from 'axios'
2
- // import * as FormData from 'form-data/lib/form_data.js'
3
- // import FormData from 'form-data'
4
2
  import get from 'lodash-es/get.js'
5
3
  import isWindow from 'wsemi/src/isWindow.mjs'
6
4
  import genPm from 'wsemi/src/genPm.mjs'
@@ -12,6 +10,7 @@ import isp0int from 'wsemi/src/isp0int.mjs'
12
10
  import isestr from 'wsemi/src/isestr.mjs'
13
11
  import isobj from 'wsemi/src/isobj.mjs'
14
12
  import iseobj from 'wsemi/src/iseobj.mjs'
13
+ import ispm from 'wsemi/src/ispm.mjs'
15
14
  import cint from 'wsemi/src/cint.mjs'
16
15
  import strright from 'wsemi/src/strright.mjs'
17
16
  import evem from 'wsemi/src/evem.mjs'
@@ -29,9 +28,10 @@ import now2strp from 'wsemi/src/now2strp.mjs'
29
28
  * @param {Object} opt 輸入設定參數物件
30
29
  * @param {String} [opt.url='http://localhost:8080'] 輸入Hapi伺服器網址,預設為'http://localhost:8080'
31
30
  * @param {String} [opt.apiName='api'] 輸入API名稱字串,預設'api'
31
+ * @param {Function} [opt.getToken=()=>''] 輸入取得使用者token的回調函數,預設()=>''
32
32
  * @param {Integer} [opt.sizeSlice=1024*1024] 輸入切片上傳檔案之切片檔案大小整數,單位為Byte,預設為1024*1024
33
33
  * @param {Integer} [opt.retry=3] 輸入傳輸失敗重試次數整數,預設為3
34
- * @returns {Object} 回傳通訊物件,可使用函數execute、upload
34
+ * @returns {Object} 回傳事件物件,可使用函數execute、upload
35
35
  * @example
36
36
  *
37
37
  * import WConverhpClient from 'w-converhp/dist/w-converhp-client.umd.js'
@@ -153,6 +153,14 @@ function WConverhpClient(opt) {
153
153
  url = _url + '/' + apiName
154
154
  }
155
155
 
156
+ //getToken
157
+ let getToken = get(opt, 'getToken', null)
158
+ if (!isfun(getToken)) {
159
+ getToken = () => {
160
+ return ''
161
+ }
162
+ }
163
+
156
164
  //sizeSlice
157
165
  let sizeSlice = get(opt, 'sizeSlice')
158
166
  if (!ispint(sizeSlice)) {
@@ -173,7 +181,7 @@ function WConverhpClient(opt) {
173
181
  let ee = evem() //new events.EventEmitter()
174
182
 
175
183
  //eeEmit
176
- function eeEmit(name, ...args) {
184
+ let eeEmit = (name, ...args) => {
177
185
  setTimeout(() => {
178
186
  ee.emit(name, ...args)
179
187
  }, 1)
@@ -206,7 +214,7 @@ function WConverhpClient(opt) {
206
214
  }
207
215
 
208
216
  //send
209
- function send(type, pkg, opt = {}) {
217
+ async function send(type, pkg, opt = {}) {
210
218
 
211
219
  //headers
212
220
  let headers = get(opt, 'headers')
@@ -217,13 +225,16 @@ function WConverhpClient(opt) {
217
225
 
218
226
  //dataType
219
227
  let dataType = get(opt, 'dataType', '')
220
- if (dataType !== 'blob' && dataType !== 'obj' && dataType !== 'fmd' && dataType !== 'json') {
228
+ if (dataType !== 'blob' && dataType !== 'fmd' && dataType !== 'json') {
221
229
  dataType = 'blob'
222
230
  }
223
231
  // console.log('dataType', dataType)
224
232
 
225
233
  //cbProgress
226
234
  let cbProgress = get(opt, 'cbProgress')
235
+ if (!isfun(cbProgress)) {
236
+ cbProgress = () => {}
237
+ }
227
238
 
228
239
  //urlUse
229
240
  let urlUse = ''
@@ -239,7 +250,6 @@ function WConverhpClient(opt) {
239
250
  else {
240
251
  throw new Error(`invalid type[${type}]`)
241
252
  }
242
- // console.log('urlUse', urlUse)
243
253
 
244
254
  //pm
245
255
  let pm = genPm()
@@ -287,17 +297,24 @@ function WConverhpClient(opt) {
287
297
  }
288
298
  // console.log('ct', ct)
289
299
  }
300
+ else {
301
+ //browser會自動根據fmd的邊界boundary來設定
302
+ }
290
303
 
291
304
  //set dd
292
305
  dd = fmd
293
306
 
294
307
  }
295
308
  else if (dataType === 'json') {
309
+ //axios預設會將物件自動轉換為JSON, 此處指定Content-Type且強制轉, 避免可能問題
310
+
311
+ //set ct
312
+ ct = {
313
+ 'Content-Type': 'application/json',
314
+ }
315
+
296
316
  dd = JSON.stringify(pkg)
297
317
  }
298
- else if (dataType === 'obj') {
299
- dd = pkg
300
- }
301
318
  // console.log('dd', dd)
302
319
 
303
320
  //rt
@@ -307,12 +324,19 @@ function WConverhpClient(opt) {
307
324
  }
308
325
  // console.log('rt', rt)
309
326
 
327
+ //token
328
+ let token = getToken()
329
+ if (ispm(token)) {
330
+ token = await token
331
+ }
332
+
310
333
  //s
311
334
  let s = {
312
335
  method: 'POST',
313
336
  url: urlUse,
314
337
  data: dd,
315
338
  headers: {
339
+ Authorization: `Bearer ${token}`,
316
340
  ...ct,
317
341
  ...headers,
318
342
  },
@@ -332,9 +356,7 @@ function WConverhpClient(opt) {
332
356
  }
333
357
 
334
358
  //cbProgress
335
- if (isfun(cbProgress)) {
336
- cbProgress(Math.floor(r), loaded, 'upload')
337
- }
359
+ cbProgress(Math.floor(r), loaded, 'upload')
338
360
 
339
361
  },
340
362
  onDownloadProgress: function (ev) {
@@ -350,9 +372,7 @@ function WConverhpClient(opt) {
350
372
  }
351
373
 
352
374
  //cbProgress
353
- if (isfun(cbProgress)) {
354
- cbProgress(Math.floor(r), loaded, 'donwload')
355
- }
375
+ cbProgress(Math.floor(r), loaded, 'download')
356
376
 
357
377
  },
358
378
  }
@@ -388,7 +408,8 @@ function WConverhpClient(opt) {
388
408
  pm.resolve(data.success)
389
409
  }
390
410
  else if (haskey(data, 'error')) {
391
- pm.resolve(data.error)
411
+ eeEmit('error', data.error)
412
+ pm.reject(data.error)
392
413
  }
393
414
  else {
394
415
  // console.log('invalid data', data)
@@ -407,6 +428,10 @@ function WConverhpClient(opt) {
407
428
  //statusText, err
408
429
  let statusText = get(res, 'response.statusText') || get(res, 'message')
409
430
  let err = get(res, 'response.data') || get(res, 'stack')
431
+ // console.log(`get(res, 'response.statusText')`, get(res, 'response.statusText'))
432
+ // console.log(`get(res, 'message')`, get(res, 'message'))
433
+ // console.log(`get(res, 'response.data')`, get(res, 'response.data'))
434
+ // console.log(`get(res, 'stack')`, get(res, 'stack'))
410
435
 
411
436
  if (statusText) {
412
437
  // console.log('statusText', statusText)
@@ -479,7 +504,7 @@ function WConverhpClient(opt) {
479
504
  break
480
505
  }
481
506
  console.log(`retry n=${n}`)
482
- r = await fun(data, cbProgress)
507
+ r = await fun(type, data, cbProgress)
483
508
  }
484
509
 
485
510
  if (r.state === 'success') {
@@ -523,6 +548,29 @@ function WConverhpClient(opt) {
523
548
  let packageId = `${now2strp()}-${genID()}`
524
549
  // console.log('packageId', packageId)
525
550
 
551
+ //progCount, progWeightSlice
552
+ let progCount = 0
553
+ let progWeightSlice = 0.99 //上傳階段進度使用99%
554
+ // let progWeightMerge = 0.01 //合併階段進度使用1%
555
+
556
+ //cbProgressSlice
557
+ let cbProgressSlice = (perc, _psiz, dir) => {
558
+ if (dir === 'upload' && perc === 100) {
559
+ progCount++
560
+ let r = progCount / chunkTotal
561
+ let prog = r * progWeightSlice * 100
562
+ let psiz = r * n
563
+ cbProgress(prog, psiz, 'upload')
564
+ }
565
+ }
566
+
567
+ //cbProgressMerge
568
+ let cbProgressMerge = (perc, _psiz, dir) => {
569
+ if (dir === 'download' && perc === 100) {
570
+ cbProgress(100, n, 'upload')
571
+ }
572
+ }
573
+
526
574
  //upload slice
527
575
  for (let i = 0; i < chunkTotal; i++) {
528
576
 
@@ -544,19 +592,19 @@ function WConverhpClient(opt) {
544
592
 
545
593
  //send slice
546
594
  // console.log(`uploading chunk[${i + 1}/${chunkTotal}] of packageId[${packageId}]...`)
547
- await send('slice', chunk, { headers: hd, dataType: 'blob', cbProgress })
595
+ await send('slice', chunk, { headers: hd, dataType: 'blob', cbProgress: cbProgressSlice })
548
596
  // console.log(`upload chunk[${i + 1}/${chunkTotal}] of packageId[${packageId}] done`, res)
549
597
 
550
598
  }
551
599
 
552
600
  //send merge
553
- // console.log(`merging tempId[${tempId}]...`)
601
+ console.log(`merging tempId[${tempId}]...`)
554
602
  let msg = {
555
603
  'filename': tempId,
556
604
  'chunk-total': chunkTotal,
557
605
  'package-id': packageId,
558
606
  }
559
- let resMg = await send('slicemerge', msg, { dataType: 'obj', cbProgress })
607
+ let resMg = await send('slicemerge', msg, { dataType: 'json', cbProgress: cbProgressMerge })
560
608
  // console.log(`merge tempId[${tempId}] done`, resMg)
561
609
 
562
610
  return resMg
@@ -580,7 +628,14 @@ function WConverhpClient(opt) {
580
628
  .then((msg) => {
581
629
  // console.log('msg', msg)
582
630
 
583
- //check
631
+ //check, 若為字串為錯誤訊息
632
+ if (isestr(msg)) {
633
+ state = 'error'
634
+ res = msg
635
+ return
636
+ }
637
+
638
+ //check, 若為非物件為非預期錯誤
584
639
  if (!iseobj(msg)) {
585
640
  console.log('msg is not an effective object', msg)
586
641
  state = 'error'
@@ -588,7 +643,7 @@ function WConverhpClient(opt) {
588
643
  return
589
644
  }
590
645
 
591
- //check, 預期msg格式為{func,input,output}, 但input會刪除
646
+ //check, 若不存在output為非預期錯誤, msg格式為{func,input,output}但input會刪除
592
647
  if (!haskey(msg, 'output')) {
593
648
  console.log('invalid msg.output', msg)
594
649
  state = 'error'
@@ -604,13 +659,6 @@ function WConverhpClient(opt) {
604
659
  res = msg
605
660
  })
606
661
 
607
- //r
608
- let r = {
609
- state,
610
- msg: res,
611
- }
612
- // console.log('sendData r', r)
613
-
614
662
  //check
615
663
  if (state === '') {
616
664
  // console.log('invalid state', r)
@@ -621,11 +669,11 @@ function WConverhpClient(opt) {
621
669
  //check
622
670
  if (state === 'error') {
623
671
  // console.log('send data error', r)
624
- eeEmit('error', `send data error`)
625
- return Promise.reject('send data error')
672
+ // eeEmit('error', res) //一般錯誤會嘗試n次, 每次也都會emit, 故此處不再基於已知state='error'時再emit
673
+ return Promise.reject(res)
626
674
  }
627
675
 
628
- return r.msg
676
+ return res
629
677
  }
630
678
 
631
679
  //upload
@@ -38,7 +38,7 @@ import fsDeleteFile from 'wsemi/src/fsDeleteFile.mjs'
38
38
  * @param {Integer} [opt.delayForBasic=0] 輸入基本API用延遲響應時間,單位ms,預設0
39
39
  * @param {Integer} [opt.delayForSlice=100] 輸入切片上傳檔案API用延遲響應時間,單位ms,預設100
40
40
  * @param {Boolean} [opt.serverHapi=null] 輸入外部提供Hapi伺服器物件,預設null
41
- * @returns {Object} 回傳通訊物件,可監聽事件execute、upload、handler
41
+ * @returns {Object} 回傳事件物件,可監聽事件execute、upload、handler
42
42
  * @example
43
43
  *
44
44
  * import _ from 'lodash-es'
@@ -194,8 +194,8 @@ function WConverhpServer(opt = {}) {
194
194
 
195
195
  //create server
196
196
  server = Hapi.server({
197
- port,
198
197
  //host: 'localhost',
198
+ port,
199
199
  routes: {
200
200
  cors: {
201
201
  origin: corsOrigins, //Access-Control-Allow-Origin
@@ -210,7 +210,7 @@ function WConverhpServer(opt = {}) {
210
210
  let ee = evem() //new events.EventEmitter()
211
211
 
212
212
  //eeEmit
213
- function eeEmit(name, ...args) {
213
+ let eeEmit = (name, ...args) => {
214
214
  setTimeout(() => {
215
215
  ee.emit(name, ...args)
216
216
  }, 1)
@@ -309,7 +309,7 @@ function WConverhpServer(opt = {}) {
309
309
  maxBytes: 1024 * 1024 * 1024 * 1024, //預設為1mb, 調整至1tb, 也就是給予3次方
310
310
  maxParts: 1000 * 1000 * 1000, //預設為1000, 給予3次方
311
311
  timeout: false, //避免請求未完成時中斷
312
- output: 'stream',
312
+ output: 'stream', //前端用blob與application/octet-stream傳
313
313
  parse: false,
314
314
  },
315
315
  timeout: {
@@ -332,20 +332,31 @@ function WConverhpServer(opt = {}) {
332
332
  // console.log('query', query)
333
333
 
334
334
  //token
335
- let token = get(query, 'token', '')
335
+ // let token = get(query, 'token', '')
336
+ let token = get(headers, 'authorization', '')
337
+ token = isestr(token) ? token : ''
336
338
 
337
339
  //check
338
340
  if (true) {
339
341
 
340
342
  //funCheck
341
- let m = funCheck({ token, headers, query })
343
+ let m = funCheck({ apiType: 'main', token, headers, query })
342
344
  if (ispm(m)) {
343
345
  m = await m
344
346
  }
345
347
 
346
348
  //check
347
349
  if (m !== true) {
348
- return res.response({ error: 'permission denied' }).code(400)
350
+
351
+ //u8aOut
352
+ let out = {
353
+ error: 'permission denied',
354
+ }
355
+ let u8aOut = obj2u8arr(out)
356
+ // console.log('main u8aOut', u8aOut)
357
+
358
+ // console.log('main return permission denied')
359
+ return responseU8aStream(res, u8aOut)
349
360
  }
350
361
 
351
362
  }
@@ -456,7 +467,7 @@ function WConverhpServer(opt = {}) {
456
467
  maxBytes: 1024 * 1024 * 1024 * 1024, //預設為1mb, 調整至1tb, 也就是給予3次方
457
468
  maxParts: 1000 * 1000 * 1000, //預設為1000, 給予3次方
458
469
  timeout: false, //避免請求未完成時中斷
459
- output: 'stream',
470
+ output: 'stream', //前端用blob與application/octet-stream傳
460
471
  parse: false,
461
472
  },
462
473
  timeout: {
@@ -479,20 +490,31 @@ function WConverhpServer(opt = {}) {
479
490
  // console.log('query', query)
480
491
 
481
492
  //token
482
- let token = get(query, 'token', '')
493
+ // let token = get(query, 'token', '')
494
+ let token = get(headers, 'authorization', '')
495
+ token = isestr(token) ? token : ''
483
496
 
484
497
  //check
485
498
  if (true) {
486
499
 
487
500
  //funCheck
488
- let m = funCheck({ token, headers, query })
501
+ let m = funCheck({ apiType: 'slice', token, headers, query })
489
502
  if (ispm(m)) {
490
503
  m = await m
491
504
  }
492
505
 
493
506
  //check
494
507
  if (m !== true) {
495
- return res.response({ error: 'permission denied' }).code(400)
508
+
509
+ //u8aOut
510
+ let out = {
511
+ error: 'permission denied',
512
+ }
513
+ let u8aOut = obj2u8arr(out)
514
+ // console.log('slice u8aOut', u8aOut)
515
+
516
+ // console.log('slice return permission denied')
517
+ return responseU8aStream(res, u8aOut)
496
518
  }
497
519
 
498
520
  }
@@ -591,7 +613,8 @@ function WConverhpServer(opt = {}) {
591
613
  maxBytes: 1024 * 1024 * 1024 * 1024, //預設為1mb, 調整至1tb, 也就是給予3次方
592
614
  maxParts: 1000 * 1000 * 1000, //預設為1000, 給予3次方
593
615
  timeout: false, //避免請求未完成時中斷
594
- parse: true,
616
+ // output: 'stream',
617
+ parse: true, //前端送obj過來
595
618
  },
596
619
  timeout: {
597
620
  socket: false, //避免socket自動關閉
@@ -613,20 +636,31 @@ function WConverhpServer(opt = {}) {
613
636
  // console.log('query', query)
614
637
 
615
638
  //token
616
- let token = get(query, 'token', '')
639
+ // let token = get(query, 'token', '')
640
+ let token = get(headers, 'authorization', '')
641
+ token = isestr(token) ? token : ''
617
642
 
618
643
  //check
619
644
  if (true) {
620
645
 
621
646
  //funCheck
622
- let m = funCheck({ token, headers, query })
647
+ let m = funCheck({ apiType: 'merge', token, headers, query })
623
648
  if (ispm(m)) {
624
649
  m = await m
625
650
  }
626
651
 
627
652
  //check
628
653
  if (m !== true) {
629
- return res.response({ error: 'permission denied' }).code(400)
654
+
655
+ //u8aOut
656
+ let out = {
657
+ error: 'permission denied',
658
+ }
659
+ let u8aOut = obj2u8arr(out)
660
+ // console.log('mergeu8aOut', u8aOut)
661
+
662
+ // console.log('merge return permission denied')
663
+ return responseU8aStream(res, u8aOut)
630
664
  }
631
665
 
632
666
  }
@@ -684,7 +718,6 @@ function WConverhpServer(opt = {}) {
684
718
  //check
685
719
  if (!fsIsFile(pathFileChunk)) {
686
720
  // console.log(`pathFileChunk[${pathFileChunk}] is not a file`)
687
- // return res.response({ error: `Missing chunk ${i} of filename[${filename}]` }).code(400)
688
721
  throw new Error(`Missing chunk ${i} of filename[${filename}]`)
689
722
  }
690
723
 
package/srv.mjs CHANGED
@@ -6,7 +6,8 @@ let opt = {
6
6
  port: 8080,
7
7
  apiName: 'api',
8
8
  pathStaticFiles: '.', //要存取專案資料夾下web.html, 故不能給dist
9
- funCheck: () => {
9
+ funCheck: ({ apiType, token, headers, query }) => {
10
+ console.log('funCheck', apiType, token)
10
11
  return true
11
12
  },
12
13
  }
@@ -69,6 +70,9 @@ wo.on('upload', function(input, pm) {
69
70
  }
70
71
 
71
72
  })
73
+ wo.on('error', function(err) {
74
+ console.log(`Server[port:${opt.port}]: error`, err)
75
+ })
72
76
  wo.on('handler', function(data) {
73
77
  // console.log(`Server[port:${opt.port}]: handler`, data)
74
78
  })
@@ -11,7 +11,7 @@ fns = fns.filter((v) => {
11
11
  })
12
12
 
13
13
  rollupFiles({
14
- fns: fns,
14
+ fns,
15
15
  fdSrc,
16
16
  fdTar,
17
17
  nameDistType: 'kebabCase',