w-web-api 1.0.53 → 1.0.55

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.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/dist/css/{app.fe69497a.css → app.cad4a1ca.css} +1 -1
  3. package/dist/index.tmp +1 -1
  4. package/dist/js/app-legacy.7687b23b.js +1 -0
  5. package/dist/js/app.7687b23b.js +1 -0
  6. package/dist/js/chunk-vendors-legacy.4c27cf51.js +15 -0
  7. package/dist/js/chunk-vendors.4c27cf51.js +15 -0
  8. package/dist/w-web-api.umd.js +2 -2
  9. package/dist/w-web-api.umd.js.map +1 -1
  10. package/docs/WWebApi.html +1 -1
  11. package/docs/index.html +1 -1
  12. package/docs/server_WWebApi.mjs.html +24 -34
  13. package/docs/src_components_Common_CheckYesNo.vue.html +1 -1
  14. package/logs/2026-06-19T16.log +6 -0
  15. package/logs/2026-06-20T11.log +4 -0
  16. package/logs/2026-06-20T14.log +2 -0
  17. package/logs/2026-06-21T20.log +1 -0
  18. package/logs/2026-06-21T21.log +4 -0
  19. package/logs/2026-06-22T07.log +12 -0
  20. package/logs/2026-06-22T08.log +808 -0
  21. package/logs/2026-06-22T09.log +104 -0
  22. package/logs/2026-06-22T10.log +26 -0
  23. package/logs/2026-06-22T11.log +860 -0
  24. package/logs/2026-06-22T12.log +430 -0
  25. package/logs/2026-06-22T23.log +1547 -0
  26. package/logs/2026-06-23T00.log +473 -0
  27. package/logs/2026-06-23T08.log +231 -0
  28. package/logs/2026-06-23T09.log +179 -0
  29. package/logs/2026-07-01T11.log +488 -0
  30. package/logs/2026-07-09T22.log +370 -0
  31. package/logs/2026-07-09T23.log +370 -0
  32. package/logs/2026-07-10T12.log +284 -0
  33. package/logs/2026-07-10T13.log +777 -0
  34. package/logs/2026-07-11T17.log +2 -0
  35. package/package.json +15 -14
  36. package/server/WWebApi.mjs +23 -33
  37. package/server/procLang.mjs +8 -88
  38. package/server/procProxy.mjs +89 -89
  39. package/server/srLog.mjs +2 -2
  40. package/server/staLogs/filterVpfsByWindow.mjs +27 -0
  41. package/server/staLogs/staEvent.mjs +4 -2
  42. package/server/staLogs/test_staEvent.mjs +67 -1
  43. package/settings.json +4 -0
  44. package/src/components/Layout.vue +1 -20
  45. package/src/components/LayoutContent.vue +0 -26
  46. package/src/components/LayoutContentEdit.vue +2 -2
  47. package/src/components/LayoutContentTest.vue +1 -19
  48. package/src/main.js +3 -8
  49. package/src/plugins/mUI.mjs +0 -35
  50. package/src/store/mutations.mjs +0 -14
  51. package/src/store/types.mjs +0 -3
  52. package/srv.mjs +6 -4
  53. package/tableTags.json +1 -1
  54. package/z/344/277/256/346/255/243/350/246/217/345/212/203/346/233/270.md +246 -0
  55. package/_gh-pages-deploy/.nojekyll +0 -0
  56. package/_gh-pages-deploy/WWebApi.html +0 -898
  57. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  58. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  59. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  60. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  61. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  62. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  63. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  64. package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  65. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  66. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -978
  67. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  68. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  69. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  70. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  71. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -1049
  72. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  73. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  74. package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  75. package/_gh-pages-deploy/index.html +0 -84
  76. package/_gh-pages-deploy/scripts/collapse.js +0 -39
  77. package/_gh-pages-deploy/scripts/commonNav.js +0 -28
  78. package/_gh-pages-deploy/scripts/linenumber.js +0 -25
  79. package/_gh-pages-deploy/scripts/nav.js +0 -12
  80. package/_gh-pages-deploy/scripts/polyfill.js +0 -4
  81. package/_gh-pages-deploy/scripts/prettify/Apache-License-2.0.txt +0 -202
  82. package/_gh-pages-deploy/scripts/prettify/lang-css.js +0 -2
  83. package/_gh-pages-deploy/scripts/prettify/prettify.js +0 -28
  84. package/_gh-pages-deploy/scripts/search.js +0 -99
  85. package/_gh-pages-deploy/server_WWebApi.mjs.html +0 -1012
  86. package/_gh-pages-deploy/src_components_Common_CheckYesNo.vue.html +0 -187
  87. package/_gh-pages-deploy/styles/jsdoc.css +0 -776
  88. package/_gh-pages-deploy/styles/prettify.css +0 -80
  89. package/dist/js/app-legacy.15819aa7.js +0 -1
  90. package/dist/js/app.15819aa7.js +0 -1
  91. package/dist/js/chunk-vendors-legacy.c1a32dd1.js +0 -15
  92. package/dist/js/chunk-vendors.c1a32dd1.js +0 -15
  93. package/src/plugins/mDataSelectorSchema.mjs +0 -30
  94. package/src/plugins/mShare.mjs +0 -44
