w-web-perm 1.1.11 → 1.1.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.
Files changed (57) hide show
  1. package/README.md +6 -0
  2. package/dist/index.tmp +1 -1
  3. package/dist/js/app-legacy.7cb7e394.js +1 -0
  4. package/dist/js/app.7cb7e394.js +1 -0
  5. package/dist/w-web-perm.umd.js +2 -2
  6. package/dist/w-web-perm.umd.js.map +1 -1
  7. package/docs/WWebPerm.html +2 -2
  8. package/docs/global.html +2239 -222
  9. package/docs/index.html +2 -2
  10. package/docs/server_WWebPerm.mjs.html +15 -2
  11. package/docs/server_dataChannel.mjs.html +2 -2
  12. package/docs/server_lockSave.mjs.html +2 -2
  13. package/docs/server_maskLog.mjs.html +2 -2
  14. package/docs/server_procCore.mjs.html +2 -2
  15. package/docs/server_staLogs_resolveShellWorker.mjs.html +2 -2
  16. package/docs/server_validateRows.mjs.html +15 -4
  17. package/docs/server_wrapInjected.mjs.html +2 -2
  18. package/docs/src_fetchJson.mjs.html +2 -2
  19. package/docs/src_js_cvKpToArr.mjs.html +125 -0
  20. package/docs/src_js_cvKpToObj.mjs.html +199 -0
  21. package/docs/src_js_eachOwn.mjs.html +2 -2
  22. package/docs/src_js_fmtLossyMsg.mjs.html +95 -0
  23. package/docs/src_js_getKeyOrderLost.mjs.html +121 -0
  24. package/docs/src_js_getKpLossy.mjs.html +160 -0
  25. package/docs/src_js_getKpWriteLost.mjs.html +100 -0
  26. package/docs/src_js_getOwn.mjs.html +2 -2
  27. package/docs/src_js_getRuleEnable.mjs.html +2 -2
  28. package/docs/src_js_isAuthMode.mjs.html +92 -0
  29. package/docs/src_js_joinNames.mjs.html +96 -0
  30. package/docs/src_js_keepKeyOrder.mjs.html +139 -0
  31. package/docs/src_js_legendFit.mjs.html +2 -2
  32. package/docs/src_plugins_reuseDeletedIds.mjs.html +2 -2
  33. package/docs/src_plugins_submitGuard.mjs.html +2 -2
  34. package/package.json +1 -1
  35. package/server/WWebPerm.mjs +13 -0
  36. package/server/procLang.mjs +4 -0
  37. package/server/validateRows.mjs +13 -2
  38. package/src/components/LayoutContentGrups.vue +3 -2
  39. package/src/components/LayoutContentPemis.vue +5 -3
  40. package/src/components/LayoutContentUsers.vue +2 -1
  41. package/src/components/VeCgrups.vue +47 -2
  42. package/src/components/VeCpemis.vue +47 -2
  43. package/src/components/VeCrules.vue +7 -1
  44. package/src/components/VeGrupBlngUsers.vue +61 -7
  45. package/src/components/VePemiBlngGrups.vue +61 -7
  46. package/src/js/cvKpToArr.mjs +53 -0
  47. package/src/js/cvKpToObj.mjs +127 -0
  48. package/src/js/fmtLossyMsg.mjs +23 -0
  49. package/src/js/getKeyOrderLost.mjs +49 -0
  50. package/src/js/getKpLossy.mjs +88 -0
  51. package/src/js/getKpWriteLost.mjs +28 -0
  52. package/src/js/isAuthMode.mjs +20 -0
  53. package/src/js/joinNames.mjs +24 -0
  54. package/src/js/keepKeyOrder.mjs +67 -0
  55. package/src/plugins/mShare.mjs +3 -34
  56. package/dist/js/app-legacy.963e800c.js +0 -1
  57. package/dist/js/app.963e800c.js +0 -1
package/docs/global.html CHANGED
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WWebPerm.html">WWebPerm</a></li></ul><h3>Global</h3><ul><li><a href="global.html#createAuthorizeExec">createAuthorizeExec</a></li><li><a href="global.html#createLegendMeasurer">createLegendMeasurer</a></li><li><a href="global.html#createLockSave">createLockSave</a></li><li><a href="global.html#decideLegendType">decideLegendType</a></li><li><a href="global.html#describeUpstream">describeUpstream</a></li><li><a href="global.html#eachOwn">eachOwn</a></li><li><a href="global.html#fetchJson">fetchJson</a></li><li><a href="global.html#genLegend">genLegend</a></li><li><a href="global.html#getOwn">getOwn</a></li><li><a href="global.html#getRuleEnable">getRuleEnable</a></li><li><a href="global.html#maskQuery">maskQuery</a></li><li><a href="global.html#maskTok">maskTok</a></li><li><a href="global.html#maskUrl">maskUrl</a></li><li><a href="global.html#mergePickKeysOnly">mergePickKeysOnly</a></li><li><a href="global.html#resolveShellWorker">resolveShellWorker</a></li><li><a href="global.html#reuseDeletedIds">reuseDeletedIds</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#validateRowsBeforeWrite">validateRowsBeforeWrite</a></li><li><a href="global.html#wrapInjected">wrapInjected</a></li><li><a href="global.html#wrapOperOrm">wrapOperOrm</a></li></ul>
32
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="WWebPerm.html">WWebPerm</a></li></ul><h3>Global</h3><ul><li><a href="global.html#createAuthorizeExec">createAuthorizeExec</a></li><li><a href="global.html#createLegendMeasurer">createLegendMeasurer</a></li><li><a href="global.html#createLockSave">createLockSave</a></li><li><a href="global.html#cvKpToArr">cvKpToArr</a></li><li><a href="global.html#cvKpToObj">cvKpToObj</a></li><li><a href="global.html#decideLegendType">decideLegendType</a></li><li><a href="global.html#describeUpstream">describeUpstream</a></li><li><a href="global.html#eachOwn">eachOwn</a></li><li><a href="global.html#fetchJson">fetchJson</a></li><li><a href="global.html#fmtLossyMsg">fmtLossyMsg</a></li><li><a href="global.html#genLegend">genLegend</a></li><li><a href="global.html#getKeyOrderLost">getKeyOrderLost</a></li><li><a href="global.html#getKpLossy">getKpLossy</a></li><li><a href="global.html#getKpWriteLost">getKpWriteLost</a></li><li><a href="global.html#getOwn">getOwn</a></li><li><a href="global.html#getRuleEnable">getRuleEnable</a></li><li><a href="global.html#isAuthMode">isAuthMode</a></li><li><a href="global.html#joinNames">joinNames</a></li><li><a href="global.html#keepKeyOrder">keepKeyOrder</a></li><li><a href="global.html#keyOrderOf">keyOrderOf</a></li><li><a href="global.html#maskQuery">maskQuery</a></li><li><a href="global.html#maskTok">maskTok</a></li><li><a href="global.html#maskUrl">maskUrl</a></li><li><a href="global.html#mergePickKeysOnly">mergePickKeysOnly</a></li><li><a href="global.html#resolveShellWorker">resolveShellWorker</a></li><li><a href="global.html#reuseDeletedIds">reuseDeletedIds</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#validateRowsBeforeWrite">validateRowsBeforeWrite</a></li><li><a href="global.html#wrapInjected">wrapInjected</a></li><li><a href="global.html#wrapOperOrm">wrapOperOrm</a></li></ul>
33
33
 
34
34
  </nav>
35
35
 
@@ -661,7 +661,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
661
661
 
662
662
 
663
663
 
664
- <h4 class="name" id="decideLegendType"><span class="type-signature"></span>decideLegendType<span class="signature">(m)</span><span class="type-signature"> &rarr; {String}</span></h4>
664
+ <h4 class="name" id="cvKpToArr"><span class="type-signature"></span>cvKpToArr<span class="signature">(kp)</span><span class="type-signature"> &rarr; {Array}</span></h4>
665
665
 
666
666
 
667
667
 
@@ -671,13 +671,18 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
671
671
  <dl class="details">
672
672
 
673
673
  <dt class="tag-description">Description:</dt>
674
- <dd class="tag-description"><ul class="dummy"><li><p>依量測結果決定圖例類型</p></li></ul></dd>
674
+ <dd class="tag-description"><ul class="dummy"><li><p>解碼授權資料(JSON5.parse(cgrups/cpemis/crules) 之結果)為 [{ name, … }] 陣列, 伺服端權限評估(src/plugins/mShare.mjs 之 getUserRules)與編輯對話框(經 cvKpToObj)共用之唯一解碼</p>
675
+ <p>授權資料為使用者(含外部應用)寫入, 鍵為群組/權限/規則名, 一律以 eachOwn 依自有鍵走訪(規則帳本 R-OBJ-ITER-01):
676
+ lodash each 對含非負整數 length 鍵之物件改走索引 0..length-1, 真實鍵被略過(權限靜默評估為 n), length 極大時空轉或耗盡記憶體(每次 getPerm/getPermUserInfor 皆走此路徑).
677
+ eachOwn 對陣列依索引、對物件依自有鍵, 對字串與其他原始值不迭代.
678
+ 名稱: 物件形式(以名稱為鍵)以外層鍵為名, 值內 name 不得改名(編輯器依外層鍵顯示與存檔, 授權若依值內 name 則顯示與授權不一致; 規則帳本 R-AUTH-PATH-01);
679
+ 陣列形式([{ name, … }])元素之 name 即名稱(元素無 name 或非物件時名稱為索引數字, 不會對應任何群組/權限/規則名)</p></li></ul></dd>
675
680
 
676
681
 
677
682
 
678
683
  <dt class="tag-source">Source:</dt>
679
684
  <dd class="tag-source"><ul class="dummy"><li>
680
- <a href="src_js_legendFit.mjs.html">src/js/legendFit.mjs</a>, <a href="src_js_legendFit.mjs.html#line43">line 43</a>
685
+ <a href="src_js_cvKpToArr.mjs.html">src/js/cvKpToArr.mjs</a>, <a href="src_js_cvKpToArr.mjs.html#line24">line 24</a>
681
686
  </li></ul></dd>
682
687
 
683
688
 
@@ -722,6 +727,14 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
722
727
 
723
728
 
724
729
 
730
+ <h5 class="h5-examples">Example</h5>
731
+
732
+ <pre class="prettyprint"><code>console.log(cvKpToArr({ A: 'y', B: { mode: 'OR', isActive: 'y' } }))
733
+ // => [{ name: 'A', isActive: 'y' }, { name: 'B', mode: 'OR', isActive: 'y' }]
734
+ console.log(cvKpToArr([{ name: 'A', isActive: 'y' }]))
735
+ // => [{ name: 'A', isActive: 'y' }]</code></pre>
736
+
737
+
725
738
 
726
739
 
727
740
  <h5 class="h5-parameters">Parameters:</h5>
@@ -749,7 +762,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
749
762
 
750
763
  <tr>
751
764
 
752
- <td class="name"><code>m</code></td>
765
+ <td class="name"><code>kp</code></td>
753
766
 
754
767
 
755
768
  <td class="type">
@@ -758,7 +771,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
758
771
  <span class="param-type">Object</span>
759
772
  |
760
773
 
761
- <span class="param-type">null</span>
774
+ <span class="param-type">Array</span>
762
775
 
763
776
 
764
777
 
@@ -769,7 +782,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
769
782
 
770
783
 
771
784
 
772
- <td class="description last"><p>輸入量測結果物件{rows,bottom}, 量測失敗為null</p></td>
785
+ <td class="description last"><p>輸入 JSON5.parse(cgrups/cpemis/crules) 之結果, 物件形式 { 名稱: 值 } 或陣列形式 [{ name, … }]</p></td>
773
786
  </tr>
774
787
 
775
788
 
@@ -795,7 +808,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
795
808
 
796
809
 
797
810
  <div class="param-desc">
798
- <p>回傳'plain'或'scroll', 量測失敗回'scroll'(單列, 不會重疊)</p>
811
+ <p>回傳 [{ name, … }] 陣列; 值為物件(iseobj)時展開其欄位(如 mode、isActive), 否則以值為 isActive</p>
799
812
  </div>
800
813
 
801
814
 
@@ -806,7 +819,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
806
819
  </dt>
807
820
  <dd>
808
821
 
