w-converhp 2.0.1 → 2.0.3

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,11 @@ 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
+ * @param {String} [opt.tokenType='Bearer'] 輸入token類型字串,預設'Bearer'
32
33
  * @param {Integer} [opt.sizeSlice=1024*1024] 輸入切片上傳檔案之切片檔案大小整數,單位為Byte,預設為1024*1024
33
34
  * @param {Integer} [opt.retry=3] 輸入傳輸失敗重試次數整數,預設為3
34
- * @returns {Object} 回傳通訊物件,可使用函數execute、upload
35
+ * @returns {Object} 回傳事件物件,可使用函數execute、upload
35
36
  * @example
36
37
  *
37
38
  * import WConverhpClient from 'w-converhp/dist/w-converhp-client.umd.js'
@@ -153,6 +154,20 @@ function WConverhpClient(opt) {
153
154
  url = _url + '/' + apiName
154
155
  }
155
156
 
157
+ //getToken
158
+ let getToken = get(opt, 'getToken', null)
159
+ if (!isfun(getToken)) {
160
+ getToken = () => {
161
+ return ''
162
+ }
163
+ }
164
+
165
+ //tokenType
166
+ let tokenType = get(opt, 'tokenType')
167
+ if (!isestr(tokenType)) {
168
+ tokenType = 'Bearer'
169
+ }
170
+
156
171
  //sizeSlice
157
172
  let sizeSlice = get(opt, 'sizeSlice')