@@ -9,6 +9,7 @@ import genPm from 'wsemi/src/genPm.mjs'
9
9
  import isestr from 'wsemi/src/isestr.mjs'
10
10
  import fsTreeFolder from 'wsemi/src/fsTreeFolder.mjs'
11
11
  import fsBuildReadStreamText from 'wsemi/src/fsBuildReadStreamText.mjs'
12
+ import filterVpfsByWindow from './filterVpfsByWindow.mjs'
12
13
 
13
14
 
14
15
  //staEvent(通用事件頻率統計,骨架移植自 w-web-sso server/staLogs/staIp.mjs,但「不過濾特定 event」、
@@ -25,13 +26,13 @@ import fsBuildReadStreamText from 'wsemi/src/fsBuildReadStreamText.mjs'
25
26
  //參數:
26
27
  // timeLength 往回統計天數(預設 7)
27
28
  // timeInterval 時間粒度 'hr'(每小時,預設)/ 'day'(每日)
28
- // opt.fdLog log 資料夾(預設 './_logs',須與 srLog 寫入之 logFd 一致;e2e 可指向合成 log 達 hermetic)
29
+ // opt.fdLog log 資料夾(預設 './logs',須與 srLog 寫入之 logFd 一致;e2e 可指向合成 log 達 hermetic)
29
30
  async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
30
31
 
31
32
  //fdLog
32
33
  let fdLog = get(opt, 'fdLog')
33
34
  if (!isestr(fdLog)) {
34
- fdLog = './_logs'
35
+ fdLog = './logs'
35
36
  }
36
37
 
37
38
  //fmt
@@ -53,6 +54,7 @@ async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
53
54
 
54
55
  //vpfs
55
56
  let vpfs = fsTreeFolder(fdLog)
57
+ vpfs = filterVpfsByWindow(vpfs, tStart, fmt) //開檔前剔除窗外檔, 見該模組註解
56
58
 
57
59
  //logs(逐檔逐行 stream parse,挑出 tStart 之後、且帶 event 字串者)
58
60
  let logs = []
@@ -10,9 +10,10 @@ import fs from 'fs'
10
10
  import path from 'path'
11
11
  import ot from 'dayjs'
12
12
  import staEvent from './staEvent.mjs'
13
+ import filterVpfsByWindow from './filterVpfsByWindow.mjs'
13
14
 
14
15
 
15
- //tmp log 資料夾(落在主 cwd ./tmp/,集中可一鍵清;不污染真實 ./_logs
16
+ //tmp log 資料夾(落在主 cwd ./tmp/,集中可一鍵清;不污染真實 ./logs
16
17
  let fdLog = './tmp/_logs-test-staEvent'
17
18
 
18
19
  //以「當前小時正中(:30)」為錨點,避免測試剛好跨小時邊界導致 bucket 飄移
@@ -71,6 +72,67 @@ function findBucket(rs, time) {
71
72
  }
72
73
 
73
74
 
