w-web-perm 1.1.12 → 1.1.13

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 (124) hide show
  1. package/README.md +158 -123
  2. package/dist/css/app.f09c7433.css +1 -0
  3. package/dist/index.tmp +1 -1
  4. package/dist/js/app-legacy.8af87052.js +1 -0
  5. package/dist/js/app.8af87052.js +1 -0
  6. package/dist/js/{chunk-vendors.3e9e3ef1.js → chunk-vendors-legacy.ece5a361.js} +1 -1
  7. package/dist/js/{chunk-vendors-legacy.3e9e3ef1.js → chunk-vendors.ece5a361.js} +1 -1
  8. package/dist/w-web-perm.umd.js +2 -2
  9. package/dist/w-web-perm.umd.js.map +1 -1
  10. package/docs/WWebPerm.html +84 -4
  11. package/docs/global.html +23023 -1125
  12. package/docs/index.html +2 -2
  13. package/docs/server_WWebPerm.mjs.html +232 -32
  14. package/docs/server_cascadeWrite.mjs.html +225 -0
  15. package/docs/server_dataChannel.mjs.html +2 -2
  16. package/docs/server_keyCheck.mjs.html +353 -0
  17. package/docs/server_lockSave.mjs.html +2 -2
  18. package/docs/server_maskLog.mjs.html +2 -2
  19. package/docs/server_procCore.mjs.html +180 -41
  20. package/docs/server_staLogs_resolveShellWorker.mjs.html +2 -2
  21. package/docs/server_syncKeep.mjs.html +311 -0
  22. package/docs/server_tools_authRefsAudit.mjs.html +247 -0
  23. package/docs/server_tools_authRefsClean.mjs.html +335 -0
  24. package/docs/server_tools_fromTools.mjs.html +797 -0
  25. package/docs/server_tools_isMain.mjs.html +103 -0
  26. package/docs/server_tools_nameDupReport.mjs.html +280 -0
  27. package/docs/server_validateRows.mjs.html +2 -2
  28. package/docs/server_wrapInjected.mjs.html +3 -3
  29. package/docs/src_fetchJson.mjs.html +2 -2
  30. package/docs/src_js_cvKpToArr.mjs.html +2 -2
  31. package/docs/src_js_cvKpToObj.mjs.html +44 -33
  32. package/docs/src_js_draftSync.mjs.html +142 -0
  33. package/docs/src_js_eachOwn.mjs.html +3 -3
  34. package/docs/src_js_editorRefRows.mjs.html +356 -0
  35. package/docs/src_js_externalRows.mjs.html +338 -0
  36. package/docs/src_js_externalUi.mjs.html +230 -0
  37. package/docs/src_js_findRefRows.mjs.html +107 -0
  38. package/docs/src_js_findTouchedDup.mjs.html +150 -0
  39. package/docs/src_js_fmtLossyMsg.mjs.html +2 -2
  40. package/docs/src_js_fromAudit.mjs.html +489 -0
  41. package/docs/src_js_getAddImpact.mjs.html +269 -0
  42. package/docs/src_js_getAuthWarn.mjs.html +463 -0
  43. package/docs/src_js_getCascadePreview.mjs.html +258 -0
  44. package/docs/src_js_getDelRefCount.mjs.html +210 -0
  45. package/docs/src_js_getEffMode.mjs.html +92 -0
  46. package/docs/src_js_getKpLossy.mjs.html +47 -52
  47. package/docs/src_js_getNameErrs.mjs.html +266 -0
  48. package/docs/src_js_getOwn.mjs.html +3 -3
  49. package/docs/src_js_getPropKey.mjs.html +109 -0
  50. package/docs/src_js_getRuleEnable.mjs.html +2 -2
  51. package/docs/src_js_isAuthMode.mjs.html +4 -4
  52. package/docs/src_js_joinNames.mjs.html +2 -2
  53. package/docs/src_js_legendFit.mjs.html +2 -2
  54. package/docs/src_js_pairRowsToSnapshot.mjs.html +156 -0
  55. package/docs/src_js_refAudit.mjs.html +359 -0
  56. package/docs/src_js_refCascade.mjs.html +572 -0
  57. package/docs/src_js_relDialogSend.mjs.html +199 -0
  58. package/docs/src_js_rowDigest.mjs.html +265 -0
  59. package/docs/src_plugins_dataReloadGuard.mjs.html +109 -0
  60. package/docs/src_plugins_reuseDeletedIds.mjs.html +2 -2
  61. package/docs/src_plugins_submitGuard.mjs.html +2 -2
  62. package/g_authRefsClean.mjs +79 -0
  63. package/g_fixFromType.mjs +92 -0
  64. package/g_initialData.mjs +3 -3
  65. package/g_purgeFrom.mjs +127 -0
  66. package/package.json +1 -1
  67. package/server/WWebPerm.mjs +230 -30
  68. package/server/cascadeWrite.mjs +153 -0
  69. package/server/keyCheck.mjs +281 -0
  70. package/server/procCore.mjs +178 -39
  71. package/server/procLang.mjs +270 -3
  72. package/server/syncKeep.mjs +239 -0
  73. package/server/tools/authRefsAudit.mjs +175 -0
  74. package/server/tools/authRefsClean.mjs +263 -0
  75. package/server/tools/fromTools.mjs +725 -0
  76. package/server/tools/isMain.mjs +31 -0
  77. package/server/tools/nameDupReport.mjs +208 -0
  78. package/server/wrapInjected.mjs +1 -1
  79. package/src/components/LayoutContentGrups.vue +396 -75
  80. package/src/components/LayoutContentPemis.vue +395 -75
  81. package/src/components/LayoutContentTargets.vue +261 -25
  82. package/src/components/LayoutContentUsers.vue +334 -97
  83. package/src/components/VeCgrups.vue +88 -129
  84. package/src/components/VeCpemis.vue +86 -129
  85. package/src/components/VeCrules.vue +15 -5
  86. package/src/components/VeGrupBlngUsers.vue +202 -89
  87. package/src/components/VePemiBlngGrups.vue +209 -99
  88. package/src/js/cvKpToObj.mjs +42 -31
  89. package/src/js/draftSync.mjs +70 -0
  90. package/src/js/eachOwn.mjs +1 -1
  91. package/src/js/editorRefRows.mjs +284 -0
  92. package/src/js/externalRows.mjs +266 -0
  93. package/src/js/externalUi.mjs +158 -0
  94. package/src/js/findRefRows.mjs +35 -0
  95. package/src/js/findTouchedDup.mjs +78 -0
  96. package/src/js/fromAudit.mjs +417 -0
  97. package/src/js/getAddImpact.mjs +197 -0
  98. package/src/js/getAuthWarn.mjs +391 -0
  99. package/src/js/getCascadePreview.mjs +186 -0
  100. package/src/js/getDelRefCount.mjs +138 -0
  101. package/src/js/getEffMode.mjs +20 -0
  102. package/src/js/getKpLossy.mjs +44 -49
  103. package/src/js/getNameErrs.mjs +194 -0
  104. package/src/js/getOwn.mjs +1 -1
  105. package/src/js/getPropKey.mjs +37 -0
  106. package/src/js/isAuthMode.mjs +2 -2
  107. package/src/js/pairRowsToSnapshot.mjs +84 -0
  108. package/src/js/refAudit.mjs +287 -0
  109. package/src/js/refCascade.mjs +500 -0
  110. package/src/js/relDialogSend.mjs +127 -0
  111. package/src/js/rowDigest.mjs +193 -0
  112. package/src/plugins/dataReloadGuard.mjs +37 -0
  113. package/src/plugins/mShare.mjs +144 -140
  114. package/src/plugins/mUI.mjs +3 -8
  115. package/src/schema/tables/users.mjs +152 -152
  116. package/dist/css/app.6918ec45.css +0 -1
  117. package/dist/js/app-legacy.7cb7e394.js +0 -1
  118. package/dist/js/app.7cb7e394.js +0 -1
  119. package/docs/src_js_getKeyOrderLost.mjs.html +0 -121
  120. package/docs/src_js_getKpWriteLost.mjs.html +0 -100
  121. package/docs/src_js_keepKeyOrder.mjs.html +0 -139
  122. package/src/js/getKeyOrderLost.mjs +0 -49
  123. package/src/js/getKpWriteLost.mjs +0 -28
  124. package/src/js/keepKeyOrder.mjs +0 -67