809
- <span class="param-type">String</span>
822
+ <span class="param-type">Array</span>
810
823
 
811
824
 
812
825
 
@@ -822,7 +835,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
822
835
 
823
836
 
824
837
 
825
- <h4 class="name" id="describeUpstream"><span class="type-signature"></span>describeUpstream<span class="signature">(err)</span><span class="type-signature"> &rarr; {Object}</span></h4>
838
+ <h4 class="name" id="cvKpToObj"><span class="type-signature"></span>cvKpToObj<span class="signature">(kp, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Object}</span></h4>
826
839
 
827
840
 
828
841
 
@@ -832,17 +845,30 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
832
845
  <dl class="details">
833
846
 
834
847
  <dt class="tag-description">Description:</dt>
835
- <dd class="tag-description"><ul class="dummy"><li><p>描述上游失敗, 供寫入 log: 絕不含上游原文</p>
848
+ <dd class="tag-description"><ul class="dummy"><li><p>授權資料(JSON5.parse(cgrups/cpemis/crules) 之結果)統一為以名稱為鍵之物件形式, 供編輯對話框依名稱查值(getOwn/getRuleEnable)</p>
849
+ <p>外部應用可直接寫入陣列形式 [{ &quot;name&quot;: &quot;A&quot;, &quot;isActive&quot;: &quot;y&quot; }], 伺服端 getUserRules 相容並授權(規則帳本 R-AUTH-DECODE-01);
850
+ 編輯對話框若依名稱為鍵查值會查不到陣列元素 → 顯示停用 → 管理者存檔即撤銷有效授權. 本函數與伺服端共用 cvKpToArr 之解碼(單一擁有者),
851
+ 並使「編輯器顯示啟用 ⇔ 該元素被伺服端採納(納入合併; 元素層級, 非最終權限樹)」.</p>
852
+ <p>存檔後授權不變(複審 R3/R4, 規則帳本 R-AUTH-ORDER-01/R-AUTH-LOSSY-01): 解碼後之鍵序即伺服端序, 編輯器以 keepKeyOrder 保留原鍵序後寫出;
853
+ 物件形式無法無損表示之格(同名有效 OR/AND 並存; 有效 AND 名稱 ≥ 2 且第一個 AND 名稱因整數式鍵先排而易位)由 getKpLossy 判定,
854
+ 編輯器對之拒存並顯示固定訊息(authLossyBlocked), 不寫出. 其餘格(含兩個以上 AND 群組)在保序下存檔前後授權相等(unit-cvKpToObj PR-001/PR-001b/PR-003/PR-004 窮舉).</p>
836
855
  <ul>
837
- <li>reject 值(字串)或其 message 屬白名單 key → { upstream: key }</li>
838
- <li>其餘 → { upstreamType, upstreamName }: 型別(null / array / typeof)與名稱形狀之 Error.name(無則 '')</li>
839
- </ul></li></ul></dd>
856
+ <li>opt.hasMode 為 false(預設, crules): 伺服端 mergeRules 以 kpRule[vv.name] = vv.isActive 收斂, 鍵經 JS 屬性鍵轉型(true → 'true'、['T1'] → 'T1'、非物件元素之索引 → '0'),
857
+ 同名後者覆蓋前者; 本函數以同一個指派式 o[r.name] = … 取得相同鍵與相同覆蓋順序(crules 之合併與順序無關, 無有損格).</li>
858
+ <li>opt.hasMode 為 true(cgrups/cpemis): 伺服端 arrFinder 以 === 比對名稱(非字串名稱不授權), 且 isActive 為 'y' 而 mode 非 OR/AND 者不納入合併(不授權).
859
+ 故僅名稱為非空字串者保留; isActive 為 'y' 而 mode 不合法者改為 'n'(顯示停用——否則存檔會補預設 OR 而把「不授權」變成「授權」); 同名重複者, 各「有效啟用元素」(isActive 'y' 且 mode 合法)
860
+ 模式一致時合為一個啟用項(與伺服端逐項合併等價: 同模式同規則之重複不改變結果); 無有效啟用元素時為 'n'; 同名 AND 與 OR 並存者(物件形式無法無損表示, 由 getKpLossy 判定並拒存)
861
+ 此處僅取 AND 支作為顯示值. 鍵序: 有效啟用元素首次出現之序在前(伺服端 AND 合併之第一個 AND 項依此序), 其後為無有效元素之名稱(首次出現之序);
862
+ 整數式名稱(如 '1')受 JS 屬性序影響恆排前面, 該格由 getKpLossy 判定.</li>
863
+ </ul>
864
+ <p>物件形式: 值為物件者去掉值內 name(外層鍵為名, 規則帳本 R-AUTH-PATH-01: 否則關聯對話框存檔會把授權改指到值內 name 所指之項目); hasMode 時另把 isActive 'y' 而 mode 不合法者改為 'n'.
865
+ 無需修改時原樣回傳(同一參考, 既有行為不變). 陣列形式一律回傳無原型物件(原型鍵名〔<strong>proto</strong>、constructor、toString〕可為一般鍵).</p></li></ul></dd>
840
866
 
841
867
 
842
868
 
843
869
  <dt class="tag-source">Source:</dt>
844
870
  <dd class="tag-source"><ul class="dummy"><li>
845
- <a href="server_wrapInjected.mjs.html">server/wrapInjected.mjs</a>, <a href="server_wrapInjected.mjs.html#line45">line 45</a>
871
+ <a href="src_js_cvKpToObj.mjs.html">src/js/cvKpToObj.mjs</a>, <a href="src_js_cvKpToObj.mjs.html#line43">line 43</a>
846
872
  </li></ul></dd>
847
873
 
848
874
 
@@ -887,6 +913,15 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
887
913
 
888
914
 
889
915
 
916
+ <h5 class="h5-examples">Example</h5>
917
+
918
+ <pre class="prettyprint"><code>let kp = cvKpToObj([{ name: 'A', mode: 'OR', isActive: 'y' }], { hasMode: true })
919
+ console.log(kp.A)
920
+ // => { mode: 'OR', isActive: 'y' }
921
+ console.log(cvKpToObj([{ name: 'A', isActive: 'y' }], { hasMode: true }).A)
922
+ // => { isActive: 'n' } (缺 mode: 伺服端不授權)</code></pre>
923
+
924
+
890
925
 
891
926
 
892
927
  <h5 class="h5-parameters">Parameters:</h5>
@@ -902,8 +937,12 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
902
937
  <th>Type</th>
903
938
 
904
939
 
940
+ <th>Attributes</th>
941
+
905
942
 
906
943
 
944
+ <th>Default</th>
945
+
907
946
 
908
947
  <th class="last">Description</th>
909
948
  </tr>
@@ -914,13 +953,16 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
914
953
 
915
954
  <tr>
916
955
 
917
- <td class="name"><code>err</code></td>
956
+ <td class="name"><code>kp</code></td>
918
957
 
919
958
 
920
959
  <td class="type">
921
960
 
922
961
 
923
- <span class="param-type">*</span>
962
+ <span class="param-type">Object</span>
963
+ |
964
+
965
+ <span class="param-type">Array</span>
924
966
 
925
967
 
926
968
 
@@ -928,10 +970,132 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
928
970
  </td>
929
971
 
930
972
 
973
+ <td class="attributes">
974
+
975
+
976
+
931
977
 
978
+
979
+ </td>
932
980
 
933
981
 
934
- <td class="description last"><p>輸入注入函數拋出或 reject 之值</p></td>
982
+
983
+ <td class="default">
984
+
985
+ </td>
986
+
987
+
988
+ <td class="description last"><p>輸入 JSON5.parse(cgrups/cpemis/crules) 之結果</p></td>
989
+ </tr>
990
+
991
+
992
+
993
+ <tr>
994
+
995
+ <td class="name"><code>opt</code></td>
996
+
997
+
998
+ <td class="type">
999
+
1000
+
1001
+ <span class="param-type">Object</span>
1002
+
1003
+
1004
+
1005
+
1006
+ </td>
1007
+
1008
+
1009
+ <td class="attributes">
1010
+
1011
+ &lt;optional><br>
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+ </td>
1018
+
1019
+
1020
+
1021
+ <td class="default">
1022
+
1023
+ <code>{}</code>
1024
+
1025
+ </td>
1026
+
1027
+
1028
+ <td class="description last"><p>輸入設定物件</p>
1029
+ <h6>Properties</h6>
1030
+
1031
+
1032
+ <table class="params">
1033
+ <thead>
1034
+ <tr>
1035
+
1036
+ <th>Name</th>
1037
+
1038
+
1039
+ <th>Type</th>
1040
+
1041
+
1042
+ <th>Attributes</th>
1043
+
1044
+
1045
+
1046
+ <th>Default</th>
1047
+
1048
+
1049
+ <th class="last">Description</th>
1050
+ </tr>
1051
+ </thead>
1052
+
1053
+ <tbody>
1054
+
1055
+
1056
+ <tr>
1057
+
1058
+ <td class="name"><code>hasMode</code></td>
1059
+
1060
+
1061
+ <td class="type">
1062
+
1063
+
1064
+ <span class="param-type">Boolean</span>
1065
+
1066
+
1067
+
1068
+
1069
+ </td>
1070
+
1071
+
1072
+ <td class="attributes">
1073
+
1074
+ &lt;optional><br>
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+ </td>
1081
+
1082
+
1083
+
1084
+ <td class="default">
1085
+
1086
+ <code>false</code>
1087
+
1088
+ </td>
1089
+
1090
+
1091
+ <td class="description last"><p>輸入是否為帶 mode 之資料(cgrups/cpemis 為 true, crules 為 false), 預設false</p></td>
1092
+ </tr>
1093
+
1094
+
1095
+ </tbody>
1096
+ </table>
1097
+
1098
+ </td>
935
1099
  </tr>
936
1100
 
937
1101
 
@@ -957,7 +1121,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
957
1121
 
958
1122
 
959
1123
  <div class="param-desc">
960
- <p>回傳描述物件</p>
1124
+ <p>回傳以名稱為鍵之物件; 輸入非物件且非陣列時原樣回傳</p>
961
1125
  </div>
962
1126
 
963
1127
 
@@ -984,7 +1148,7 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
984
1148
 
985
1149
 
986
1150
 
987
- <h4 class="name" id="eachOwn"><span class="type-signature"></span>eachOwn<span class="signature">(o, fn)</span><span class="type-signature"> &rarr; {Array|Object}</span></h4>
1151
+ <h4 class="name" id="decideLegendType"><span class="type-signature"></span>decideLegendType<span class="signature">(m)</span><span class="type-signature"> &rarr; {String}</span></h4>
988
1152
 
989
1153
 
990
1154
 
@@ -994,16 +1158,13 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
994
1158
  <dl class="details">
995
1159
 
996
1160
  <dt class="tag-description">Description:</dt>
997
- <dd class="tag-description"><ul class="dummy"><li><p>迭代陣列或物件, 物件只依自有可列舉字串鍵(lodash each 對具非負整數 length 鍵之物件會改走索引 0..length-1, 真實鍵被略過且迭代次數即 length 之值)</p>
998
- <p>真陣列(Array.isArray, 不用依 Object.prototype.toString 之 isarr: 可被 Symbol.toStringTag 偽稱)依索引由小到大迭代, 空洞以 undefined 迭代, 長度於開始時取一次, 同 lodash each;
999
- 一般物件依 Object.keys 之順序迭代, length 與其他鍵同為一般鍵, 成本只依實際鍵數, 與 length 之值無關;
1000
- 其餘(null、undefined、字串、數字、布林、函數、Symbol)不迭代, 原樣回傳(lodash each 對字串會逐字元迭代, 本函數不做)</p></li></ul></dd>
1161
+ <dd class="tag-description"><ul class="dummy"><li><p>依量測結果決定圖例類型</p></li></ul></dd>
1001
1162
 
1002
1163
 
1003
1164
 
1004
1165
  <dt class="tag-source">Source:</dt>
1005
1166
  <dd class="tag-source"><ul class="dummy"><li>
1006
- <a href="src_js_eachOwn.mjs.html">src/js/eachOwn.mjs</a>, <a href="src_js_eachOwn.mjs.html#line26">line 26</a>
1167
+ <a href="src_js_legendFit.mjs.html">src/js/legendFit.mjs</a>, <a href="src_js_legendFit.mjs.html#line43">line 43</a>
1007
1168
  </li></ul></dd>