75
+ //testFilterVpfsByWindowDirect:直測 filterVpfsByWindow「粒度自適應」防線(filterVpfsByWindow.mjs:22),
76
+ //以自造 vpfs 物件陣列覆蓋 P-2 要求之三個分支,不經 staEvent/fsTreeFolder。
77
+ function testFilterVpfsByWindowDirect() {
78
+
79
+ //tStart 固定為 2026-07-08 21:00,keyStart(fmt='YYYY-MM-DDTHH')= '2026-07-08T21'
80
+ let tStart = ot('2026-07-08T21:00:00')
81
+ let fmtHr2 = 'YYYY-MM-DDTHH'
82
+
83
+ //①day 粒度檔名(10 字元)× fmt='YYYY-MM-DDTHH',且 tStart 落在該日內 → 應保留。
84
+ //對應規格:filterVpfsByWindow.mjs:11-14 註解——不 slice 則 '2026-07-08' < '2026-07-08T21'(同日
85
+ //字典序比較,短字串為前綴恆較小)誤判窗外漏讀整天;filterVpfsByWindow.mjs:22 之
86
+ //`bn >= keyStart.slice(0, bn.length)` 為此案例之防線(slice 後同為 '2026-07-08',相等即保留)。
87
+ let vpfDaySameDate = { path: '/x/2026-07-08.log', name: '2026-07-08.log', isFolder: false, level: 1 }
88
+ let rs1 = filterVpfsByWindow([vpfDaySameDate], tStart, fmtHr2)
89
+ assert.strictEqual(rs1.length, 1, 'day 粒度同日檔名(10 字元)於 hr fmt(13 字元)下應被保留')
90
+
91
+ //②明確窗外之 hr 檔名(早於 tStart 所在小時)→ 應剔除。
92
+ //對應規格:filterVpfsByWindow.mjs:22 主邏輯 `bn >= keyStart.slice(0, bn.length)`——
93
+ //bn 與 keyStart 同為 hr 粒度(13 字元)時 slice 為 no-op,純字串比較即可判窗外。
94
+ let vpfHrBefore = { path: '/x/2026-07-08T10.log', name: '2026-07-08T10.log', isFolder: false, level: 1 }
95
+ let rs2 = filterVpfsByWindow([vpfHrBefore], tStart, fmtHr2)
96
+ assert.strictEqual(rs2.length, 0, '明確窗外(早於 tStart 小時)之 hr 檔名應被剔除')
97
+
98
+ //③非 ISO 前綴檔名 → fail-open 保留。
99
+ //對應規格:filterVpfsByWindow.mjs:9,19-20 註解——「fail-open: 檔名不符 ISO 前綴者一律保留
100
+ //(寧可多讀, 不可漏讀)」。
101
+ let vpfNonIso = { path: '/x/current.log', name: 'current.log', isFolder: false, level: 1 }
102
+ let rs3 = filterVpfsByWindow([vpfNonIso], tStart, fmtHr2)
103
+ assert.strictEqual(rs3.length, 1, '非 ISO 前綴檔名應 fail-open 保留')
104
+
105
+ console.log('=== testFilterVpfsByWindowDirect PASS ===')
106
+ }
107
+
108
+
109
+ //testGranularityAdaptiveIntegration:整合路徑驗證——srLog 之 logInterval(決定檔名粒度)與 staLogs 之
110
+ //timeInterval(決定 fmt)不同調時(day 粒度檔名 × hr 粒度 fmt),窗內事件仍須被 staEvent 讀到。
111
+ //對應規格:filterVpfsByWindow.mjs:11-14 註解之情境重現於整合路徑(經 fsTreeFolder + fsBuildReadStreamText
112
+ //實際開檔讀行),證明 filterVpfsByWindow.mjs:22 之 slice 防線在 staEvent.mjs:57 呼叫處確實生效,
113
+ //而非僅單元測試層級成立。
114
+ async function testGranularityAdaptiveIntegration() {
115
+ let fdLog2 = './tmp/_logs-test-staEvent-granularity'
116
+ fs.rmSync(fdLog2, { recursive: true, force: true })
117
+ fs.mkdirSync(fdLog2, { recursive: true })
118
+
119
+ //tRef 近似 staEvent 內部之 tStart(timeLength=0 → tStart ≈ now);day 粒度檔名(10 字元)= tRef 當日
120
+ let tRef = ot()
121
+ let dayFileName = `${tRef.format('YYYY-MM-DD')}.log`
122
+ let tEvent = tRef.add(5, 'second') //晚於 tStart,使 staEvent.mjs:76 之 per-line `t.isAfter(tStart)` 成立
123
+ let lines = [logLine(tEvent, 'granularityProbe')]
124
+ fs.writeFileSync(path.join(fdLog2, dayFileName), lines.join('\n') + '\n', 'utf8')
125
+
126
+ let rsG = await staEvent(0, 'hr', { fdLog: fdLog2 })
127
+ let totalG = rsG.reduce((acc, v) => acc + v.data.count, 0)
128
+ assert.strictEqual(totalG, 1, 'day 粒度檔名於 hr timeInterval 下,窗內事件應被 staEvent 計入(不被誤判窗外漏讀)')
129
+
130
+ fs.rmSync(fdLog2, { recursive: true, force: true })
131
+
132
+ console.log('=== testGranularityAdaptiveIntegration PASS ===')
133
+ }
134
+
135
+
74
136
  async function main() {
75
137
 
76
138
  writeSyntheticLogs()
@@ -119,6 +181,10 @@ async function main() {
119
181
  //清理
120
182
  fs.rmSync(fdLog, { recursive: true, force: true })
121
183
 
184
+ //=== 粒度自適應防線(P-2)===
185
+ testFilterVpfsByWindowDirect()
186
+ await testGranularityAdaptiveIntegration()
187
+
122
188
  console.log('=== test_staEvent PASS ===')
123
189
  console.log(`hr buckets: ${rs.length}, 本小時=${JSON.stringify(bNow.data)}, 前一小時=${JSON.stringify(bPrev.data)}`)
124
190
  }
package/settings.json CHANGED
@@ -11,4 +11,8 @@
11
11
 
12
12
  // 伺服器通訊 port
13
13
  serverPort: 11005,
14
+
15
+ logFd: './logs',
16
+ logInterval: 'hr',
17
+
14
18
  }