@@ -1,121 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
-
5
- <meta charset="utf-8">
6
- <title>src/js/getKeyOrderLost.mjs - Documentation</title>
7
-
8
-
9
- <script src="scripts/prettify/prettify.js"></script>
10
- <script src="scripts/prettify/lang-css.js"></script>
11
- <!--[if lt IE 9]>
12
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
- <![endif]-->
14
- <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
- <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
- <script src="scripts/nav.js" defer></script>
17
-
18
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
- </head>
20
- <body>
21
-
22
- <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
- <label for="nav-trigger" class="navicon-button x">
24
- <div class="navicon"></div>
25
- </label>
26
-
27
- <label for="nav-trigger" class="overlay"></label>
28
-
29
- <nav >
30
-
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#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
-
34
- </nav>
35
-
36
- <div id="main">
37
-
38
- <h1 class="page-title">src/js/getKeyOrderLost.mjs</h1>
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- <section>
47
- <article>
48
- <pre class="prettyprint source linenums"><code>import isAuthMode from './isAuthMode.mjs'
49
-
50
-
51
- /**
52
- * 判定欲寫出之物件 kpOut 的鍵序(JS 屬性序: 整數式鍵先排、遞增)是否與預期序 seq 不同, 使有效 AND 名稱之相對順序易位, 回傳受影響之 AND 名稱
53
- *
54
- * 編輯器以 keepKeyOrder 讓「原字串已有之名稱維持原序、新增者附加於後」, 但 JS 物件的整數式鍵(如群組名 '1')恆排在前面,
55
- * 新增(或新啟用)的整數式 AND 名稱會排到既有 AND 名稱之前, 使伺服端 mergeRules 在沒有有效 OR 項時的「第一個 AND 項」易位而改變授權(規則帳本 R-AUTH-LOSSY-01);
56
- * 此為編輯器無法在不改變授權下寫出的格, 須拒存並顯示固定訊息(authLossyBlocked).
57
- * 只看有效 AND 項(isActive 'y' 且 mode 'AND')之「第一個」是否易位: 欲寫出之物件只含現存之群組/權限(編輯器列出之列, 無查無實體之名稱被丟棄的問題),
58
- * mergeRules 的結果對 AND 項順序的依賴只經第一個 AND 項(其餘 AND 項彼此可交換), 故第一個不變則其後之相對順序改變不影響授權, 不需拒存(輸入側 getKpLossy 因幻影名稱須比整個相對順序, 見其說明).
59
- *
60
- * @param {Object} kpOut 輸入欲寫出之物件 { 名稱: { mode, isActive } }
61
- * @param {Array} seq 輸入預期的名稱順序(keepKeyOrder 之 keyOrderOf 結果)
62
- * @returns {Array} 回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入
63
- * @example
64
- *
65
- * let seq = ['A', '1']
66
- * let kpOut = { '1': { mode: 'AND', isActive: 'y' }, A: { mode: 'AND', isActive: 'y' } } //JS 把 '1' 排到 A 前面
67
- * console.log(getKeyOrderLost(kpOut, seq))
68
- * // => ['A', '1']
69
- *
70
- */
71
- function getKeyOrderLost(kpOut, seq) {
72
- if (kpOut === null || typeof kpOut !== 'object' || !Array.isArray(seq)) {
73
- return []
74
- }
75
- let isAnd = (n) => {
76
- let p = Object.prototype.hasOwnProperty.call(kpOut, n) ? kpOut[n] : null
77
- return p !== null &amp;&amp; typeof p === 'object' &amp;&amp; p.isActive === 'y' &amp;&amp; isAuthMode(p.mode) &amp;&amp; p.mode === 'AND'
78
- }
79
- //有任何有效 OR 項時, mergeRules 以 OR 聯集為基底、各 AND 項各鍵獨立相交, AND 項順序與授權無關(外審 minimax 第二輪#2: 否則多餘拒存)
80
- let hasOr = Object.keys(kpOut).some((n) => {
81
- let p = kpOut[n]
82
- return p !== null &amp;&amp; typeof p === 'object' &amp;&amp; p.isActive === 'y' &amp;&amp; p.mode === 'OR'
83
- })
84
- if (hasOr) {
85
- return []
86
- }
87
- let want = seq.filter((n) => isAnd(n))
88
- if (want.length &lt; 2) {
89
- return []
90
- }
91
- let got = Object.keys(kpOut).filter((n) => want.includes(n))
92
- return got[0] !== want[0] ? want : []
93
- }
94
-
95
-
96
- export default getKeyOrderLost
97
- </code></pre>
98
- </article>
99
- </section>
100
-
101
-
102
-
103
-
104
-
105
-
106
- </div>
107
-
108
- <br class="clear">
109
-
110
- <footer>
111
- 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.
112
- </footer>
113
-
114
- <script>prettyPrint();</script>
115
- <script src="scripts/polyfill.js"></script>
116
- <script src="scripts/linenumber.js"></script>
117
-
118
-
119
-
120
- </body>
121
- </html>
@@ -1,100 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
-
5
- <meta charset="utf-8">
6
- <title>src/js/getKpWriteLost.mjs - Documentation</title>
7
-
8
-
9
- <script src="scripts/prettify/prettify.js"></script>
10
- <script src="scripts/prettify/lang-css.js"></script>
11
- <!--[if lt IE 9]>
12
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
- <![endif]-->
14
- <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
- <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
- <script src="scripts/nav.js" defer></script>
17
-
18
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
- </head>
20
- <body>
21
-
22
- <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
- <label for="nav-trigger" class="navicon-button x">
24
- <div class="navicon"></div>
25
- </label>
26
-
27
- <label for="nav-trigger" class="overlay"></label>
28
-
29
- <nav >
30
-
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#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
-
34
- </nav>
35
-
36
- <div id="main">
37
-
38
- <h1 class="page-title">src/js/getKpWriteLost.mjs</h1>
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- <section>
47
- <article>
48
- <pre class="prettyprint source linenums"><code>import keepKeyOrder, { keyOrderOf } from './keepKeyOrder.mjs'
49
- import getKeyOrderLost from './getKeyOrderLost.mjs'
50
-
51
-
52
- /**
53
- * 判定欲寫出之授權物件 kpNew 以 keepKeyOrder(kpRef, kpNew) 寫出時, 鍵序是否被 JS 屬性序(整數式鍵恆先排)改變而使第一個有效 AND 項易位, 回傳受影響之 AND 名稱
54
- *
55
- * 四個帶 mode 的編輯器(VeCgrups/VeCpemis/VeGrupBlngUsers/VePemiBlngGrups)寫出前共用此函數(規則帳本 R-AUTH-LOSSY-01 ③): 預期序一律由「參考(解碼後之原資料)」與「欲寫出之物件」
56
- * 在此函數內導出, 呼叫端不得自行傳入預期序——外審 minimax 第二輪指出關聯對話框曾以「已套用 JS 屬性序之物件序」當預期序, 守門恆等而形同虛設.
57
- * kpRef 須為解碼後之原授權資料(cvKpToObj 之結果, 鍵序即伺服端序); kpNew 為欲寫出之物件(名稱 → { mode, isActive }).
58
- *
59
- * @param {Object} kpRef 輸入解碼後之原授權資料
60
- * @param {Object} kpNew 輸入欲寫出之物件
61
- * @returns {Array} 回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入
62
- * @example
63
- *
64
- * let kpRef = { A: { mode: 'AND', isActive: 'y' } }
65
- * let kpNew = { A: { mode: 'AND', isActive: 'y' }, 1: { mode: 'AND', isActive: 'y' } } //新啟用整數式名稱 1 為 AND
66
- * console.log(getKpWriteLost(kpRef, kpNew))
67
- * // => ['A', '1']
68
- *
69
- */
70
- function getKpWriteLost(kpRef, kpNew) {
71
- return getKeyOrderLost(keepKeyOrder(kpRef, kpNew), keyOrderOf(kpRef, kpNew))
72
- }
73
-
74
-
75
- export default getKpWriteLost
76
- </code></pre>
77
- </article>
78
- </section>
79
-
80
-
81
-
82
-
83
-
84
-
85
- </div>
86
-
87
- <br class="clear">
88
-
89
- <footer>
90
- 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.
91
- </footer>
92
-
93
- <script>prettyPrint();</script>
94
- <script src="scripts/polyfill.js"></script>
95
- <script src="scripts/linenumber.js"></script>
96
-
97
-
98
-
99
- </body>
100
- </html>
@@ -1,139 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
-
5
- <meta charset="utf-8">
6
- <title>src/js/keepKeyOrder.mjs - Documentation</title>
7
-
8
-
9
- <script src="scripts/prettify/prettify.js"></script>
10
- <script src="scripts/prettify/lang-css.js"></script>
11
- <!--[if lt IE 9]>
12
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
- <![endif]-->
14
- <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
- <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
- <script src="scripts/nav.js" defer></script>
17
-
18
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
- </head>
20
- <body>
21
-
22
- <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
- <label for="nav-trigger" class="navicon-button x">
24
- <div class="navicon"></div>
25
- </label>
26
-
27
- <label for="nav-trigger" class="overlay"></label>
28
-
29
- <nav >
30
-
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#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
-
34
- </nav>
35
-
36
- <div id="main">
37
-
38
- <h1 class="page-title">src/js/keepKeyOrder.mjs</h1>
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- <section>
47
- <article>
48
- <pre class="prettyprint source linenums"><code>import eachOwn from './eachOwn.mjs'
49
-
50
-
51
- /**
52
- * 以 kpRef 之鍵序重排 kpNew: 參考中已有之名稱維持參考序, 新增名稱附加於後(依 kpNew 序), kpNew 沒有之名稱(已刪除)不出現
53
- *
54
- * 編輯器寫出授權字串(cgrups/cpemis/crules)時使用(規則帳本 R-AUTH-ORDER-01): 伺服端 mergeRules 在沒有任何有效 OR 項時以「第一個 AND 項」為 AND 合併之起始,
55
- * 結果因鍵序而異, 編輯器若依對話框(群組表)順序重寫, 未改動之授權也會被改變(可增權可減權); 保留原鍵序使「存檔後授權不變」.
56
- * 值一律取 kpNew; 鍵為使用者資料(含 __proto__、constructor 等原型鍵名), 回傳無原型物件, 不改動輸入.
57
- * JS 物件屬性序使整數式鍵(如 '1'、'2')恆排在前面且遞增, 本函數無法改變(此類資料由 getKpLossy 判定, 見規則帳本 R-AUTH-LOSSY-01).
58
- *
59
- * @param {Object} kpRef 輸入參考物件(通常為 cvKpToObj 解碼後之原授權資料), 非物件(null、undefined、陣列、字串、數字)視為無參考
60
- * @param {Object} kpNew 輸入欲寫出之物件, 鍵為名稱
61
- * @returns {Object} 回傳無原型物件, 鍵序為參考序在前、新增在後
62
- * @example
63
- *
64
- * console.log(Object.keys(keepKeyOrder({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' })))
65
- * // => ['B', 'A', 'C']
66
- *
67
- */
68
- function keepKeyOrder(kpRef, kpNew) {
69
- let o = Object.create(null)
70
- eachOwn(keyOrderOf(kpRef, kpNew), (k) => {
71
- o[k] = kpNew[k]
72
- })
73
- return o
74
- }
75
-
76
-
77
- /**
78
- * keepKeyOrder 的預期名稱順序: 參考中已有之名稱依參考序在前, kpNew 新增之名稱依 kpNew 序附加於後; 以陣列回傳(不受 JS 屬性序影響)
79
- *
80
- * 輸出物件(keepKeyOrder)之鍵序受 JS 屬性序影響(整數式鍵恆先排), 與本函數的預期序可能不同, 差異影響有效 AND 項之相對順序者由 getKeyOrderLost 判定(編輯器拒存).
81
- *
82
- * @param {Object} kpRef 輸入參考物件, 非物件視為無參考
83
- * @param {Object} kpNew 輸入欲寫出之物件, 非物件回傳空陣列
84
- * @returns {Array} 回傳名稱陣列
85
- * @example
86
- *
87
- * console.log(keyOrderOf({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' }))
88
- * // => ['B', 'A', 'C']
89
- *
90
- */
91
- function keyOrderOf(kpRef, kpNew) {
92
- let isOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k)
93
- let names = []
94
- if (kpNew === null || typeof kpNew !== 'object' || Array.isArray(kpNew)) {
95
- return names
96
- }
97
- if (kpRef !== null &amp;&amp; typeof kpRef === 'object' &amp;&amp; !Array.isArray(kpRef)) {
98
- eachOwn(kpRef, (v, k) => {
99
- if (isOwn(kpNew, k)) {
100
- names.push(k)
101
- }
102
- })
103
- }
104
- eachOwn(kpNew, (v, k) => {
105
- if (!names.includes(k)) {
106
- names.push(k)
107
- }
108
- })
109
- return names
110
- }
111
-
112
-
113
- export { keyOrderOf }
114
- export default keepKeyOrder
115
- </code></pre>
116
- </article>
117
- </section>
118
-
119
-
120
-
121
-
122
-
123
-
124
- </div>
125
-
126
- <br class="clear">
127
-
128
- <footer>
129
- 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.
130
- </footer>
131
-
132
- <script>prettyPrint();</script>
133
- <script src="scripts/polyfill.js"></script>
134
- <script src="scripts/linenumber.js"></script>
135
-
136
-
137
-
138
- </body>
139
- </html>
@@ -1,49 +0,0 @@
1
- import isAuthMode from './isAuthMode.mjs'
2
-
3
-
4
- /**
5
- * 判定欲寫出之物件 kpOut 的鍵序(JS 屬性序: 整數式鍵先排、遞增)是否與預期序 seq 不同, 使有效 AND 名稱之相對順序易位, 回傳受影響之 AND 名稱
6
- *
7
- * 編輯器以 keepKeyOrder 讓「原字串已有之名稱維持原序、新增者附加於後」, 但 JS 物件的整數式鍵(如群組名 '1')恆排在前面,
8
- * 新增(或新啟用)的整數式 AND 名稱會排到既有 AND 名稱之前, 使伺服端 mergeRules 在沒有有效 OR 項時的「第一個 AND 項」易位而改變授權(規則帳本 R-AUTH-LOSSY-01);
9
- * 此為編輯器無法在不改變授權下寫出的格, 須拒存並顯示固定訊息(authLossyBlocked).
10
- * 只看有效 AND 項(isActive 'y' 且 mode 'AND')之「第一個」是否易位: 欲寫出之物件只含現存之群組/權限(編輯器列出之列, 無查無實體之名稱被丟棄的問題),
11
- * mergeRules 的結果對 AND 項順序的依賴只經第一個 AND 項(其餘 AND 項彼此可交換), 故第一個不變則其後之相對順序改變不影響授權, 不需拒存(輸入側 getKpLossy 因幻影名稱須比整個相對順序, 見其說明).
12
- *
13
- * @param {Object} kpOut 輸入欲寫出之物件 { 名稱: { mode, isActive } }
14
- * @param {Array} seq 輸入預期的名稱順序(keepKeyOrder 之 keyOrderOf 結果)
15
- * @returns {Array} 回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入
16
- * @example
17
- *
18
- * let seq = ['A', '1']
19
- * let kpOut = { '1': { mode: 'AND', isActive: 'y' }, A: { mode: 'AND', isActive: 'y' } } //JS 把 '1' 排到 A 前面
20
- * console.log(getKeyOrderLost(kpOut, seq))
21
- * // => ['A', '1']
22
- *
23
- */
24
- function getKeyOrderLost(kpOut, seq) {
25
- if (kpOut === null || typeof kpOut !== 'object' || !Array.isArray(seq)) {
26
- return []
27
- }
28
- let isAnd = (n) => {
29
- let p = Object.prototype.hasOwnProperty.call(kpOut, n) ? kpOut[n] : null
30
- return p !== null && typeof p === 'object' && p.isActive === 'y' && isAuthMode(p.mode) && p.mode === 'AND'
31
- }
32
- //有任何有效 OR 項時, mergeRules 以 OR 聯集為基底、各 AND 項各鍵獨立相交, AND 項順序與授權無關(外審 minimax 第二輪#2: 否則多餘拒存)
33
- let hasOr = Object.keys(kpOut).some((n) => {
34
- let p = kpOut[n]
35
- return p !== null && typeof p === 'object' && p.isActive === 'y' && p.mode === 'OR'
36
- })
37
- if (hasOr) {
38
- return []
39
- }
40
- let want = seq.filter((n) => isAnd(n))
41
- if (want.length < 2) {
42
- return []
43
- }
44
- let got = Object.keys(kpOut).filter((n) => want.includes(n))
45
- return got[0] !== want[0] ? want : []
46
- }
47
-
48
-
49
- export default getKeyOrderLost
@@ -1,28 +0,0 @@
1
- import keepKeyOrder, { keyOrderOf } from './keepKeyOrder.mjs'
2
- import getKeyOrderLost from './getKeyOrderLost.mjs'
3
-
4
-
5
- /**
6
- * 判定欲寫出之授權物件 kpNew 以 keepKeyOrder(kpRef, kpNew) 寫出時, 鍵序是否被 JS 屬性序(整數式鍵恆先排)改變而使第一個有效 AND 項易位, 回傳受影響之 AND 名稱
7
- *
8
- * 四個帶 mode 的編輯器(VeCgrups/VeCpemis/VeGrupBlngUsers/VePemiBlngGrups)寫出前共用此函數(規則帳本 R-AUTH-LOSSY-01 ③): 預期序一律由「參考(解碼後之原資料)」與「欲寫出之物件」
9
- * 在此函數內導出, 呼叫端不得自行傳入預期序——外審 minimax 第二輪指出關聯對話框曾以「已套用 JS 屬性序之物件序」當預期序, 守門恆等而形同虛設.
10
- * kpRef 須為解碼後之原授權資料(cvKpToObj 之結果, 鍵序即伺服端序); kpNew 為欲寫出之物件(名稱 → { mode, isActive }).
11
- *
12
- * @param {Object} kpRef 輸入解碼後之原授權資料
13
- * @param {Object} kpNew 輸入欲寫出之物件
14
- * @returns {Array} 回傳受影響之 AND 名稱(依預期序), 無易位回傳空陣列; 不改動輸入
15
- * @example
16
- *
17
- * let kpRef = { A: { mode: 'AND', isActive: 'y' } }
18
- * let kpNew = { A: { mode: 'AND', isActive: 'y' }, 1: { mode: 'AND', isActive: 'y' } } //新啟用整數式名稱 1 為 AND
19
- * console.log(getKpWriteLost(kpRef, kpNew))
20
- * // => ['A', '1']
21
- *
22
- */
23
- function getKpWriteLost(kpRef, kpNew) {
24
- return getKeyOrderLost(keepKeyOrder(kpRef, kpNew), keyOrderOf(kpRef, kpNew))
25
- }
26
-
27
-
28
- export default getKpWriteLost
@@ -1,67 +0,0 @@
1
- import eachOwn from './eachOwn.mjs'
2
-
3
-
4
- /**
5
- * 以 kpRef 之鍵序重排 kpNew: 參考中已有之名稱維持參考序, 新增名稱附加於後(依 kpNew 序), kpNew 沒有之名稱(已刪除)不出現
6
- *
7
- * 編輯器寫出授權字串(cgrups/cpemis/crules)時使用(規則帳本 R-AUTH-ORDER-01): 伺服端 mergeRules 在沒有任何有效 OR 項時以「第一個 AND 項」為 AND 合併之起始,
8
- * 結果因鍵序而異, 編輯器若依對話框(群組表)順序重寫, 未改動之授權也會被改變(可增權可減權); 保留原鍵序使「存檔後授權不變」.
9
- * 值一律取 kpNew; 鍵為使用者資料(含 __proto__、constructor 等原型鍵名), 回傳無原型物件, 不改動輸入.
10
- * JS 物件屬性序使整數式鍵(如 '1'、'2')恆排在前面且遞增, 本函數無法改變(此類資料由 getKpLossy 判定, 見規則帳本 R-AUTH-LOSSY-01).
11
- *
12
- * @param {Object} kpRef 輸入參考物件(通常為 cvKpToObj 解碼後之原授權資料), 非物件(null、undefined、陣列、字串、數字)視為無參考
13
- * @param {Object} kpNew 輸入欲寫出之物件, 鍵為名稱
14
- * @returns {Object} 回傳無原型物件, 鍵序為參考序在前、新增在後
15
- * @example
16
- *
17
- * console.log(Object.keys(keepKeyOrder({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' })))
18
- * // => ['B', 'A', 'C']
19
- *
20
- */
21
- function keepKeyOrder(kpRef, kpNew) {
22
- let o = Object.create(null)
23
- eachOwn(keyOrderOf(kpRef, kpNew), (k) => {
24
- o[k] = kpNew[k]
25
- })
26
- return o
27
- }
28
-
29
-
30
- /**
31
- * keepKeyOrder 的預期名稱順序: 參考中已有之名稱依參考序在前, kpNew 新增之名稱依 kpNew 序附加於後; 以陣列回傳(不受 JS 屬性序影響)
32
- *
33
- * 輸出物件(keepKeyOrder)之鍵序受 JS 屬性序影響(整數式鍵恆先排), 與本函數的預期序可能不同, 差異影響有效 AND 項之相對順序者由 getKeyOrderLost 判定(編輯器拒存).
34
- *
35
- * @param {Object} kpRef 輸入參考物件, 非物件視為無參考
36
- * @param {Object} kpNew 輸入欲寫出之物件, 非物件回傳空陣列
37
- * @returns {Array} 回傳名稱陣列
38
- * @example
39
- *
40
- * console.log(keyOrderOf({ B: 1, A: 2 }, { A: 'a', C: 'c', B: 'b' }))
41
- * // => ['B', 'A', 'C']
42
- *
43
- */
44
- function keyOrderOf(kpRef, kpNew) {
45
- let isOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k)
46
- let names = []
47
- if (kpNew === null || typeof kpNew !== 'object' || Array.isArray(kpNew)) {
48
- return names
49
- }
50
- if (kpRef !== null && typeof kpRef === 'object' && !Array.isArray(kpRef)) {
51
- eachOwn(kpRef, (v, k) => {
52
- if (isOwn(kpNew, k)) {
53
- names.push(k)
54
- }
55
- })
56
- }
57
- eachOwn(kpNew, (v, k) => {
58
- if (!names.includes(k)) {
59
- names.push(k)
60
- }
61
- })
62
- return names
63
- }
64
-
65
-
66
- export { keyOrderOf }
67
- export default keepKeyOrder