1008
1169
 
1009
1170
 
@@ -1048,14 +1209,1943 @@ operatorId 可為操作者 id 或「操作者 id + 列識別」(只擋同一列
1048
1209
 
1049
1210
 
1050
1211
 
1051
- <h5 class="h5-examples">Example</h5>
1052
-
1053
- <pre class="prettyprint"><code>let ks = []
1054
- eachOwn({ id: 'a', length: 1, name: 'x' }, (v, k) => {
1055
- ks.push(k)
1056
- })
1057
- console.log(ks)
1058
- // => ['id', 'length', 'name']</code></pre>
1212
+
1213
+
1214
+ <h5 class="h5-parameters">Parameters:</h5>
1215
+
1216
+
1217
+ <table class="params">
1218
+ <thead>
1219
+ <tr>
1220
+
1221
+ <th>Name</th>
1222
+
1223
+
1224
+ <th>Type</th>
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+ <th class="last">Description</th>
1231
+ </tr>
1232
+ </thead>
1233
+
1234
+ <tbody>
1235
+
1236
+
1237
+ <tr>
1238
+
1239
+ <td class="name"><code>m</code></td>
1240
+
1241
+
1242
+ <td class="type">
1243
+
1244
+
1245
+ <span class="param-type">Object</span>
1246
+ |
1247
+
1248
+ <span class="param-type">null</span>
1249
+
1250
+
1251
+
1252
+
1253
+ </td>
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+ <td class="description last"><p>輸入量測結果物件{rows,bottom}, 量測失敗為null</p></td>
1260
+ </tr>
1261
+
1262
+
1263
+ </tbody>
1264
+ </table>
1265
+
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+ <h5 class="h5-returns">Returns:</h5>
1282
+
1283
+
1284
+ <div class="param-desc">
1285
+ <p>回傳'plain'或'scroll', 量測失敗回'scroll'(單列, 不會重疊)</p>
1286
+ </div>
1287
+
1288
+
1289
+
1290
+ <dl class="param-type">
1291
+ <dt>
1292
+ Type
1293
+ </dt>
1294
+ <dd>
1295
+
1296
+ <span class="param-type">String</span>
1297
+
1298
+
1299
+
1300
+ </dd>
1301
+ </dl>
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+ <h4 class="name" id="describeUpstream"><span class="type-signature"></span>describeUpstream<span class="signature">(err)</span><span class="type-signature"> &rarr; {Object}</span></h4>
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+ <dl class="details">
1320
+
1321
+ <dt class="tag-description">Description:</dt>
1322
+ <dd class="tag-description"><ul class="dummy"><li><p>描述上游失敗, 供寫入 log: 絕不含上游原文</p>
1323
+ <ul>
1324
+ <li>reject 值(字串)或其 message 屬白名單 key → { upstream: key }</li>
1325
+ <li>其餘 → { upstreamType, upstreamName }: 型別(null / array / typeof)與名稱形狀之 Error.name(無則 '')</li>
1326
+ </ul></li></ul></dd>
1327
+
1328
+
1329
+
1330
+ <dt class="tag-source">Source:</dt>
1331
+ <dd class="tag-source"><ul class="dummy"><li>
1332
+ <a href="server_wrapInjected.mjs.html">server/wrapInjected.mjs</a>, <a href="server_wrapInjected.mjs.html#line45">line 45</a>
1333
+ </li></ul></dd>
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+ </dl>
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+ <h5 class="h5-parameters">Parameters:</h5>
1380
+
1381
+
1382
+ <table class="params">
1383
+ <thead>
1384
+ <tr>
1385
+
1386
+ <th>Name</th>
1387
+
1388
+
1389
+ <th>Type</th>
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+ <th class="last">Description</th>
1396
+ </tr>
1397
+ </thead>
1398
+
1399
+ <tbody>
1400
+
1401
+
1402
+ <tr>
1403
+
1404
+ <td class="name"><code>err</code></td>
1405
+
1406
+
1407
+ <td class="type">
1408
+
1409
+
1410
+ <span class="param-type">*</span>
1411
+
1412
+
1413
+
1414
+
1415
+ </td>
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+ <td class="description last"><p>輸入注入函數拋出或 reject 之值</p></td>
1422
+ </tr>
1423
+
1424
+
1425
+ </tbody>
1426
+ </table>
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+ <h5 class="h5-returns">Returns:</h5>
1444
+
1445
+
1446
+ <div class="param-desc">
1447
+ <p>回傳描述物件</p>
1448
+ </div>
1449
+
1450
+
1451
+
1452
+ <dl class="param-type">
1453
+ <dt>
1454
+ Type
1455
+ </dt>
1456
+ <dd>
1457
+
1458
+ <span class="param-type">Object</span>
1459
+
1460
+
1461
+
1462
+ </dd>
1463
+ </dl>
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+ <h4 class="name" id="eachOwn"><span class="type-signature"></span>eachOwn<span class="signature">(o, fn)</span><span class="type-signature"> &rarr; {Array|Object}</span></h4>
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+ <dl class="details">
1482
+
1483
+ <dt class="tag-description">Description:</dt>
1484
+ <dd class="tag-description"><ul class="dummy"><li><p>迭代陣列或物件, 物件只依自有可列舉字串鍵(lodash each 對具非負整數 length 鍵之物件會改走索引 0..length-1, 真實鍵被略過且迭代次數即 length 之值)</p>
1485
+ <p>真陣列(Array.isArray, 不用依 Object.prototype.toString 之 isarr: 可被 Symbol.toStringTag 偽稱)依索引由小到大迭代, 空洞以 undefined 迭代, 長度於開始時取一次, 同 lodash each;
1486
+ 一般物件依 Object.keys 之順序迭代, length 與其他鍵同為一般鍵, 成本只依實際鍵數, 與 length 之值無關;
1487
+ 其餘(null、undefined、字串、數字、布林、函數、Symbol)不迭代, 原樣回傳(lodash each 對字串會逐字元迭代, 本函數不做)</p></li></ul></dd>
1488
+
1489
+
1490
+
1491
+ <dt class="tag-source">Source:</dt>
1492
+ <dd class="tag-source"><ul class="dummy"><li>
1493
+ <a href="src_js_eachOwn.mjs.html">src/js/eachOwn.mjs</a>, <a href="src_js_eachOwn.mjs.html#line26">line 26</a>
1494
+ </li></ul></dd>
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+ </dl>
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+ <h5 class="h5-examples">Example</h5>
1539
+
1540
+ <pre class="prettyprint"><code>let ks = []
1541
+ eachOwn({ id: 'a', length: 1, name: 'x' }, (v, k) => {
1542
+ ks.push(k)
1543
+ })
1544
+ console.log(ks)
1545
+ // => ['id', 'length', 'name']</code></pre>
1546
+
1547
+
1548
+
1549
+
1550
+ <h5 class="h5-parameters">Parameters:</h5>
1551
+
1552
+
1553
+ <table class="params">
1554
+ <thead>
1555
+ <tr>
1556
+
1557
+ <th>Name</th>
1558
+
1559
+
1560
+ <th>Type</th>
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+ <th class="last">Description</th>
1567
+ </tr>
1568
+ </thead>
1569
+
1570
+ <tbody>
1571
+
1572
+
1573
+ <tr>
1574
+
1575
+ <td class="name"><code>o</code></td>
1576
+
1577
+
1578
+ <td class="type">
1579
+
1580
+
1581
+ <span class="param-type">Array</span>
1582
+ |
1583
+
1584
+ <span class="param-type">Object</span>
1585
+
1586
+
1587
+
1588
+
1589
+ </td>
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+ <td class="description last"><p>輸入陣列或物件</p></td>
1596
+ </tr>
1597
+
1598
+
1599
+
1600
+ <tr>
1601
+
1602
+ <td class="name"><code>fn</code></td>
1603
+
1604
+
1605
+ <td class="type">
1606
+
1607
+
1608
+ <span class="param-type">function</span>
1609
+
1610
+
1611
+
1612
+
1613
+ </td>
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+ <td class="description last"><p>輸入回呼函數(值, 鍵或索引, 原輸入), 回傳false時跳出, 其他回傳值(含undefined、true)皆繼續</p></td>
1620
+ </tr>
1621
+
1622
+
1623
+ </tbody>
1624
+ </table>
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+ <h5 class="h5-returns">Returns:</h5>
1642
+
1643
+
1644
+ <div class="param-desc">
1645
+ <p>回傳原輸入</p>
1646
+ </div>
1647
+
1648
+
1649
+
1650
+ <dl class="param-type">
1651
+ <dt>
1652
+ Type
1653
+ </dt>
1654
+ <dd>
1655
+
1656
+ <span class="param-type">Array</span>
1657
+ |
1658
+
1659
+ <span class="param-type">Object</span>
1660
+
1661
+
1662
+
1663
+ </dd>
1664
+ </dl>
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+ <h4 class="name" id="fetchJson"><span class="type-signature type-signature-async">(async) </span>fetchJson<span class="signature">(url, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
1676
+
1677
+
1678
+
1679
+
1680
+
1681
+
1682
+ <dl class="details">
1683
+
1684
+ <dt class="tag-description">Description:</dt>
1685
+ <dd class="tag-description"><ul class="dummy"><li><p>以瀏覽器與 node(18+) 內建之 fetch 取得 JSON 回應, 取代 axios(2026-09-07 起本套件不再依賴 axios)</p>
1686
+ <p>與 axios 之語意對齊:</p>
1687
+ <ul>
1688
+ <li>網路錯誤或非 2xx: axios 會 reject, fetch 只在網路錯誤 reject, 故此處對 !res.ok 亦 reject, 統一為 { kind: 'request', status, message }</li>
1689
+ <li>回應非 JSON: axios 回原字串(呼叫端判 state 失敗), 此處 res.json() 失敗 reject { kind: 'parse', status, message }</li>
1690
+ <li>成功: resolve 解析後之 JSON(對應 axios 之 res.data)
1691
+ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'SyntaxError')或 'HTTP <status>', 不含網址與回應本體(網址常帶權杖)
1692
+ 注意: node 端 fetch(undici) 不讀 HTTP_PROXY / HTTPS_PROXY 環境變數(axios 會), 需走 proxy 之部署須自行以 opt.dispatcher 注入 undici Agent</li>
1693
+ </ul></li></ul></dd>
1694
+
1695
+
1696
+
1697
+ <dt class="tag-source">Source:</dt>
1698
+ <dd class="tag-source"><ul class="dummy"><li>
1699
+ <a href="src_fetchJson.mjs.html">src/fetchJson.mjs</a>, <a href="src_fetchJson.mjs.html#line40">line 40</a>
1700
+ </li></ul></dd>
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+
1731
+
1732
+ </dl>
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+ <h5 class="h5-parameters">Parameters:</h5>
1747
+
1748
+
1749
+ <table class="params">
1750
+ <thead>
1751
+ <tr>
1752
+
1753
+ <th>Name</th>
1754
+
1755
+
1756
+ <th>Type</th>
1757
+
1758
+
1759
+ <th>Attributes</th>
1760
+
1761
+
1762
+
1763
+ <th>Default</th>
1764
+
1765
+
1766
+ <th class="last">Description</th>
1767
+ </tr>
1768
+ </thead>
1769
+
1770
+ <tbody>
1771
+
1772
+
1773
+ <tr>
1774
+
1775
+ <td class="name"><code>url</code></td>
1776
+
1777
+
1778
+ <td class="type">
1779
+
1780
+
1781
+ <span class="param-type">String</span>
1782
+
1783
+
1784
+
1785
+
1786
+ </td>
1787
+
1788
+
1789
+ <td class="attributes">
1790
+
1791
+
1792
+
1793
+
1794
+
1795
+ </td>
1796
+
1797
+
1798
+
1799
+ <td class="default">
1800
+
1801
+ </td>
1802
+
1803
+
1804
+ <td class="description last"><p>輸入請求網址字串</p></td>
1805
+ </tr>
1806
+
1807
+
1808
+
1809
+ <tr>
1810
+
1811
+ <td class="name"><code>opt</code></td>
1812
+
1813
+
1814
+ <td class="type">
1815
+
1816
+
1817
+ <span class="param-type">Object</span>
1818
+
1819
+
1820
+
1821
+
1822
+ </td>
1823
+
1824
+
1825
+ <td class="attributes">
1826
+
1827
+ &lt;optional><br>
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+ </td>
1834
+
1835
+
1836
+
1837
+ <td class="default">
1838
+
1839
+ <code>{}</code>
1840
+
1841
+ </td>
1842
+
1843
+
1844
+ <td class="description last"><p>輸入 fetch 選項物件(method / headers / body / signal / dispatcher 等原樣傳給 fetch), 預設 {}</p></td>
1845
+ </tr>
1846
+
1847
+
1848
+ </tbody>
1849
+ </table>
1850
+
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+ <h5 class="h5-returns">Returns:</h5>
1867
+
1868
+
1869
+ <div class="param-desc">
1870
+ <p>回傳 Promise, resolve 為 JSON 物件, reject 為 { kind: 'request'|'parse', status, message }</p>
1871
+ </div>
1872
+
1873
+
1874
+
1875
+ <dl class="param-type">
1876
+ <dt>
1877
+ Type
1878
+ </dt>
1879
+ <dd>
1880
+
1881
+ <span class="param-type">Promise</span>
1882
+
1883
+
1884
+
1885
+ </dd>
1886
+ </dl>
1887
+
1888
+
1889
+
1890
+
1891
+
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+ <h4 class="name" id="fmtLossyMsg"><span class="type-signature"></span>fmtLossyMsg<span class="signature">(tpl, names)</span><span class="type-signature"> &rarr; {String}</span></h4>
1898
+
1899
+
1900
+
1901
+
1902
+
1903
+
1904
+ <dl class="details">
1905
+
1906
+ <dt class="tag-description">Description:</dt>
1907
+ <dd class="tag-description"><ul class="dummy"><li><p>把拒存訊息範本(authLossyBlocked)之 {names} 代入受影響之名稱</p>
1908
+ <p>名稱為使用者/外部應用寫入之資料, 可含 $&amp;、$$、$' 等字樣; 以 split/join 代入(不用 String.replace, 其替換字串中的 $ 樣式會被展開), 名稱原樣顯示.</p></li></ul></dd>
1909
+
1910
+
1911
+
1912
+ <dt class="tag-source">Source:</dt>
1913
+ <dd class="tag-source"><ul class="dummy"><li>
1914
+ <a href="src_js_fmtLossyMsg.mjs.html">src/js/fmtLossyMsg.mjs</a>, <a href="src_js_fmtLossyMsg.mjs.html#line18">line 18</a>
1915
+ </li></ul></dd>
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+
1938
+
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+ </dl>
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+ <h5 class="h5-examples">Example</h5>
1960
+
1961
+ <pre class="prettyprint"><code>console.log(fmtLossyMsg('Not saved: {names}', ['a', '$&amp;']))
1962
+ // => 'Not saved: a, $&amp;'</code></pre>
1963
+
1964
+
1965
+
1966
+
1967
+ <h5 class="h5-parameters">Parameters:</h5>
1968
+
1969
+
1970
+ <table class="params">
1971
+ <thead>
1972
+ <tr>
1973
+
1974
+ <th>Name</th>
1975
+
1976
+
1977
+ <th>Type</th>
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+ <th class="last">Description</th>
1984
+ </tr>
1985
+ </thead>
1986
+
1987
+ <tbody>
1988
+
1989
+
1990
+ <tr>
1991
+
1992
+ <td class="name"><code>tpl</code></td>
1993
+
1994
+
1995
+ <td class="type">
1996
+
1997
+
1998
+ <span class="param-type">String</span>
1999
+
2000
+
2001
+
2002
+
2003
+ </td>
2004
+
2005
+
2006
+
2007
+
2008
+
2009
+ <td class="description last"><p>輸入訊息範本, 含 {names}</p></td>
2010
+ </tr>
2011
+
2012
+
2013
+
2014
+ <tr>
2015
+
2016
+ <td class="name"><code>names</code></td>
2017
+
2018
+
2019
+ <td class="type">
2020
+
2021
+
2022
+ <span class="param-type">Array</span>
2023
+
2024
+
2025
+
2026
+
2027
+ </td>
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+ <td class="description last"><p>輸入受影響之名稱陣列(至多列出 5 個, 超過加省略號, 見 joinNames)</p></td>
2034
+ </tr>
2035
+
2036
+
2037
+ </tbody>
2038
+ </table>
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+
2049
+
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+ <h5 class="h5-returns">Returns:</h5>
2056
+
2057
+
2058
+ <div class="param-desc">
2059
+ <p>回傳代入後之訊息</p>
2060
+ </div>
2061
+
2062
+
2063
+
2064
+ <dl class="param-type">
2065
+ <dt>
2066
+ Type
2067
+ </dt>
2068
+ <dd>
2069
+
2070
+ <span class="param-type">String</span>
2071
+
2072
+
2073
+
2074
+ </dd>
2075
+ </dl>
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+ <h4 class="name" id="genLegend"><span class="type-signature"></span>genLegend<span class="signature">(type<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Object}</span></h4>
2087
+
2088
+
2089
+
2090
+
2091
+
2092
+
2093
+ <dl class="details">
2094
+
2095
+ <dt class="tag-description">Description:</dt>
2096
+ <dd class="tag-description"><ul class="dummy"><li><p>產生圖例設定(單一來源), genOpt 與執行期切換類型共用</p>
2097
+ <p>切換類型(plain↔scroll)時 echarts 以新傳入之選項重建圖例模型(Global.js:322-344), 未帶之設定一律回到預設, 故每次都須帶齊</p></li></ul></dd>
2098
+
2099
+
2100
+
2101
+ <dt class="tag-source">Source:</dt>
2102
+ <dd class="tag-source"><ul class="dummy"><li>
2103
+ <a href="src_js_legendFit.mjs.html">src/js/legendFit.mjs</a>, <a href="src_js_legendFit.mjs.html#line24">line 24</a>
2104
+ </li></ul></dd>
2105
+
2106
+
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+
2119
+
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+ </dl>
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+ <h5 class="h5-parameters">Parameters:</h5>
2151
+
2152
+
2153
+ <table class="params">
2154
+ <thead>
2155
+ <tr>
2156
+
2157
+ <th>Name</th>
2158
+
2159
+
2160
+ <th>Type</th>
2161
+
2162
+
2163
+ <th>Attributes</th>
2164
+
2165
+
2166
+
2167
+ <th>Default</th>
2168
+
2169
+
2170
+ <th class="last">Description</th>
2171
+ </tr>
2172
+ </thead>
2173
+
2174
+ <tbody>
2175
+
2176
+
2177
+ <tr>
2178
+
2179
+ <td class="name"><code>type</code></td>
2180
+
2181
+
2182
+ <td class="type">
2183
+
2184
+
2185
+ <span class="param-type">String</span>
2186
+
2187
+
2188
+
2189
+
2190
+ </td>
2191
+
2192
+
2193
+ <td class="attributes">
2194
+
2195
+ &lt;optional><br>
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+ </td>
2202
+
2203
+
2204
+
2205
+ <td class="default">
2206
+
2207
+ <code>'plain'</code>
2208
+
2209
+ </td>
2210
+
2211
+
2212
+ <td class="description last"><p>輸入圖例類型字串, 'plain'或'scroll', 預設'plain'</p></td>
2213
+ </tr>
2214
+
2215
+
2216
+ </tbody>
2217
+ </table>
2218
+
2219
+
2220
+
2221
+
2222
+
2223
+
2224
+
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+
2234
+ <h5 class="h5-returns">Returns:</h5>
2235
+
2236
+
2237
+ <div class="param-desc">
2238
+ <p>回傳echarts之legend設定物件</p>
2239
+ </div>
2240
+
2241
+
2242
+
2243
+ <dl class="param-type">
2244
+ <dt>
2245
+ Type
2246
+ </dt>
2247
+ <dd>
2248
+
2249
+ <span class="param-type">Object</span>
2250
+
2251
+
2252
+
2253
+ </dd>
2254
+ </dl>
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+ <h4 class="name" id="getKeyOrderLost"><span class="type-signature"></span>getKeyOrderLost<span class="signature">(kpOut, seq)</span><span class="type-signature"> &rarr; {Array}</span></h4>
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+ <dl class="details">
2273
+
2274
+ <dt class="tag-description">Description:</dt>
2275
+ <dd class="tag-description"><ul class="dummy"><li><p>判定欲寫出之物件 kpOut 的鍵序(JS 屬性序: 整數式鍵先排、遞增)是否與預期序 seq 不同, 使有效 AND 名稱之相對順序易位, 回傳受影響之 AND 名稱</p>
2276
+ <p>編輯器以 keepKeyOrder 讓「原字串已有之名稱維持原序、新增者附加於後」, 但 JS 物件的整數式鍵(如群組名 '1')恆排在前面,
2277
+ 新增(或新啟用)的整數式 AND 名稱會排到既有 AND 名稱之前, 使伺服端 mergeRules 在沒有有效 OR 項時的「第一個 AND 項」易位而改變授權(規則帳本 R-AUTH-LOSSY-01);
2278
+ 此為編輯器無法在不改變授權下寫出的格, 須拒存並顯示固定訊息(authLossyBlocked).
2279
+ 只看有效 AND 項(isActive 'y' 且 mode 'AND')之「第一個」是否易位: 欲寫出之物件只含現存之群組/權限(編輯器列出之列, 無查無實體之名稱被丟棄的問題),
2280
+ mergeRules 的結果對 AND 項順序的依賴只經第一個 AND 項(其餘 AND 項彼此可交換), 故第一個不變則其後之相對順序改變不影響授權, 不需拒存(輸入側 getKpLossy 因幻影名稱須比整個相對順序, 見其說明).</p></li></ul></dd>
2281
+
2282
+
2283
+
2284
+ <dt class="tag-source">Source:</dt>
2285
+ <dd class="tag-source"><ul class="dummy"><li>
2286
+ <a href="src_js_getKeyOrderLost.mjs.html">src/js/getKeyOrderLost.mjs</a>, <a href="src_js_getKeyOrderLost.mjs.html#line24">line 24</a>
2287
+ </li></ul></dd>
2288
+
2289
+
2290
+
2291
+
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+
2299
+
2300
+
2301
+
2302
+
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+
2309
+
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+ </dl>
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+ <h5 class="h5-examples">Example</h5>
2332
+
2333
+ <pre class="prettyprint"><code>let seq = ['A', '1']
2334
+ let kpOut = { '1': { mode: 'AND', isActive: 'y' }, A: { mode: 'AND', isActive: 'y' } } //JS 把 '1' 排到 A 前面
2335
+ console.log(getKeyOrderLost(kpOut, seq))
2336
+ // => ['A', '1']</code></pre>
2337
+
2338
+
2339
+
2340
+
2341
+ <h5 class="h5-parameters">Parameters:</h5>
2342
+
2343
+
2344
+ <table class="params">
2345
+ <thead>
2346
+ <tr>
2347
+
2348
+ <th>Name</th>
2349
+
2350
+
2351
+ <th>Type</th>
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+ <th class="last">Description</th>
2358
+ </tr>
2359
+ </thead>
2360
+
2361
+ <tbody>
2362
+
2363
+
2364
+ <tr>
2365
+
2366
+ <td class="name"><code>kpOut</code></td>
2367
+
2368
+
2369
+ <td class="type">
2370
+
2371
+
2372
+ <span class="param-type">Object</span>
2373
+
2374
+
2375
+
2376
+
2377
+ </td>
2378
+
2379
+
2380
+
2381
+
2382
+
2383
+ <td class="description last"><p>輸入欲寫出之物件 { 名稱: { mode, isActive } }</p></td>
2384
+ </tr>
2385
+
2386
+
2387
+
2388
+ <tr>
2389
+
2390
+ <td class="name"><code>seq</code></td>
2391
+
2392
+
2393
+ <td class="type">
2394
+
2395
+
2396
+ <span class="param-type">Array</span>
2397
+
2398
+
2399
+
2400
+
2401
+ </td>
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+ <td class="description last"><p>輸入預期的名稱順序(keepKeyOrder 之 keyOrderOf 結果)</p></td>
2408
+ </tr>
2409
+
2410
+
2411
+ </tbody>
2412
+ </table>
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+
2423
+
2424
+
2425
+
2426
+
2427
+
2428
+
2429
+ <h5 class="h5-returns">Returns:</h5>
2430
+
2431
+
2432
+ <div class="param-desc">
2433
+ <p>回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入</p>
2434
+ </div>
2435
+
2436
+
2437
+
2438
+ <dl class="param-type">
2439
+ <dt>
2440
+ Type
2441
+ </dt>
2442
+ <dd>
2443
+
2444
+ <span class="param-type">Array</span>
2445
+
2446
+
2447
+
2448
+ </dd>
2449
+ </dl>
2450
+
2451
+
2452
+
2453
+
2454
+
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+ <h4 class="name" id="getKpLossy"><span class="type-signature"></span>getKpLossy<span class="signature">(kp)</span><span class="type-signature"> &rarr; {Array}</span></h4>
2461
+
2462
+
2463
+
2464
+
2465
+
2466
+
2467
+ <dl class="details">
2468
+
2469
+ <dt class="tag-description">Description:</dt>
2470
+ <dd class="tag-description"><ul class="dummy"><li><p>判定帶 mode 之授權資料(JSON5.parse(cgrups/cpemis) 之結果)是否含「編輯器無法以物件形式無損表示」之格, 回傳受影響之名稱</p>
2471
+ <p>編輯器存檔一律寫物件形式 { 名稱: { mode, isActive } }(每個名稱只有一個 mode、鍵序為 JS 屬性序); 外部應用可直接寫入陣列形式, 其下列兩格物件形式無法無損表示,
2472
+ 硬寫即靜默改變授權(規則帳本 R-AUTH-LOSSY-01; 複審 R4), 編輯器須拒存並顯示固定訊息(authLossyBlocked), 庫內字串不動:</p>
2473
+ <ol>
2474
+ <li>同名有效啟用元素同時為 OR 與 AND: 物件形式只能留一個 mode. 保留 AND 支者, 另有其他 AND 名稱時 AND 合併之起始值由 OR 聯集改為第一個 AND 項而增權(外審 sol 第三輪#2);
2475
+ 保留 OR 支或停用者亦會減權或增權, 一律視為有損(此格若整組只有該名稱則碰巧相等, 仍從嚴判定).</li>
2476
+ <li>有效 AND 名稱 ≥ 2 且其相對順序於伺服端序(陣列元素首次有效出現之序)與物件鍵序(整數式鍵先、遞增)不同:
2477
+ mergeRules 在沒有有效 OR 項時以第一個 AND 項為 AND 合併之起始, 結果因之而異; 整數式名稱(如群組名 '1')在物件形式中恆排在前面, 陣列形式之順序無法保留.
2478
+ 須比整個相對順序而非只比第一個: 查無實體(群組/權限表內沒有)之名稱會被伺服端 arrFinder 丟棄、編輯器存檔時亦不寫出, 丟棄後實際的第一個 AND 項可能是其後任一名稱(外審 sol#1/minimax#1).
2479
+ 有效啟用元素: 名稱為非空字串、isActive 為 'y'、mode 為 OR/AND(同伺服端 arrFinder 以 === 比對名稱、mergeRules 跳過非 OR/AND 者).
2480
+ 物件形式(編輯器自己寫出之形式、鍵唯一、鍵序即伺服端序)與其他輸入恆可無損表示, 回傳空陣列. 以原函式 getUserRules 為真理之窮舉驗證見 unit-cvKpToObj PR-001/PR-001b/PR-003
2481
+ (凡存檔前後授權不相等者皆被本函數判定, 漏判 0; 本函數為保守側, 某些整體授權碰巧相等之格仍判有損).</li>
2482
+ </ol></li></ul></dd>
2483
+
2484
+
2485
+
2486
+ <dt class="tag-source">Source:</dt>
2487
+ <dd class="tag-source"><ul class="dummy"><li>
2488
+ <a href="src_js_getKpLossy.mjs.html">src/js/getKpLossy.mjs</a>, <a href="src_js_getKpLossy.mjs.html#line31">line 31</a>
2489
+ </li></ul></dd>
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+ </dl>
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+ <h5 class="h5-examples">Example</h5>
2534
+
2535
+ <pre class="prettyprint"><code>console.log(getKpLossy([{ name: 'G1', mode: 'OR', isActive: 'y' }, { name: 'G1', mode: 'AND', isActive: 'y' }]))
2536
+ // => ['G1']
2537
+ console.log(getKpLossy({ G1: { mode: 'OR', isActive: 'y' } }))
2538
+ // => []</code></pre>
2539
+
2540
+
2541
+
2542
+
2543
+ <h5 class="h5-parameters">Parameters:</h5>
2544
+
2545
+
2546
+ <table class="params">
2547
+ <thead>
2548
+ <tr>
2549
+
2550
+ <th>Name</th>
2551
+
2552
+
2553
+ <th>Type</th>
2554
+
2555
+
2556
+
2557
+
2558
+
2559
+ <th class="last">Description</th>
2560
+ </tr>
2561
+ </thead>
2562
+
2563
+ <tbody>
2564
+
2565
+
2566
+ <tr>
2567
+
2568
+ <td class="name"><code>kp</code></td>
2569
+
2570
+
2571
+ <td class="type">
2572
+
2573
+
2574
+ <span class="param-type">Object</span>
2575
+ |
2576
+
2577
+ <span class="param-type">Array</span>
2578
+
2579
+
2580
+
2581
+
2582
+ </td>
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+ <td class="description last"><p>輸入 JSON5.parse(cgrups/cpemis) 之結果</p></td>
2589
+ </tr>
2590
+
2591
+
2592
+ </tbody>
2593
+ </table>
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+ <h5 class="h5-returns">Returns:</h5>
2611
+
2612
+
2613
+ <div class="param-desc">
2614
+ <p>回傳受影響之名稱陣列(不重複), 無損回傳空陣列; 不改動輸入</p>
2615
+ </div>
2616
+
2617
+
2618
+
2619
+ <dl class="param-type">
2620
+ <dt>
2621
+ Type
2622
+ </dt>
2623
+ <dd>
2624
+
2625
+ <span class="param-type">Array</span>
2626
+
2627
+
2628
+
2629
+ </dd>
2630
+ </dl>
2631
+
2632
+
2633
+
2634
+
2635
+
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+ <h4 class="name" id="getKpWriteLost"><span class="type-signature"></span>getKpWriteLost<span class="signature">(kpRef, kpNew)</span><span class="type-signature"> &rarr; {Array}</span></h4>
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+ <dl class="details">
2649
+
2650
+ <dt class="tag-description">Description:</dt>
2651
+ <dd class="tag-description"><ul class="dummy"><li><p>判定欲寫出之授權物件 kpNew 以 keepKeyOrder(kpRef, kpNew) 寫出時, 鍵序是否被 JS 屬性序(整數式鍵恆先排)改變而使第一個有效 AND 項易位, 回傳受影響之 AND 名稱</p>
2652
+ <p>四個帶 mode 的編輯器(VeCgrups/VeCpemis/VeGrupBlngUsers/VePemiBlngGrups)寫出前共用此函數(規則帳本 R-AUTH-LOSSY-01 ③): 預期序一律由「參考(解碼後之原資料)」與「欲寫出之物件」
2653
+ 在此函數內導出, 呼叫端不得自行傳入預期序——外審 minimax 第二輪指出關聯對話框曾以「已套用 JS 屬性序之物件序」當預期序, 守門恆等而形同虛設.
2654
+ kpRef 須為解碼後之原授權資料(cvKpToObj 之結果, 鍵序即伺服端序); kpNew 為欲寫出之物件(名稱 → { mode, isActive }).</p></li></ul></dd>
2655
+
2656
+
2657
+
2658
+ <dt class="tag-source">Source:</dt>
2659
+ <dd class="tag-source"><ul class="dummy"><li>
2660
+ <a href="src_js_getKpWriteLost.mjs.html">src/js/getKpWriteLost.mjs</a>, <a href="src_js_getKpWriteLost.mjs.html#line23">line 23</a>
2661
+ </li></ul></dd>
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+ </dl>
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+ <h5 class="h5-examples">Example</h5>
2706
+
2707
+ <pre class="prettyprint"><code>let kpRef = { A: { mode: 'AND', isActive: 'y' } }
2708
+ let kpNew = { A: { mode: 'AND', isActive: 'y' }, 1: { mode: 'AND', isActive: 'y' } } //新啟用整數式名稱 1 為 AND
2709
+ console.log(getKpWriteLost(kpRef, kpNew))
2710
+ // => ['A', '1']</code></pre>
2711
+
2712
+
2713
+
2714
+
2715
+ <h5 class="h5-parameters">Parameters:</h5>
2716
+
2717
+
2718
+ <table class="params">
2719
+ <thead>
2720
+ <tr>
2721
+
2722
+ <th>Name</th>
2723
+
2724
+
2725
+ <th>Type</th>
2726
+
2727
+
2728
+
2729
+
2730
+
2731
+ <th class="last">Description</th>
2732
+ </tr>
2733
+ </thead>
2734
+
2735
+ <tbody>
2736
+
2737
+
2738
+ <tr>
2739
+
2740
+ <td class="name"><code>kpRef</code></td>
2741
+
2742
+
2743
+ <td class="type">
2744
+
2745
+
2746
+ <span class="param-type">Object</span>
2747
+
2748
+
2749
+
2750
+
2751
+ </td>
2752
+
2753
+
2754
+
2755
+
2756
+
2757
+ <td class="description last"><p>輸入解碼後之原授權資料</p></td>
2758
+ </tr>
2759
+
2760
+
2761
+
2762
+ <tr>
2763
+
2764
+ <td class="name"><code>kpNew</code></td>
2765
+
2766
+
2767
+ <td class="type">
2768
+
2769
+
2770
+ <span class="param-type">Object</span>
2771
+
2772
+
2773
+
2774
+
2775
+ </td>
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+ <td class="description last"><p>輸入欲寫出之物件</p></td>
2782
+ </tr>
2783
+
2784
+
2785
+ </tbody>
2786
+ </table>
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+ <h5 class="h5-returns">Returns:</h5>
2804
+
2805
+
2806
+ <div class="param-desc">
2807
+ <p>回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入</p>
2808
+ </div>
2809
+
2810
+
2811
+
2812
+ <dl class="param-type">
2813
+ <dt>
2814
+ Type
2815
+ </dt>
2816
+ <dd>
2817
+
2818
+ <span class="param-type">Array</span>
2819
+
2820
+
2821
+
2822
+ </dd>
2823
+ </dl>
2824
+
2825
+
2826
+
2827
+
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+ <h4 class="name" id="getOwn"><span class="type-signature"></span>getOwn<span class="signature">(o, k, def<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {*}</span></h4>
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+ <dl class="details">
2842
+
2843
+ <dt class="tag-description">Description:</dt>
2844
+ <dd class="tag-description"><ul class="dummy"><li><p>取物件之自有屬性值, 不解析路徑、不取繼承屬性(lodash get 會把含 . 或 [ 之字串鍵解析為路徑, 並可取到繼承屬性)</p>
2845
+ <p>鍵為使用端資料(標的 id、群組/權限/規則名稱、列 id)時一律用本函數: 只授權 A 時, lodash get(kp, 'A.0') 經字串索引得 'y'、'A.length' 得 1、
2846
+ 'toString' 得繼承函數; 本函數對這些鍵回預設值. 自有屬性存在時回其值(含 0、''、null、false、undefined), 精確鍵(整串即鍵名, 如 'A.0')照常.
2847
+ 輸入非物件(null、undefined、字串、數字、布林)一律回預設值.</p></li></ul></dd>
2848
+
2849
+
2850
+
2851
+ <dt class="tag-source">Source:</dt>
2852
+ <dd class="tag-source"><ul class="dummy"><li>
2853
+ <a href="src_js_getOwn.mjs.html">src/js/getOwn.mjs</a>, <a href="src_js_getOwn.mjs.html#line30">line 30</a>
2854
+ </li></ul></dd>
2855
+
2856
+
2857
+
2858
+
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+
2885
+
2886
+ </dl>
2887
+
2888
+
2889
+
2890
+
2891
+
2892
+
2893
+
2894
+
2895
+
2896
+
2897
+
2898
+ <h5 class="h5-examples">Example</h5>
2899
+
2900
+ <pre class="prettyprint"><code>let kp = { A: 'y', 'B.0': 'y' }
2901
+ console.log(getOwn(kp, 'A', 'n'))
2902
+ // => 'y'
2903
+ console.log(getOwn(kp, 'A.0', 'n'))
2904
+ // => 'n'
2905
+ console.log(getOwn(kp, 'B.0', 'n'))
2906
+ // => 'y'
2907
+ console.log(getOwn(kp, 'toString', 'n'))
2908
+ // => 'n'</code></pre>
2909
+
2910
+
2911
+
2912
+
2913
+ <h5 class="h5-parameters">Parameters:</h5>
2914
+
2915
+
2916
+ <table class="params">
2917
+ <thead>
2918
+ <tr>
2919
+
2920
+ <th>Name</th>
2921
+
2922
+
2923
+ <th>Type</th>
2924
+
2925
+
2926
+ <th>Attributes</th>
2927
+
2928
+
2929
+
2930
+
2931
+ <th class="last">Description</th>
2932
+ </tr>
2933
+ </thead>
2934
+
2935
+ <tbody>
2936
+
2937
+
2938
+ <tr>
2939
+
2940
+ <td class="name"><code>o</code></td>
2941
+
2942
+
2943
+ <td class="type">
2944
+
2945
+
2946
+ <span class="param-type">Object</span>
2947
+
2948
+
2949
+
2950
+
2951
+ </td>
2952
+
2953
+
2954
+ <td class="attributes">
2955
+
2956
+
2957
+
2958
+
2959
+
2960
+ </td>
2961
+
2962
+
2963
+
2964
+
2965
+ <td class="description last"><p>輸入物件(可為一般物件或無原型物件)</p></td>
2966
+ </tr>
2967
+
2968
+
2969
+
2970
+ <tr>
2971
+
2972
+ <td class="name"><code>k</code></td>
2973
+
2974
+
2975
+ <td class="type">
2976
+
2977
+
2978
+ <span class="param-type">String</span>
2979
+ |
2980
+
2981
+ <span class="param-type">Number</span>
2982
+
2983
+
2984
+
2985
+
2986
+ </td>
2987
+
2988
+
2989
+ <td class="attributes">
2990
+
2991
+
2992
+
2993
+
2994
+
2995
+ </td>
2996
+
2997
+
2998
+
2999
+
3000
+ <td class="description last"><p>輸入鍵(整串視為鍵名)</p></td>
3001
+ </tr>
3002
+
3003
+
3004
+
3005
+ <tr>
3006
+
3007
+ <td class="name"><code>def</code></td>
3008
+
3009
+
3010
+ <td class="type">
3011
+
3012
+
3013
+ <span class="param-type">*</span>
3014
+
3015
+
3016
+
3017
+
3018
+ </td>
3019
+
3020
+
3021
+ <td class="attributes">
3022
+
3023
+ &lt;optional><br>
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+ </td>
3030
+
3031
+
3032
+
3033
+
3034
+ <td class="description last"><p>輸入無自有屬性時回傳之預設值, 預設undefined</p></td>
3035
+ </tr>
3036
+
3037
+
3038
+ </tbody>
3039
+ </table>
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+ <h5 class="h5-returns">Returns:</h5>
3057
+
3058
+
3059
+ <div class="param-desc">
3060
+ <p>回傳自有屬性值或預設值</p>
3061
+ </div>
3062
+
3063
+
3064
+
3065
+ <dl class="param-type">
3066
+ <dt>
3067
+ Type
3068
+ </dt>
3069
+ <dd>
3070
+
3071
+ <span class="param-type">*</span>
3072
+
3073
+
3074
+
3075
+ </dd>
3076
+ </dl>
3077
+
3078
+
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+
3087
+ <h4 class="name" id="getRuleEnable"><span class="type-signature"></span>getRuleEnable<span class="signature">(kp, name)</span><span class="type-signature"> &rarr; {String}</span></h4>
3088
+
3089
+
3090
+
3091
+
3092
+
3093
+
3094
+ <dl class="details">
3095
+
3096
+ <dt class="tag-description">Description:</dt>
3097
+ <dd class="tag-description"><ul class="dummy"><li><p>取得規則(標的)於 JSON5 解析結果(crules)中之啟用狀態</p>
3098
+ <p>與 getUserRules 之解碼一致: 名稱為資料不是路徑(僅以自有屬性精確查值, 規則帳本 R-AUTH-PATH-01),
3099
+ 值為物件(如 { isActive: 'y' })時取其 isActive, 其餘取值本身; 僅 'y' 為啟用, 其餘(含缺漏、非字串、物件值無 isActive)皆為 'n'.
3100
+ 使編輯對話框顯示之狀態與實際授權結果一致, 存檔時不致把有效授權靜默改成 n</p></li></ul></dd>
3101
+
3102
+
3103
+
3104
+ <dt class="tag-source">Source:</dt>
3105
+ <dd class="tag-source"><ul class="dummy"><li>
3106
+ <a href="src_js_getRuleEnable.mjs.html">src/js/getRuleEnable.mjs</a>, <a href="src_js_getRuleEnable.mjs.html#line15">line 15</a>
3107
+ </li></ul></dd>
3108
+
3109
+
3110
+
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+
3138
+
3139
+ </dl>
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
1059
3149
 
1060
3150
 
1061
3151
 
@@ -1085,15 +3175,12 @@ console.log(ks)
1085
3175
 
1086
3176
  <tr>
1087
3177
 
1088
- <td class="name"><code>o</code></td>
3178
+ <td class="name"><code>kp</code></td>
1089
3179
 
1090
3180
 
1091
3181
  <td class="type">
1092
3182
 
1093
3183
 
1094
- <span class="param-type">Array</span>
1095
- |
1096
-
1097
3184
  <span class="param-type">Object</span>
1098
3185
 
1099
3186
 
@@ -1105,20 +3192,20 @@ console.log(ks)
1105
3192
 
1106
3193
 
1107
3194
 
1108
- <td class="description last"><p>輸入陣列或物件</p></td>
3195
+ <td class="description last"><p>輸入 JSON5.parse(crules) 之結果, 鍵為規則(標的)名稱</p></td>
1109
3196
  </tr>
1110
3197
 
1111
3198
 
1112
3199
 
1113
3200
  <tr>
1114
3201
 
1115
- <td class="name"><code>fn</code></td>
3202
+ <td class="name"><code>name</code></td>
1116
3203
 
1117
3204
 
1118
3205
  <td class="type">
1119
3206
 
1120
3207
 
1121
- <span class="param-type">function</span>
3208
+ <span class="param-type">String</span>
1122
3209
 
1123
3210
 
1124
3211
 
@@ -1129,7 +3216,7 @@ console.log(ks)
1129
3216
 
1130
3217
 
1131
3218
 
1132
- <td class="description last"><p>輸入回呼函數(值, 鍵或索引, 原輸入), 回傳false時跳出, 其他回傳值(含undefined、true)皆繼續</p></td>
3219
+ <td class="description last"><p>輸入規則(標的)名稱</p></td>
1133
3220
  </tr>
1134
3221
 
1135
3222
 
@@ -1155,7 +3242,7 @@ console.log(ks)
1155
3242
 
1156
3243
 
1157
3244
  <div class="param-desc">
1158
- <p>回傳原輸入</p>
3245
+ <p>回傳 'y' 或 'n'</p>
1159
3246
  </div>
1160
3247
 
1161
3248
 
@@ -1166,10 +3253,7 @@ console.log(ks)
1166
3253
  </dt>
1167
3254
  <dd>
1168
3255
 
1169
- <span class="param-type">Array</span>
1170
- |
1171
-
1172
- <span class="param-type">Object</span>
3256
+ <span class="param-type">String</span>
1173
3257
 
1174
3258
 
1175
3259
 
@@ -1185,7 +3269,7 @@ console.log(ks)
1185
3269
 
1186
3270
 
1187
3271
 
1188
- <h4 class="name" id="fetchJson"><span class="type-signature type-signature-async">(async) </span>fetchJson<span class="signature">(url, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
3272
+ <h4 class="name" id="isAuthMode"><span class="type-signature"></span>isAuthMode<span class="signature">(m)</span><span class="type-signature"> &rarr; {Boolean}</span></h4>
1189
3273
 
1190
3274
 
1191
3275
 
@@ -1195,21 +3279,15 @@ console.log(ks)
1195
3279
  <dl class="details">
1196
3280
 
1197
3281
  <dt class="tag-description">Description:</dt>
1198
- <dd class="tag-description"><ul class="dummy"><li><p>以瀏覽器與 node(18+) 內建之 fetch 取得 JSON 回應, 取代 axios(2026-09-07 起本套件不再依賴 axios)</p>
1199
- <p>與 axios 之語意對齊:</p>
1200
- <ul>
1201
- <li>網路錯誤或非 2xx: axios 會 reject, fetch 只在網路錯誤 reject, 故此處對 !res.ok 亦 reject, 統一為 { kind: 'request', status, message }</li>
1202
- <li>回應非 JSON: axios 回原字串(呼叫端判 state 失敗), 此處 res.json() 失敗 reject { kind: 'parse', status, message }</li>
1203
- <li>成功: resolve 解析後之 JSON(對應 axios 之 res.data)
1204
- reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'SyntaxError')或 'HTTP <status>', 不含網址與回應本體(網址常帶權杖)
1205
- 注意: node 端 fetch(undici) 不讀 HTTP_PROXY / HTTPS_PROXY 環境變數(axios 會), 需走 proxy 之部署須自行以 opt.dispatcher 注入 undici Agent</li>
1206
- </ul></li></ul></dd>
3282
+ <dd class="tag-description"><ul class="dummy"><li><p>判斷是否為合法合併模式 'OR' 或 'AND'</p>
3283
+ <p>與伺服端 src/plugins/mShare.mjs 之 mergeRules 一致: mode 非 OR/AND 之群組/權限不納入合併(不授權).
3284
+ 編輯器解碼(cvKpToObj)與無損表示判定(getKpLossy)共用, 單一擁有者.</p></li></ul></dd>
1207
3285
 
1208
3286
 
1209
3287
 
1210
3288
  <dt class="tag-source">Source:</dt>
1211
3289
  <dd class="tag-source"><ul class="dummy"><li>
1212
- <a href="src_fetchJson.mjs.html">src/fetchJson.mjs</a>, <a href="src_fetchJson.mjs.html#line40">line 40</a>
3290
+ <a href="src_js_isAuthMode.mjs.html">src/js/isAuthMode.mjs</a>, <a href="src_js_isAuthMode.mjs.html#line15">line 15</a>
1213
3291
  </li></ul></dd>
1214
3292
 
1215
3293
 
@@ -1254,6 +3332,12 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1254
3332
 
1255
3333
 
1256
3334
 
3335
+ <h5 class="h5-examples">Example</h5>
3336
+
3337
+ <pre class="prettyprint"><code>console.log(isAuthMode('OR'), isAuthMode('or'), isAuthMode(undefined))
3338
+ // => true false false</code></pre>
3339
+
3340
+
1257
3341
 
1258
3342
 
1259
3343
  <h5 class="h5-parameters">Parameters:</h5>
@@ -1269,12 +3353,8 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1269
3353
  <th>Type</th>
1270
3354
 
1271
3355
 
1272
- <th>Attributes</th>
1273
-
1274
3356
 
1275
3357
 
1276
- <th>Default</th>
1277
-
1278
3358
 
1279
3359
  <th class="last">Description</th>
1280
3360
  </tr>
@@ -1285,49 +3365,13 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1285
3365
 
1286
3366
  <tr>
1287
3367
 
1288
- <td class="name"><code>url</code></td>
1289
-
1290
-
1291
- <td class="type">
1292
-
1293
-
1294
- <span class="param-type">String</span>
1295
-
1296
-
1297
-
1298
-
1299
- </td>
1300
-
1301
-
1302
- <td class="attributes">
1303
-
1304
-
1305
-
1306
-
1307
-
1308
- </td>
1309
-
1310
-
1311
-
1312
- <td class="default">
1313
-
1314
- </td>
1315
-
1316
-
1317
- <td class="description last"><p>輸入請求網址字串</p></td>
1318
- </tr>
1319
-
1320
-
1321
-
1322
- <tr>
1323
-
1324
- <td class="name"><code>opt</code></td>
3368
+ <td class="name"><code>m</code></td>
1325
3369
 
1326
3370
 
1327
3371
  <td class="type">
1328
3372
 
1329
3373
 
1330
- <span class="param-type">Object</span>
3374
+ <span class="param-type">*</span>
1331
3375
 
1332
3376
 
1333
3377
 
@@ -1335,26 +3379,10 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1335
3379
  </td>
1336
3380
 
1337
3381
 
1338
- <td class="attributes">
1339
-
1340
- &lt;optional><br>
1341
-
1342
-
1343
-
1344
-
1345
-
1346
- </td>
1347
-
1348
3382
 
1349
3383
 
1350
- <td class="default">
1351
-
1352
- <code>{}</code>
1353
-
1354
- </td>
1355
-
1356
3384
 
1357
- <td class="description last"><p>輸入 fetch 選項物件(method / headers / body / signal / dispatcher 等原樣傳給 fetch), 預設 {}</p></td>
3385
+ <td class="description last"><p>輸入 mode</p></td>
1358
3386
  </tr>
1359
3387
 
1360
3388
 
@@ -1380,7 +3408,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1380
3408
 
1381
3409
 
1382
3410
  <div class="param-desc">
1383
- <p>回傳 Promise, resolve 為 JSON 物件, reject 為 { kind: 'request'|'parse', status, message }</p>
3411
+ <p>回傳是否為 'OR' 或 'AND'</p>
1384
3412
  </div>
1385
3413
 
1386
3414
 
@@ -1391,7 +3419,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1391
3419
  </dt>
1392
3420
  <dd>
1393
3421
 
1394
- <span class="param-type">Promise</span>
3422
+ <span class="param-type">Boolean</span>
1395
3423
 
1396
3424
 
1397
3425
 
@@ -1407,7 +3435,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1407
3435
 
1408
3436
 
1409
3437
 
1410
- <h4 class="name" id="genLegend"><span class="type-signature"></span>genLegend<span class="signature">(type<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Object}</span></h4>
3438
+ <h4 class="name" id="joinNames"><span class="type-signature"></span>joinNames<span class="signature">(names, max<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {String}</span></h4>
1411
3439
 
1412
3440
 
1413
3441
 
@@ -1417,14 +3445,13 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1417
3445
  <dl class="details">
1418
3446
 
1419
3447
  <dt class="tag-description">Description:</dt>
1420
- <dd class="tag-description"><ul class="dummy"><li><p>產生圖例設定(單一來源), genOpt 與執行期切換類型共用</p>
1421
- <p>切換類型(plain↔scroll)時 echarts 以新傳入之選項重建圖例模型(Global.js:322-344), 未帶之設定一律回到預設, 故每次都須帶齊</p></li></ul></dd>
3448
+ <dd class="tag-description"><ul class="dummy"><li><p>把名稱陣列以「, 」串接供訊息顯示, 超過上限者截斷並加省略號</p></li></ul></dd>
1422
3449
 
1423
3450
 
1424
3451
 
1425
3452
  <dt class="tag-source">Source:</dt>
1426
3453
  <dd class="tag-source"><ul class="dummy"><li>
1427
- <a href="src_js_legendFit.mjs.html">src/js/legendFit.mjs</a>, <a href="src_js_legendFit.mjs.html#line24">line 24</a>
3454
+ <a href="src_js_joinNames.mjs.html">src/js/joinNames.mjs</a>, <a href="src_js_joinNames.mjs.html#line15">line 15</a>
1428
3455
  </li></ul></dd>
1429
3456
 
1430
3457
 
@@ -1469,6 +3496,14 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1469
3496
 
1470
3497
 
1471
3498
 
3499
+ <h5 class="h5-examples">Example</h5>
3500
+
3501
+ <pre class="prettyprint"><code>console.log(joinNames(['a', 'b']))
3502
+ // => 'a, b'
3503
+ console.log(joinNames(['a', 'b', 'c'], 2))
3504
+ // => 'a, b …'</code></pre>
3505
+
3506
+
1472
3507
 
1473
3508
 
1474
3509
  <h5 class="h5-parameters">Parameters:</h5>
@@ -1500,13 +3535,49 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1500
3535
 
1501
3536
  <tr>
1502
3537
 
1503
- <td class="name"><code>type</code></td>
3538
+ <td class="name"><code>names</code></td>
1504
3539
 
1505
3540
 
1506
3541
  <td class="type">
1507
3542
 
1508
3543
 
1509
- <span class="param-type">String</span>
3544
+ <span class="param-type">Array</span>
3545
+
3546
+
3547
+
3548
+
3549
+ </td>
3550
+
3551
+
3552
+ <td class="attributes">
3553
+
3554
+
3555
+
3556
+
3557
+
3558
+ </td>
3559
+
3560
+
3561
+
3562
+ <td class="default">
3563
+
3564
+ </td>
3565
+
3566
+
3567
+ <td class="description last"><p>輸入名稱陣列, 非陣列回傳空字串, 元素非字串者轉字串</p></td>
3568
+ </tr>
3569
+
3570
+
3571
+
3572
+ <tr>
3573
+
3574
+ <td class="name"><code>max</code></td>
3575
+
3576
+
3577
+ <td class="type">
3578
+
3579
+
3580
+ <span class="param-type">Number</span>
1510
3581
 
1511
3582
 
1512
3583
 
@@ -1528,12 +3599,12 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1528
3599
 
1529
3600
  <td class="default">
1530
3601
 
1531
- <code>'plain'</code>
3602
+ <code>5</code>
1532
3603
 
1533
3604
  </td>
1534
3605
 
1535
3606
 
1536
- <td class="description last"><p>輸入圖例類型字串, 'plain'或'scroll', 預設'plain'</p></td>
3607
+ <td class="description last"><p>輸入最多列出幾個名稱, 預設5</p></td>
1537
3608
  </tr>
1538
3609
 
1539
3610
 
@@ -1559,7 +3630,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1559
3630
 
1560
3631
 
1561
3632
  <div class="param-desc">
1562
- <p>回傳echarts之legend設定物件</p>
3633
+ <p>回傳字串, 如 'a, b, c' 或 'a, b, c, d, e …'</p>
1563
3634
  </div>
1564
3635
 
1565
3636
 
@@ -1570,7 +3641,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1570
3641
  </dt>
1571
3642
  <dd>
1572
3643
 
1573
- <span class="param-type">Object</span>
3644
+ <span class="param-type">String</span>
1574
3645
 
1575
3646
 
1576
3647
 
@@ -1586,7 +3657,7 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1586
3657
 
1587
3658
 
1588
3659
 
1589
- <h4 class="name" id="getOwn"><span class="type-signature"></span>getOwn<span class="signature">(o, k, def<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {*}</span></h4>
3660
+ <h4 class="name" id="keepKeyOrder"><span class="type-signature"></span>keepKeyOrder<span class="signature">(kpRef, kpNew)</span><span class="type-signature"> &rarr; {Object}</span></h4>
1590
3661
 
1591
3662
 
1592
3663
 
@@ -1596,16 +3667,17 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1596
3667
  <dl class="details">
1597
3668
 
1598
3669
  <dt class="tag-description">Description:</dt>
1599
- <dd class="tag-description"><ul class="dummy"><li><p>取物件之自有屬性值, 不解析路徑、不取繼承屬性(lodash get 會把含 . 或 [ 之字串鍵解析為路徑, 並可取到繼承屬性)</p>
1600
- <p>鍵為使用端資料(標的 id、群組/權限/規則名稱、列 id)時一律用本函數: 只授權 A 時, lodash get(kp, 'A.0') 經字串索引得 'y'、'A.length' 得 1、
1601
- 'toString' 得繼承函數; 本函數對這些鍵回預設值. 自有屬性存在時回其值(含 0、''、null、false、undefined), 精確鍵(整串即鍵名, 如 'A.0')照常.
1602
- 輸入非物件(null、undefined、字串、數字、布林)一律回預設值.</p></li></ul></dd>
3670
+ <dd class="tag-description"><ul class="dummy"><li><p>以 kpRef 之鍵序重排 kpNew: 參考中已有之名稱維持參考序, 新增名稱附加於後(依 kpNew 序), kpNew 沒有之名稱(已刪除)不出現</p>
3671
+ <p>編輯器寫出授權字串(cgrups/cpemis/crules)時使用(規則帳本 R-AUTH-ORDER-01): 伺服端 mergeRules 在沒有任何有效 OR 項時以「第一個 AND 項」為 AND 合併之起始,
3672
+ 結果因鍵序而異, 編輯器若依對話框(群組表)順序重寫, 未改動之授權也會被改變(可增權可減權); 保留原鍵序使「存檔後授權不變」.
3673
+ 值一律取 kpNew; 鍵為使用者資料(含 <strong>proto</strong>、constructor 等原型鍵名), 回傳無原型物件, 不改動輸入.
3674
+ JS 物件屬性序使整數式鍵(如 '1'、'2')恆排在前面且遞增, 本函數無法改變(此類資料由 getKpLossy 判定, 見規則帳本 R-AUTH-LOSSY-01).</p></li></ul></dd>
1603
3675
 
1604
3676
 
1605
3677
 
1606
3678
  <dt class="tag-source">Source:</dt>
1607
3679
  <dd class="tag-source"><ul class="dummy"><li>
1608
- <a href="src_js_getOwn.mjs.html">src/js/getOwn.mjs</a>, <a href="src_js_getOwn.mjs.html#line30">line 30</a>
3680
+ <a href="src_js_keepKeyOrder.mjs.html">src/js/keepKeyOrder.mjs</a>, <a href="src_js_keepKeyOrder.mjs.html#line21">line 21</a>
1609
3681
  </li></ul></dd>
1610
3682
 
1611
3683
 
@@ -1652,15 +3724,8 @@ reject 之 message 只含例外名稱與代碼(如 'TypeError ECONNREFUSED'、'S
1652
3724
 
1653
3725
  <h5 class="h5-examples">Example</h5>
1654
3726
 
1655
- <pre class="prettyprint"><code>let kp = { A: 'y', 'B.0': 'y' }
1656
- console.log(getOwn(kp, 'A', 'n'))
1657
- // => 'y'
1658
- console.log(getOwn(kp, 'A.0', 'n'))
1659
- // => 'n'
1660
- console.log(getOwn(kp, 'B.0', 'n'))
1661
- // => 'y'
1662
- console.log(getOwn(kp, 'toString', 'n'))
1663
- // => 'n'</code></pre>
3727
+ <pre class="prettyprint"><code>console.log(Object.keys(keepKeyOrder({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' })))
3728
+ // => ['B', 'A', 'C']</code></pre>
1664
3729
 
1665
3730
 
1666
3731
 
@@ -1678,8 +3743,6 @@ console.log(getOwn(kp, 'toString', 'n'))
1678
3743
  <th>Type</th>
1679
3744
 
1680
3745
 
1681
- <th>Attributes</th>
1682
-
1683
3746
 
1684
3747
 
1685
3748
 
@@ -1692,7 +3755,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1692
3755
 
1693
3756
  <tr>
1694
3757
 
1695
- <td class="name"><code>o</code></td>
3758
+ <td class="name"><code>kpRef</code></td>
1696
3759
 
1697
3760
 
1698
3761
  <td class="type">
@@ -1706,66 +3769,23 @@ console.log(getOwn(kp, 'toString', 'n'))
1706
3769
  </td>
1707
3770
 
1708
3771
 
1709
- <td class="attributes">
1710
-
1711
-
1712
-
1713
-
1714
-
1715
- </td>
1716
-
1717
-
1718
-
1719
-
1720
- <td class="description last"><p>輸入物件(可為一般物件或無原型物件)</p></td>
1721
- </tr>
1722
-
1723
-
1724
-
1725
- <tr>
1726
-
1727
- <td class="name"><code>k</code></td>
1728
-
1729
-
1730
- <td class="type">
1731
-
1732
-
1733
- <span class="param-type">String</span>
1734
- |
1735
-
1736
- <span class="param-type">Number</span>
1737
-
1738
-
1739
-
1740
-
1741
- </td>
1742
-
1743
-
1744
- <td class="attributes">
1745
-
1746
-
1747
-
1748
-
1749
-
1750
- </td>
1751
-
1752
3772
 
1753
3773
 
1754
3774
 
1755
- <td class="description last"><p>輸入鍵(整串視為鍵名)</p></td>
3775
+ <td class="description last"><p>輸入參考物件(通常為 cvKpToObj 解碼後之原授權資料), 非物件(null、undefined、陣列、字串、數字)視為無參考</p></td>
1756
3776
  </tr>
1757
3777
 
1758
3778
 
1759
3779
 
1760
3780
  <tr>
1761
3781
 
1762
- <td class="name"><code>def</code></td>
3782
+ <td class="name"><code>kpNew</code></td>
1763
3783
 
1764
3784
 
1765
3785
  <td class="type">
1766
3786
 
1767
3787
 
1768
- <span class="param-type">*</span>
3788
+ <span class="param-type">Object</span>
1769
3789
 
1770
3790
 
1771
3791
 
@@ -1773,20 +3793,10 @@ console.log(getOwn(kp, 'toString', 'n'))
1773
3793
  </td>
1774
3794
 
1775
3795
 
1776
- <td class="attributes">
1777
-
1778
- &lt;optional><br>
1779
-
1780
-
1781
-
1782
-
1783
-
1784
- </td>
1785
-
1786
3796
 
1787
3797
 
1788
3798
 
1789
- <td class="description last"><p>輸入無自有屬性時回傳之預設值, 預設undefined</p></td>
3799
+ <td class="description last"><p>輸入欲寫出之物件, 鍵為名稱</p></td>
1790
3800
  </tr>
1791
3801
 
1792
3802
 
@@ -1812,7 +3822,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1812
3822
 
1813
3823
 
1814
3824
  <div class="param-desc">
1815
- <p>回傳自有屬性值或預設值</p>
3825
+ <p>回傳無原型物件, 鍵序為參考序在前、新增在後</p>
1816
3826
  </div>
1817
3827
 
1818
3828
 
@@ -1823,7 +3833,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1823
3833
  </dt>
1824
3834
  <dd>
1825
3835
 
1826
- <span class="param-type">*</span>
3836
+ <span class="param-type">Object</span>
1827
3837
 
1828
3838
 
1829
3839
 
@@ -1839,7 +3849,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1839
3849
 
1840
3850
 
1841
3851
 
1842
- <h4 class="name" id="getRuleEnable"><span class="type-signature"></span>getRuleEnable<span class="signature">(kp, name)</span><span class="type-signature"> &rarr; {String}</span></h4>
3852
+ <h4 class="name" id="keyOrderOf"><span class="type-signature"></span>keyOrderOf<span class="signature">(kpRef, kpNew)</span><span class="type-signature"> &rarr; {Array}</span></h4>
1843
3853
 
1844
3854
 
1845
3855
 
@@ -1849,16 +3859,14 @@ console.log(getOwn(kp, 'toString', 'n'))
1849
3859
  <dl class="details">
1850
3860
 
1851
3861
  <dt class="tag-description">Description:</dt>
1852
- <dd class="tag-description"><ul class="dummy"><li><p>取得規則(標的)於 JSON5 解析結果(crules)中之啟用狀態</p>
1853
- <p>與 getUserRules 之解碼一致: 名稱為資料不是路徑(僅以自有屬性精確查值, 規則帳本 R-AUTH-PATH-01),
1854
- 值為物件(如 { isActive: 'y' })時取其 isActive, 其餘取值本身; 僅 'y' 為啟用, 其餘(含缺漏、非字串、物件值無 isActive)皆為 'n'.
1855
- 使編輯對話框顯示之狀態與實際授權結果一致, 存檔時不致把有效授權靜默改成 n</p></li></ul></dd>
3862
+ <dd class="tag-description"><ul class="dummy"><li><p>keepKeyOrder 的預期名稱順序: 參考中已有之名稱依參考序在前, kpNew 新增之名稱依 kpNew 序附加於後; 以陣列回傳(不受 JS 屬性序影響)</p>
3863
+ <p>輸出物件(keepKeyOrder)之鍵序受 JS 屬性序影響(整數式鍵恆先排), 與本函數的預期序可能不同, 差異影響有效 AND 項之相對順序者由 getKeyOrderLost 判定(編輯器拒存).</p></li></ul></dd>
1856
3864
 
1857
3865
 
1858
3866
 
1859
3867
  <dt class="tag-source">Source:</dt>
1860
3868
  <dd class="tag-source"><ul class="dummy"><li>
1861
- <a href="src_js_getRuleEnable.mjs.html">src/js/getRuleEnable.mjs</a>, <a href="src_js_getRuleEnable.mjs.html#line15">line 15</a>
3869
+ <a href="src_js_keepKeyOrder.mjs.html">src/js/keepKeyOrder.mjs</a>, <a href="src_js_keepKeyOrder.mjs.html#line44">line 44</a>
1862
3870
  </li></ul></dd>
1863
3871
 
1864
3872
 
@@ -1903,6 +3911,12 @@ console.log(getOwn(kp, 'toString', 'n'))
1903
3911
 
1904
3912
 
1905
3913
 
3914
+ <h5 class="h5-examples">Example</h5>
3915
+
3916
+ <pre class="prettyprint"><code>console.log(keyOrderOf({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' }))
3917
+ // => ['B', 'A', 'C']</code></pre>
3918
+
3919
+
1906
3920
 
1907
3921
 
1908
3922
  <h5 class="h5-parameters">Parameters:</h5>
@@ -1930,7 +3944,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1930
3944
 
1931
3945
  <tr>
1932
3946
 
1933
- <td class="name"><code>kp</code></td>
3947
+ <td class="name"><code>kpRef</code></td>
1934
3948
 
1935
3949
 
1936
3950
  <td class="type">
@@ -1947,20 +3961,20 @@ console.log(getOwn(kp, 'toString', 'n'))
1947
3961
 
1948
3962
 
1949
3963
 
1950
- <td class="description last"><p>輸入 JSON5.parse(crules) 之結果, 鍵為規則(標的)名稱</p></td>
3964
+ <td class="description last"><p>輸入參考物件, 非物件視為無參考</p></td>
1951
3965
  </tr>
1952
3966
 
1953
3967
 
1954
3968
 
1955
3969
  <tr>
1956
3970
 
1957
- <td class="name"><code>name</code></td>
3971
+ <td class="name"><code>kpNew</code></td>
1958
3972
 
1959
3973
 
1960
3974
  <td class="type">
1961
3975
 
1962
3976
 
1963
- <span class="param-type">String</span>
3977
+ <span class="param-type">Object</span>
1964
3978
 
1965
3979
 
1966
3980
 
@@ -1971,7 +3985,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1971
3985
 
1972
3986
 
1973
3987
 
1974
- <td class="description last"><p>輸入規則(標的)名稱</p></td>
3988
+ <td class="description last"><p>輸入欲寫出之物件, 非物件回傳空陣列</p></td>
1975
3989
  </tr>
1976
3990
 
1977
3991
 
@@ -1997,7 +4011,7 @@ console.log(getOwn(kp, 'toString', 'n'))
1997
4011
 
1998
4012
 
1999
4013
  <div class="param-desc">
2000
- <p>回傳 'y' 或 'n'</p>
4014
+ <p>回傳名稱陣列</p>
2001
4015
  </div>
2002
4016
 
2003
4017
 
@@ -2008,7 +4022,7 @@ console.log(getOwn(kp, 'toString', 'n'))
2008
4022
  </dt>
2009
4023
  <dd>
2010
4024
 
2011
- <span class="param-type">String</span>
4025
+ <span class="param-type">Array</span>
2012
4026
 
2013
4027
 
2014
4028
 
@@ -3543,7 +5557,10 @@ opt.hold 為函數, 輸入流程結果, 回傳 true 時保持占位與按鈕鎖(
3543
5557
  <li>主鍵 id 有給時須為非空字串或有限數字(NaN、±Infinity 視為未給, 同 w-serv-orm 1.1.11 之補值), 字串之 UTF-8 位元組數不得超過 1978(LMDB 鍵長上限),
3544
5558
  且批內不得重複(以 String(id) 比對: w-serv-orm 1.1.11 起數字主鍵存為其字串形式, 數字與其字串形式為同一主鍵).</li>
3545
5559
  <li>任一字串欄位之值會被 wsemi 之 clearXSS 改寫者(含 HTML 標記, 如「&lt;」後接英文字母)即拒絕——與 w-serv-orm 寫入前之 adjustData 同一函數,
3546
- 主鍵被改寫時 ORM 拒絕整批, 其他欄位則會被靜默改寫(存值與送入值不同), 兩者皆於此擋下, 使送入值即儲存值.
5560
+ 主鍵被改寫時 ORM 拒絕整批, 其他欄位則會被靜默改寫(存值與送入值不同), 兩者皆於此擋下, 使送入值即儲存值.</li>
5561
+ <li>任一欄位之值須為純量(字串、數字、布林、null、undefined)——物件、陣列、函數、symbol、bigint 一律拒絕(規則帳本 R-FIELD-SCALAR-01):
5562
+ 四表 schema 欄位型別只有 STRING/INTEGER/TEXT(cgrups/cpemis/crules 為 TEXT 存 JSON 字串), 無合法物件型欄位; 修正前預檢只看 isestr(vv),
5563
+ 巢狀字串(如 { description: { value: '&lt;標記&gt;' } })避過預檢而於寫入時被 w-serv-orm 靜默改寫(非拒絕), 「送入值即儲存值」不成立.
3547
5564
  本函數為純函數: 不修改輸入、不呼叫 ORM; 主鍵是否必填由呼叫端以 opt.idRequired 指定(未給主鍵之列由 ORM 自動補主鍵者可不要求).
3548
5565
  列物件之欄位一律依自有可列舉字串鍵逐一檢查(規則帳本 R-OBJ-ITER-01): 名為 length 之欄位與其他欄位同為一般欄位, 即使其值為非負整數(0、1、2**32-1)亦然——
3549
5566
  lodash each 對這類物件會改走索引 0..length-1 而略過全部字串欄位, 且迭代次數即 length 之值; rows 與 rowsIdOnly 須為真陣列(Array.isArray),
@@ -3554,7 +5571,7 @@ lodash each 對這類物件會改走索引 0..length-1 而略過全部字串欄
3554
5571
 
3555
5572
  <dt class="tag-source">Source:</dt>
3556
5573
  <dd class="tag-source"><ul class="dummy"><li>
3557
- <a href="server_validateRows.mjs.html">server/validateRows.mjs</a>, <a href="server_validateRows.mjs.html#line31">line 31</a>
5574
+ <a href="server_validateRows.mjs.html">server/validateRows.mjs</a>, <a href="server_validateRows.mjs.html#line38">line 38</a>
3558
5575
  </li></ul></dd>
3559
5576
 
3560
5577
 
@@ -3835,7 +5852,7 @@ lodash each 對這類物件會改走索引 0..length-1 而略過全部字串欄
3835
5852
 
3836
5853
 
3837
5854
  <div class="param-desc">
3838
- <p>回傳第一個違規 { reason, k, field }, reason 為 'rowsInvalid'、'idInvalid'、'idTooLong'、'idDuplicate'、'htmlMarkup' 之一, k 為該列於 rows 之位置(rowsIdOnly 之列為 -1), field 為欄位名; 皆通過回傳 null</p>
5855
+ <p>回傳第一個違規 { reason, k, field }, reason 為 'rowsInvalid'、'idInvalid'、'idTooLong'、'idDuplicate'、'fieldNotScalar'、'htmlMarkup' 之一, k 為該列於 rows 之位置(rowsIdOnly 之列為 -1), field 為欄位名; 皆通過回傳 null</p>
3839
5856
  </div>
3840
5857
 
3841
5858
 
@@ -4437,7 +6454,7 @@ lodash each 對這類物件會改走索引 0..length-1 而略過全部字串欄
4437
6454
  <br class="clear">
4438
6455
 
4439
6456
  <footer>
4440
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Tue Oct 20 2026 14:44:45 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
6457
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Wed Oct 21 2026 01:27:46 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
4441
6458
  </footer>
4442
6459
 
4443
6460
  <script>prettyPrint();</script>