@@ -106,7 +106,7 @@ export default {
106
106
  let showLanguage = get(vo, 'webInfor.showLanguage', '')
107
107
  // console.log('showLanguage', showLanguage)
108
108
  vo.showLangSelect = showLanguage === 'y'
109
- //setLang(null):改走 getLang 解析(URL ?lang= > store > window 注入之 server 語系),
109
+ //setLang(null):改走 getLang 解析(URL ?lang= > window 注入之 server 語系 > store),
110
110
  //不再用 webInfor.language 明確覆蓋(否則會蓋掉 URL ?lang= 與使用者切換)。server 初始語系已由
111
111
  //window.___pmwperm___.language(WWebApi 注入 index.html)提供,getLang 會取得。
112
112
  vo.$ui.setLang(null, 'layout mounted')
@@ -116,10 +116,6 @@ export default {
116
116
  },
117
117
  computed: {
118
118
 
119
- viewState: function() {
120
- return get(this, `$store.state.viewState`, '')
121
- },
122
-
123
119
  heightToolbar: function() {
124
120
  //console.log('computed heightToolbar')
125
121
 
@@ -128,11 +124,6 @@ export default {
128
124
  return get(vo, `$store.state.heightToolbar`, 0)
129
125
  },
130
126
 
131
- userToken: function() {
132
- let vo = this
133
- return get(vo, `$store.state.userToken`)
134
- },
135
-
136
127
  lang: function() {
137
128
  let vo = this
138
129
  return get(vo, `$store.state.lang`, '')
@@ -168,16 +159,6 @@ export default {
168
159
  return get(vo, `$store.state.webInfor.webLogo`, '')
169
160
  },
170
161
 
171
- userSelf: function() {
172
- let vo = this
173
- return get(vo, `$store.state.userSelf`, '')
174
- },
175
-
176
- userName: function() {
177
- let vo = this
178
- return get(vo, `userSelf.name`, '')
179
- },
180
-
181
162
  },
182
163
  methods: {
183
164
 
@@ -286,7 +286,6 @@ import filter from 'lodash-es/filter.js'
286
286
  import cloneDeep from 'lodash-es/cloneDeep.js'
287
287
  import isobj from 'wsemi/src/isobj.mjs'
288
288
  import iseobj from 'wsemi/src/iseobj.mjs'
289
- import timemsTZ2day from 'wsemi/src/timemsTZ2day.mjs'
290
289
  import convertToTree from 'wsemi/src/convertToTree.mjs'
291
290
  import { mdiArrowLeft, mdiArrowRight, mdiCloudBraces, mdiChartBar } from '@mdi/js'
292
291
  import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
@@ -338,13 +337,6 @@ export default {
338
337
  mdiArrowRight,
339
338
  apiSelect: null,
340
339
 
341
- kpColorMethod: {
342
- GET: '#0082d0',
343
- POST: '#069061',
344
- PUT: '#ff5800',
345
- DEL: '#ef0006',
346
- },
347
-
348
340
  //API 管理:模式切換 / 新增 / 搜尋
349
341
  mode: 'docs', //'docs' | 'edit' | 'test'
350
342
  newMode: false,
@@ -509,24 +501,6 @@ export default {
509
501
  return method
510
502
  },
511
503
 
512
- getMethodColor: function(item) {
513
- let vo = this
514
- let method = vo.getMethod(item)
515
- let color = get(vo.kpColorMethod, method, '#888')
516
- return color
517
- },
518
-
519
- getMethodColorByKey: function(key) {
520
- let vo = this
521
- let method = vo.getMethodByKey(key)
522
- let color = get(vo.kpColorMethod, method, '#888')
523
- return color
524
- },
525
-
526
- getDay: function(t) {
527
- return timemsTZ2day(t)
528
- },
529
-
530
504
  jsonHighlight: function(str) {
531
505
  let s = (str === null || str === undefined) ? '' : String(str)
532
506
  // escape HTML
@@ -341,7 +341,7 @@ export default {
341
341
  onClickSave: function() {
342
342
  let vo = this
343
343
  vo.submitSave()
344
- .catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error') })
344
+ .catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) })
345
345
  .finally(function() { vo.$ui.updateLoading(false) })
346
346
  },
347
347
 
@@ -435,7 +435,7 @@ export default {
435
435
 
436
436
  }
437
437
  core()
438
- .catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error') })
438
+ .catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) })
439
439
  .finally(function() { vo.$ui.updateLoading(false) })
440
440
  },