158
173
  if (!ispint(sizeSlice)) {
@@ -173,7 +188,7 @@ function WConverhpClient(opt) {
173
188
  let ee = evem() //new events.EventEmitter()
174
189
 
175
190
  //eeEmit
176
- function eeEmit(name, ...args) {
191
+ let eeEmit = (name, ...args) => {
177
192
  setTimeout(() => {
178
193
  ee.emit(name, ...args)
179
194
  }, 1)
@@ -206,7 +221,7 @@ function WConverhpClient(opt) {
206
221
  }
207
222
 
208
223
  //send
209
- function send(type, pkg, opt = {}) {
224
+ async function send(type, pkg, opt = {}) {
210
225
 
211
226
  //headers
212
227
  let headers = get(opt, 'headers')
@@ -217,13 +232,16 @@ function WConverhpClient(opt) {
217
232
 
218
233
  //dataType
219
234
  let dataType = get(opt, 'dataType', '')
220
- if (dataType !== 'blob' && dataType !== 'obj' && dataType !== 'fmd' && dataType !== 'json') {
235
+ if (dataType !== 'blob' && dataType !== 'fmd' && dataType !== 'json') {
221
236
  dataType = 'blob'
222
237
  }
223
238
  // console.log('dataType', dataType)
224
239
 
225
240
  //cbProgress
226
241
  let cbProgress = get(opt, 'cbProgress')
242
+ if (!isfun(cbProgress)) {
243
+ cbProgress = () => {}
244
+ }
227
245
 
228
246
  //urlUse
229
247
  let urlUse = ''
@@ -239,7 +257,6 @@ function WConverhpClient(opt) {
239
257
  else {
240
258
  throw new Error(`invalid type[${type}]`)
241
259
  }
242
- // console.log('urlUse', urlUse)
243
260
 
244
261
  //pm
245
262
  let pm = genPm()
@@ -287,17 +304,24 @@ function WConverhpClient(opt) {
287
304
  }
288
305
  // console.log('ct', ct)
289
306
  }
307
+ else {
308
+ //browser會自動根據fmd的邊界boundary來設定
309
+ }
290
310
 
291
311
  //set dd
292
312
  dd = fmd
293
313
 
294
314
  }
295
315
  else if (dataType === 'json') {
316
+ //axios預設會將物件自動轉換為JSON, 此處指定Content-Type且強制轉, 避免可能問題
317
+
318
+ //set ct
319
+ ct = {
320
+ 'Content-Type': 'application/json',
321
+ }
322
+
296
323
  dd = JSON.stringify(pkg)
297
324
  }
298
- else if (dataType === 'obj') {
299
- dd = pkg
300
- }
301
325
  // console.log('dd', dd)
302
326
 
303
327
  //rt
@@ -307,12 +331,19 @@ function WConverhpClient(opt) {
307
331
  }
308
332
  // console.log('rt', rt)
309
333
 
334
+ //token
335
+ let token = getToken()
336
+ if (ispm(token)) {
337
+ token = await token
338
+ }
339
+
310
340
  //s
311
341
  let s = {
312
342
  method: 'POST',
313
343
  url: urlUse,
314
344
  data: dd,
315
345
  headers: {
346
+ Authorization: `${tokenType} ${token}`,
316
347
  ...ct,
317
348
  ...headers,
318
349
  },
@@ -332,9 +363,7 @@ function WConverhpClient(opt) {
332
363
  }
333
364
 
334
365
  //cbProgress
335
- if (isfun(cbProgress)) {
336
- cbProgress(Math.floor(r), loaded, 'upload')
337
- }
366
+ cbProgress(Math.floor(r), loaded, 'upload')
338
367
 
339
368
  },
340
369
  onDownloadProgress: function (ev) {
@@ -350,9 +379,7 @@ function WConverhpClient(opt) {
350
379
  }
351
380
 
352
381
  //cbProgress
353
- if (isfun(cbProgress)) {
354
- cbProgress(Math.floor(r), loaded, 'donwload')
355
- }
382
+ cbProgress(Math.floor(r), loaded, 'download')
356
383
 
357
384
  },
358
385
  }
@@ -388,7 +415,8 @@ function WConverhpClient(opt) {
388
415
  pm.resolve(data.success)
389
416
  }
390
417
  else if (haskey(data, 'error')) {
391
- pm.resolve(data.error)
418
+ eeEmit('error', data.error)
419
+ pm.reject(data.error)
392
420
  }
393
421
  else {
394
422
  // console.log('invalid data', data)
@@ -407,6 +435,10 @@ function WConverhpClient(opt) {
407
435
  //statusText, err
408
436
  let statusText = get(res, 'response.statusText') || get(res, 'message')
409
437
  let err = get(res, 'response.data') || get(res, 'stack')
438
+ // console.log(`get(res, 'response.statusText')`, get(res, 'response.statusText'))
439
+ // console.log(`get(res, 'message')`, get(res, 'message'))
440
+ // console.log(`get(res, 'response.data')`, get(res, 'response.data'))
441
+ // console.log(`get(res, 'stack')`, get(res, 'stack'))
410
442
 
411
443
  if (statusText) {
412
444
  // console.log('statusText', statusText)
@@ -479,7 +511,7 @@ function WConverhpClient(opt) {
479
511
  break
480
512
  }
481
513
  console.log(`retry n=${n}`)
482
- r = await fun(data, cbProgress)
514
+ r = await fun(type, data, cbProgress)
483
515
  }
484
516
 
485
517
  if (r.state === 'success') {
@@ -523,6 +555,29 @@ function WConverhpClient(opt) {
523
555
  let packageId = `${now2strp()}-${genID()}`
524
556
  // console.log('packageId', packageId)
525
557
 
558
+ //progCount, progWeightSlice
559
+ let progCount = 0
560
+ let progWeightSlice = 0.99 //上傳階段進度使用99%
561
+ // let progWeightMerge = 0.01 //合併階段進度使用1%
562
+
563
+ //cbProgressSlice
564
+ let cbProgressSlice = (perc, _psiz, dir) => {
565
+ if (dir === 'upload' && perc === 100) {
566
+ progCount++
567
+ let r = progCount / chunkTotal
568
+ let prog = r * progWeightSlice * 100
569
+ let psiz = r * n
570
+ cbProgress(prog, psiz, 'upload')
571
+ }
572
+ }
573
+
574
+ //cbProgressMerge
575
+ let cbProgressMerge = (perc, _psiz, dir) => {
576
+ if (dir === 'download' && perc === 100) {
577
+ cbProgress(100, n, 'upload')
578
+ }
579
+ }
580
+
526
581
  //upload slice
527
582
  for (let i = 0; i < chunkTotal; i++) {
528
583
 
@@ -544,19 +599,19 @@ function WConverhpClient(opt) {
544
599
 
545
600
  //send slice
546
601
  // console.log(`uploading chunk[${i + 1}/${chunkTotal}] of packageId[${packageId}]...`)
547
- await send('slice', chunk, { headers: hd, dataType: 'blob', cbProgress })
602
+ await send('slice', chunk, { headers: hd, dataType: 'blob', cbProgress: cbProgressSlice })
548
603
  // console.log(`upload chunk[${i + 1}/${chunkTotal}] of packageId[${packageId}] done`, res)
549
604
 
550
605
  }
551
606
 
552
607
  //send merge
553
- // console.log(`merging tempId[${tempId}]...`)
608
+ console.log(`merging tempId[${tempId}]...`)
554
609
  let msg = {
555
610
  'filename': tempId,
556
611
  'chunk-total': chunkTotal,
557
612
  'package-id': packageId,
558
613
  }
559
- let resMg = await send('slicemerge', msg, { dataType: 'obj', cbProgress })
614
+ let resMg = await send('slicemerge', msg, { dataType: 'json', cbProgress: cbProgressMerge })
560
615
  // console.log(`merge tempId[${tempId}] done`, resMg)
561
616
 
562
617
  return resMg
@@ -580,7 +635,14 @@ function WConverhpClient(opt) {
580
635
  .then((msg) => {
581
636
  // console.log('msg', msg)
582
637
 
583
- //check
638
+ //check, 若為字串為錯誤訊息
639
+ if (isestr(msg)) {
640
+ state = 'error'
641
+ res = msg
642
+ return
643
+ }
644
+
645
+ //check, 若為非物件為非預期錯誤
584
646
  if (!iseobj(msg)) {
585
647
  console.log('msg is not an effective object', msg)
586
648
  state = 'error'
@@ -588,7 +650,7 @@ function WConverhpClient(opt) {
588
650
  return
589
651
  }
590
652
 
591
- //check, 預期msg格式為{func,input,output}, 但input會刪除
653
+ //check, 若不存在output為非預期錯誤, msg格式為{func,input,output}但input會刪除
592
654
  if (!haskey(msg, 'output')) {
593
655
  console.log('invalid msg.output', msg)
594
656
  state = 'error'
@@ -604,13 +666,6 @@ function WConverhpClient(opt) {
604
666
  res = msg
605
667
  })
606
668
 
607
- //r
608
- let r = {
609
- state,
610
- msg: res,
611
- }
612
- // console.log('sendData r', r)
613
-
614
669
  //check
615
670
  if (state === '') {
616
671
  // console.log('invalid state', r)
@@ -621,11 +676,11 @@ function WConverhpClient(opt) {
621
676
  //check
622
677
  if (state === 'error') {
623
678
  // console.log('send data error', r)
624
- eeEmit('error', `send data error`)
625
- return Promise.reject('send data error')
679
+ // eeEmit('error', res) //一般錯誤會嘗試n次, 每次也都會emit, 故此處不再基於已知state='error'時再emit
680
+ return Promise.reject(res)
626
681
  }
627
682
 
628
- return r.msg
683
+ return res
629
684
  }
630
685
 
631
686
  //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 authorization = get(headers, 'authorization', '')
337
+ authorization = isestr(authorization) ? authorization : ''
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', authorization, 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 authorization = get(headers, 'authorization', '')
495
+ authorization = isestr(authorization) ? authorization : ''
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', authorization, 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 authorization = get(headers, 'authorization', '')
641
+ authorization = isestr(authorization) ? authorization : ''
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', authorization, 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, authorization, headers, query }) => {
10
+ console.log('funCheck', `apiType[${apiType}]`, `authorization[${authorization}]`)
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',