441
441
 
@@ -372,24 +372,6 @@ export default {
372
372
  return get(kpColorMethod, method, 'var(--c-2)')
373
373
  },
374
374
 
375
- getStatusColor: function(status) {
376
- // let vo = this
377
- let s = parseInt(status, 10)
378
- if (s >= 200 && s < 300) {
379
- return '#2a2'
380
- }
381
- if (s >= 300 && s < 400) {
382
- return '#68f'
383
- }
384
- if (s >= 400 && s < 500) {
385
- return '#f82'
386
- }
387
- if (s >= 500) {
388
- return '#f26'
389
- }
390
- return '#888'
391
- },
392
-
393
375
  jsonToRows: function(jsonStr) {
394
376
  // let vo = this
395
377
  let rows = []
@@ -605,7 +587,7 @@ export default {
605
587
  core()
606
588
  .catch(function(err) {
607
589
  console.log('catch', err)
608
- vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error')
590
+ vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' })
609
591
  })
610
592
  .finally(function() {
611
593
  vo.sending = false
package/src/main.js CHANGED
@@ -13,8 +13,6 @@ import domDragDrop from 'w-component-vue/src/js/domDragDrop.mjs'
13
13
  import App from './App.vue'
14
14
  import store from './store/index.mjs'
15
15
  import ui from './plugins/mUI.mjs'
16
- import mDataSelectorSchema from './plugins/mDataSelectorSchema.mjs'
17
- import * as s from './plugins/mShare.mjs'
18
16
  import ds from './schema/index.mjs'
19
17
  // console.log('globalState', globalState)
20
18
  // console.log('ds', ds)
@@ -32,9 +30,6 @@ Vue.prototype.$alert = function() {
32
30
  }
33
31
  }
34
32
 
35
- //dssm
36
- let dssm = mDataSelectorSchema(ds)
37
-
38
33
  //prototype
39
34
  Vue.prototype.$ui = ui
40
35
  Vue.prototype.$t = ui.getKpText
@@ -45,8 +40,6 @@ Vue.prototype.$transErr = (err) => {
45
40
  let msg = ui.getKpText(key)
46
41
  return (msg && msg !== key) ? msg : ui.getKpText('anUnexpectedErrorOccurred')
47
42
  }
48
- Vue.prototype.$s = s
49
- Vue.prototype.$dssm = dssm
50
43
  Vue.prototype.$ds = ds
51
44
  Vue.prototype.$dg = {}
52
45
 
@@ -87,7 +80,9 @@ WServHapiClient({
87
80
 
88
81
  })
89
82
  .catch((err) => {
90
- console.log(err)
83
+ console.log('getWebInfor failed', err)
84
+ //getWebInfor 失敗時導向連線錯誤態,避免 ready(需 webInfor) 永假而卡在「已登入」轉圈無回饋
85
+ ui.updateConnState('csErrConn')
91
86
  })
92
87
 
93
88
  },
@@ -1,47 +1,12 @@
1
1
  import Vue from 'vue'
2
- import min from 'lodash-es/min.js'
3
- import size from 'lodash-es/size.js'
4
- import take from 'lodash-es/take.js'
5
- import isEqual from 'lodash-es/isEqual.js'
6
- import uniq from 'lodash-es/uniq.js'
7
- import set from 'lodash-es/set.js'
8
2
  import get from 'lodash-es/get.js'
9
3
  import each from 'lodash-es/each.js'
10
- import map from 'lodash-es/map.js'
11
- import filter from 'lodash-es/filter.js'
12
- import last from 'lodash-es/last.js'
13
- import split from 'lodash-es/split.js'
14
- import join from 'lodash-es/join.js'
15
- import drop from 'lodash-es/drop.js'
16
- import dropRight from 'lodash-es/dropRight.js'
17
- import groupBy from 'lodash-es/groupBy.js'
18
- import sortBy from 'lodash-es/sortBy.js'
19
4
  import cloneDeep from 'lodash-es/cloneDeep.js'
20
- import cint from 'wsemi/src/cint.mjs'
21
5
  import delay from 'wsemi/src/delay.mjs'
22
- import isarr from 'wsemi/src/isarr.mjs'
23
6
  import isestr from 'wsemi/src/isestr.mjs'
24
7
  import isfun from 'wsemi/src/isfun.mjs'
25
8
  import iseobj from 'wsemi/src/iseobj.mjs'
26
- import isearr from 'wsemi/src/isearr.mjs'
27
- import isEle from 'wsemi/src/isEle.mjs'
28
- import strleft from 'wsemi/src/strleft.mjs'
29
- import strdelleft from 'wsemi/src/strdelleft.mjs'
30
- import sep from 'wsemi/src/sep.mjs'
31
- import aes2str from 'wsemi/src/aes2str.mjs'
32
- import str2aes from 'wsemi/src/str2aes.mjs'
33
- import haskey from 'wsemi/src/haskey.mjs'
34
- import genPm from 'wsemi/src/genPm.mjs'
35
- import pmSeries from 'wsemi/src/pmSeries.mjs'
36
9
  import waitFun from 'wsemi/src/waitFun.mjs'
37
- import browserView from 'wsemi/src/browserView.mjs'
38
- import arrHas from 'wsemi/src/arrHas.mjs'
39
- import arrSort from 'wsemi/src/arrSort.mjs'
40
- import arrInsert from 'wsemi/src/arrInsert.mjs'
41
- import replace from 'wsemi/src/replace.mjs'
42
- import timemsTZ2past from 'wsemi/src/timemsTZ2past.mjs'
43
- import convertToTree from 'wsemi/src/convertToTree.mjs'
44
- // import WUiDwload from 'w-ui-dwload/src/WUiDwload.mjs'
45
10
 
46
11
 
47
12
  let kpFallback = {
@@ -79,12 +79,6 @@ export let mutations = {
79
79
  state[msg.tableName] = msg.data
80
80
  },
81
81
 
82
- [types.UpdateData] (state, msg) {
83
- //msg.path內為存取路徑, 需使用set處理
84
- // console.log('UpdateData msg', msg)
85
- set(state, msg.path, msg.data)
86
- },
87
-
88
82
  [types.UpdateHeightApp] (state, heightApp) {
89
83
  state.heightApp = heightApp
90
84
  },
@@ -93,14 +87,6 @@ export let mutations = {
93
87
  state.heightAppEff = heightAppEff
94
88
  },
95
89
 
96
- [types.UpdateHeightToolbar] (state, heightToolbar) {
97
- state.heightToolbar = heightToolbar
98
- },
99
-
100
- [types.UpdateMenu] (state, menu) {
101
- state.menu = menu
102
- },
103
-
104
90
  [types.UpdateUserToken] (state, userToken) {
105
91
  state.userToken = userToken
106
92
  },
@@ -6,10 +6,7 @@ export const UpdateSyncState = 'UpdateSyncState'
6
6
  export const UpdateLoading = 'UpdateLoading'
7
7
  // export const UpdateViewState = 'UpdateViewState'
8
8
  export const UpdateTableData = 'UpdateTableData'
9
- export const UpdateData = 'UpdateData'
10
9
  export const UpdateHeightApp = 'UpdateHeightApp'
11
10
  export const UpdateHeightAppEff = 'UpdateHeightAppEff'
12
- export const UpdateHeightToolbar = 'UpdateHeightToolbar'
13
- export const UpdateMenu = 'UpdateMenu'
14
11
  export const UpdateUserToken = 'UpdateUserToken'
15
12
  export const UpdateUserSelf = 'UpdateUserSelf'
package/srv.mjs CHANGED
@@ -37,7 +37,7 @@ let opt = {
37
37
  language: get(stApp, 'language', 'eng'),
38
38
 
39
39
  //log 資料夾與輪檔間隔(srLog 寫入 + staEvent 統計皆讀此)。e2e 可用 genTempSettings({logFd}) 指向合成 log 達 hermetic。
40
- logFd: get(stApp, 'logFd', './_logs'),
40
+ logFd: get(stApp, 'logFd', './logs'),
41
41
  logInterval: get(stApp, 'logInterval', 'hr'),
42
42
 
43
43
  webName: {
@@ -46,7 +46,7 @@ let opt = {
46
46
  },
47
47
  webDescription: {
48
48
  'eng': 'A web service package as methods to send requests to and receive responses from an API.',
49
- 'cht': 'A web service package as methods to send requests to and receive responses from an API.',
49
+ 'cht': '一套以方法形式,用於發送請求至API並接收其回應的網頁服務套件。',
50
50
  },
51
51
  webLogo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMyIDMyIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGcgaWQ9IkxheWVyXzIiLz48ZyBpZD0iTGF5ZXJfMyIvPjxnIGlkPSJMYXllcl80Ij48Zz48cGF0aCBkPSJNOS4wMiw2QzkuMDEyNyw2LDkuMDA2OCw1Ljk5OSw5LDZIMkMxLjQ0NzgsNiwxLDUuNTUyNywxLDVWMmMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoNiAgICBjMC40MzA3LDAsMC44MTI1LDAuMjc1NCwwLjk0ODcsMC42ODM2bDAuOTQwNCwyLjgyMTNDOS45NzIyLDQuNjUxNCwxMC4wMiw0LjgyMDMsMTAuMDIsNUMxMC4wMiw1LjU1MjcsOS41NzIzLDYsOS4wMiw2eiBNMyw0ICAgIGg0LjYxMjhMNy4yNzkzLDNIM1Y0eiIgZmlsbD0iI0Y1RDgwMyIvPjwvZz48Zz48cGF0aCBkPSJNMjQuMDE5NSwyMmMtMC4wMDM5LDAtMC4wMTE3LDAuMDAxLTAuMDE5NSwwaC03Yy0wLjU1MjIsMC0xLTAuNDQ3My0xLTF2LTNjMC0wLjU1MjcsMC40NDc4LTEsMS0xaDYgICAgYzAuNDMwNywwLDAuODEyNSwwLjI3NTQsMC45NDgyLDAuNjgzNmwwLjk0MDQsMi44MjEzYzAuMDg0LDAuMTQ2NSwwLjEzMDksMC4zMTU0LDAuMTMwOSwwLjQ5NTEgICAgQzI1LjAxOTUsMjEuNTUyNywyNC41NzIzLDIyLDI0LjAxOTUsMjJ6IE0xOCwyMGg0LjYxMjNsLTAuMzMzLTFIMThWMjB6IiBmaWxsPSIjRjVEODAzIi8+PC9nPjxnPjxwYXRoIGQ9Ik0xNSwxNUgyYy0wLjU1MjIsMC0xLTAuNDQ3My0xLTFWNWMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoMTNjMC41NTIyLDAsMSwwLjQ0NzMsMSwxdjkgICAgQzE2LDE0LjU1MjcsMTUuNTUyMiwxNSwxNSwxNXogTTMsMTNoMTFWNkgzVjEzeiIgZmlsbD0iIzAxODFCMCIvPjwvZz48Zz48cGF0aCBkPSJNMzAsMzFIMTdjLTAuNTUyMiwwLTEtMC40NDczLTEtMXYtOWMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoMTNjMC41NTI3LDAsMSwwLjQ0NzMsMSwxdjkgICAgQzMxLDMwLjU1MjcsMzAuNTUyNywzMSwzMCwzMXogTTE4LDI5aDExdi03SDE4VjI5eiIgZmlsbD0iIzAxODFCMCIvPjwvZz48Zz48cGF0aCBkPSJNMjYsOGgtOGMtMC41NTI3LDAtMSwwLjQ0NzMtMSwxczAuNDQ3MywxLDEsMWg3djZjMCwwLjU1MjcsMC40NDczLDEsMSwxczEtMC40NDczLDEtMVY5ICAgIEMyNyw4LjQ0NzMsMjYuNTUyNyw4LDI2LDh6IiBmaWxsPSIjMDBBQ0JBIi8+PGc+PHBhdGggZD0iTTIwLDEyYy0wLjI1NTksMC0wLjUxMTctMC4wOTc3LTAuNzA3LTAuMjkzbC0yLTJjLTAuMzkwNi0wLjM5MDYtMC4zOTA2LTEuMDIzNCwwLTEuNDE0MWwyLTIgICAgIGMwLjM5MDYtMC4zOTA2LDEuMDIzNC0wLjM5MDYsMS40MTQxLDBzMC4zOTA2LDEuMDIzNCwwLDEuNDE0MUwxOS40MTQxLDlsMS4yOTMsMS4yOTNjMC4zOTA2LDAuMzkwNiwwLjM5MDYsMS4wMjM0LDAsMS40MTQxICAgICBDMjAuNTExNywxMS45MDIzLDIwLjI1NTksMTIsMjAsMTJ6IiBmaWxsPSIjRjVEODAzIi8+PC9nPjwvZz48Zz48cGF0aCBkPSJNMTQsMjVIN3YtNmMwLTAuNTUyNy0wLjQ0NzgtMS0xLTFzLTEsMC40NDczLTEsMXY3YzAsMC41NTI3LDAuNDQ3OCwxLDEsMWg4YzAuNTUyMiwwLDEtMC40NDczLDEtMSAgICBTMTQuNTUyMiwyNSwxNCwyNXoiIGZpbGw9IiMwMEFDQkEiLz48Zz48cGF0aCBkPSJNMTIsMjljLTAuMjU1OSwwLTAuNTExNy0wLjA5NzctMC43MDctMC4yOTNjLTAuMzkwNi0wLjM5MDYtMC4zOTA2LTEuMDIzNCwwLTEuNDE0MUwxMi41ODU5LDI2ICAgICBsLTEuMjkzLTEuMjkzYy0wLjM5MDYtMC4zOTA2LTAuMzkwNi0xLjAyMzQsMC0xLjQxNDFzMS4wMjM0LTAuMzkwNiwxLjQxNDEsMGwyLDJjMC4zOTA2LDAuMzkwNiwwLjM5MDYsMS4wMjM0LDAsMS40MTQxbC0yLDIgICAgIEMxMi41MTE3LDI4LjkwMjMsMTIuMjU1OSwyOSwxMiwyOXoiIGZpbGw9IiNGNUQ4MDMiLz48L2c+PC9nPjwvZz48ZyBpZD0iTGF5ZXJfNSIvPjxnIGlkPSJMYXllcl82Ii8+PGcgaWQ9IkxheWVyXzciLz48ZyBpZD0iTGF5ZXJfOCIvPjxnIGlkPSJMYXllcl85Ii8+PGcgaWQ9IkxheWVyXzEwIi8+PGcgaWQ9IkxheWVyXzExIi8+PGcgaWQ9IkxheWVyXzEyIi8+PGcgaWQ9IkxheWVyXzEzIi8+PGcgaWQ9IkxheWVyXzE0Ii8+PGcgaWQ9IkxheWVyXzE1Ii8+PGcgaWQ9IkxheWVyXzE2Ii8+PGcgaWQ9IkxheWVyXzE3Ii8+PGcgaWQ9IkxheWVyXzE4Ii8+PGcgaWQ9IkxheWVyXzE5Ii8+PGcgaWQ9IkxheWVyXzIwIi8+PGcgaWQ9IkxheWVyXzIxIi8+PGcgaWQ9IkxheWVyXzIyIi8+PGcgaWQ9IkxheWVyXzIzIi8+PGcgaWQ9IkxheWVyXzI0Ii8+PGcgaWQ9IkxheWVyXzI1Ii8+PGcgaWQ9IkxheWVyXzI2Ii8+PC9zdmc+',
52
52
 
@@ -54,8 +54,10 @@ let opt = {
54
54
 
55
55
  let getUserByToken = async (token) => {
56
56
  // return {} //測試無法登入
57
- //開發階段 w-ui-loginout 於 localhost 自動給 token 'sys'
58
- if (token === 'sys') {
57
+ //'sys' 為開發捷徑(w-ui-loginout 於 localhost 自動帶入)。加環境守門:NODE_ENV==='production' 時不接受,
58
+ //避免 srv.mjs 若作正式入口時 'sys' 成為遠端管理員後門。e2e/dev 未設 NODE_ENV=production 故仍可用;
59
+ //正式部署設 NODE_ENV=production 即停用此捷徑(並應改提供真實 getUserByToken)。
60
+ if (token === 'sys' && process.env.NODE_ENV !== 'production') {
59
61
  return { id: 'id-for-admin', name: '測試者', email: 'admin@example.com', isAdmin: 'y' }
60
62
  }
61
63
  //未設定 SSO app token 時(本機開發未接SSO), 不打SSO直接拒絕
package/tableTags.json CHANGED
@@ -1 +1 @@
1
- {"apis":"2026-06-22T12:43:06+08:00|Yl6xfX"}
1
+ {"apis":"2026-07-11T17:47:54+08:00|7AQq2D"}