w-web-perm 1.1.13 → 1.1.15
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.
- package/README.md +98 -7
- package/dist/css/{app.f09c7433.css → app.f24c5e50.css} +1 -1
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.307bef4f.js +1 -0
- package/dist/js/app.307bef4f.js +1 -0
- package/dist/js/{chunk-vendors.ece5a361.js → chunk-vendors-legacy.6cc4d11e.js} +1 -1
- package/dist/js/{chunk-vendors-legacy.ece5a361.js → chunk-vendors.6cc4d11e.js} +1 -1
- package/dist/w-web-perm.umd.js +2 -2
- package/dist/w-web-perm.umd.js.map +1 -1
- package/docs/WWebPerm.html +15 -7
- package/docs/global.html +11733 -5078
- package/docs/index.html +2 -2
- package/docs/server_WWebPerm.mjs.html +154 -345
- package/docs/server_adminCheck.mjs.html +92 -0
- package/docs/server_cascadeWrite.mjs.html +5 -26
- package/docs/server_dataChannel.mjs.html +4 -4
- package/docs/server_keyCheck.mjs.html +150 -23
- package/docs/server_lockSave.mjs.html +2 -2
- package/docs/server_maskLog.mjs.html +2 -2
- package/docs/server_procCore.mjs.html +261 -65
- package/docs/server_staLogs_resolveShellWorker.mjs.html +2 -2
- package/docs/server_syncCore.mjs.html +533 -0
- package/docs/server_syncKeep.mjs.html +27 -20
- package/docs/server_tools_authRefsAudit.mjs.html +30 -10
- package/docs/server_tools_authRefsClean.mjs.html +2 -2
- package/docs/server_tools_fromTools.mjs.html +2 -2
- package/docs/server_tools_isMain.mjs.html +2 -2
- package/docs/server_tools_nameDupReport.mjs.html +40 -7
- package/docs/server_validateRows.mjs.html +2 -2
- package/docs/server_wrapInjected.mjs.html +2 -2
- package/docs/src_fetchJson.mjs.html +2 -2
- package/docs/src_getPermUserInfor.mjs.html +175 -0
- package/docs/src_js_applySaved.mjs.html +128 -0
- package/docs/src_js_cellEditing.mjs.html +163 -0
- package/docs/src_js_cvKpToArr.mjs.html +2 -2
- package/docs/src_js_cvKpToObj.mjs.html +2 -2
- package/docs/src_js_draftSync.mjs.html +83 -7
- package/docs/src_js_eachOwn.mjs.html +2 -2
- package/docs/src_js_editorRefRows.mjs.html +2 -2
- package/docs/src_js_externalRows.mjs.html +34 -10
- package/docs/src_js_externalUi.mjs.html +4 -8
- package/docs/src_js_findRefRows.mjs.html +2 -2
- package/docs/src_js_findTouchedDup.mjs.html +2 -2
- package/docs/src_js_fmtLossyMsg.mjs.html +2 -2
- package/docs/src_js_fromAudit.mjs.html +2 -2
- package/docs/src_js_getAddImpact.mjs.html +2 -2
- package/docs/src_js_getAuthWarn.mjs.html +2 -2
- package/docs/src_js_getCascadePreview.mjs.html +2 -2
- package/docs/src_js_getDelRefCount.mjs.html +2 -2
- package/docs/src_js_getEffMode.mjs.html +2 -2
- package/docs/src_js_getKpLossy.mjs.html +2 -2
- package/docs/src_js_getNameErrs.mjs.html +2 -2
- package/docs/src_js_getOwn.mjs.html +2 -2
- package/docs/src_js_getPropKey.mjs.html +2 -2
- package/docs/src_js_getRuleEnable.mjs.html +2 -2
- package/docs/src_js_isAuthMode.mjs.html +2 -2
- package/docs/src_js_joinNames.mjs.html +2 -2
- package/docs/src_js_legendFit.mjs.html +2 -2
- package/docs/src_js_pairRowsToSnapshot.mjs.html +2 -2
- package/docs/src_js_refAudit.mjs.html +2 -2
- package/docs/src_js_refCascade.mjs.html +2 -2
- package/docs/src_js_refIdentity.mjs.html +500 -0
- package/docs/src_js_relDialogSend.mjs.html +2 -2
- package/docs/src_js_rowDigest.mjs.html +75 -145
- package/docs/src_plugins_dataReloadGuard.mjs.html +2 -2
- package/docs/src_plugins_reuseDeletedIds.mjs.html +2 -2
- package/docs/src_plugins_submitGuard.mjs.html +2 -2
- package/g_provideGrups.mjs +1 -1
- package/g_providePemis.mjs +1 -1
- package/g_provideTargets.mjs +1 -1
- package/g_provideUsers.mjs +1 -1
- package/package.json +2 -2
- package/server/WWebPerm.mjs +152 -343
- package/server/adminCheck.mjs +20 -0
- package/server/cascadeWrite.mjs +3 -24
- package/server/dataChannel.mjs +2 -2
- package/server/keyCheck.mjs +148 -21
- package/server/procCore.mjs +259 -63
- package/server/procLang.mjs +78 -4
- package/server/provideTabs.mjs +6 -4
- package/server/syncCore.mjs +461 -0
- package/server/syncKeep.mjs +25 -18
- package/server/tools/authRefsAudit.mjs +28 -8
- package/server/tools/nameDupReport.mjs +38 -5
- package/src/App.vue +6 -1
- package/src/components/LayoutContentGrups.vue +57 -8
- package/src/components/LayoutContentPemis.vue +57 -8
- package/src/components/LayoutContentTargets.vue +38 -7
- package/src/components/LayoutContentUsers.vue +57 -8
- package/src/components/LayoutState.vue +12 -0
- package/src/components/VeGrupBlngUsers.vue +128 -20
- package/src/components/VePemiBlngGrups.vue +128 -20
- package/src/getPermUserInfor.mjs +10 -0
- package/src/js/applySaved.mjs +56 -0
- package/src/js/cellEditing.mjs +91 -0
- package/src/js/draftSync.mjs +81 -5
- package/src/js/externalRows.mjs +32 -8
- package/src/js/externalUi.mjs +2 -6
- package/src/js/refIdentity.mjs +428 -0
- package/src/js/rowDigest.mjs +73 -143
- package/src/plugins/mUI.mjs +5 -0
- package/src/schema/contracts/grups.mjs +8 -0
- package/src/schema/contracts/index.mjs +17 -0
- package/src/schema/contracts/pemis.mjs +8 -0
- package/src/schema/contracts/targets.mjs +8 -0
- package/src/schema/contracts/users.mjs +13 -0
- package/src/schema/tables/grups.mjs +4 -0
- package/src/schema/tables/pemis.mjs +4 -0
- package/src/schema/tables/targets.mjs +4 -0
- package/src/schema/tables/users.mjs +4 -0
- package/src/store/mutations.mjs +1 -1
- package/srv.mjs +43 -0
- package/dist/js/app-legacy.8af87052.js +0 -1
- package/dist/js/app.8af87052.js +0 -1
|
@@ -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#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#
|
|
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#activeNames">activeNames</a></li><li><a href="global.html#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#applySavedRows">applySavedRows</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#bindCellEditingStop">bindCellEditingStop</a></li><li><a href="global.html#bindCellEditingStopRetry">bindCellEditingStopRetry</a></li><li><a href="global.html#buildRefDecl">buildRefDecl</a></li><li><a href="global.html#buildReport">buildReport</a></li><li><a href="global.html#buildRowsSend">buildRowsSend</a></li><li><a href="global.html#checkBaseline">checkBaseline</a></li><li><a href="global.html#checkCascadePlan">checkCascadePlan</a></li><li><a href="global.html#checkDbNotInUse">checkDbNotInUse</a></li><li><a href="global.html#checkExternalWrite">checkExternalWrite</a></li><li><a href="global.html#checkMapKeyBatch">checkMapKeyBatch</a></li><li><a href="global.html#checkRefIdentity">checkRefIdentity</a></li><li><a href="global.html#checkSubject">checkSubject</a></li><li><a href="global.html#checkSubjectIdentity">checkSubjectIdentity</a></li><li><a href="global.html#checkUsersWrite">checkUsersWrite</a></li><li><a href="global.html#cleanOutOf">cleanOutOf</a></li><li><a href="global.html#collectChangedNames">collectChangedNames</a></li><li><a href="global.html#collectNewNames">collectNewNames</a></li><li><a href="global.html#compareBaseline">compareBaseline</a></li><li><a href="global.html#countAndRefs">countAndRefs</a></li><li><a href="global.html#countExternalRows">countExternalRows</a></li><li><a href="global.html#countRefMismatch">countRefMismatch</a></li><li><a href="global.html#countSrcKeyRenumber">countSrcKeyRenumber</a></li><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#diffRefTargets">diffRefTargets</a></li><li><a href="global.html#dropServerOnlyDiff">dropServerOnlyDiff</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#fillIdlessIds">fillIdlessIds</a></li><li><a href="global.html#findDupIndex">findDupIndex</a></li><li><a href="global.html#findKeyOtherFrom">findKeyOtherFrom</a></li><li><a href="global.html#findLoginIdClash">findLoginIdClash</a></li><li><a href="global.html#findLoginIdClashDetail">findLoginIdClashDetail</a></li><li><a href="global.html#findLoginUsers">findLoginUsers</a></li><li><a href="global.html#findRefRows">findRefRows</a></li><li><a href="global.html#findTouchedDup">findTouchedDup</a></li><li><a href="global.html#fmtLossyMsg">fmtLossyMsg</a></li><li><a href="global.html#fmtVars">fmtVars</a></li><li><a href="global.html#fmtWarn">fmtWarn</a></li><li><a href="global.html#formatFixReport">formatFixReport</a></li><li><a href="global.html#formatFromAudit">formatFromAudit</a></li><li><a href="global.html#formatPurgeReport">formatPurgeReport</a></li><li><a href="global.html#genLegend">genLegend</a></li><li><a href="global.html#getAddConfirmText">getAddConfirmText</a></li><li><a href="global.html#getAddImpact">getAddImpact</a></li><li><a href="global.html#getBannerLines">getBannerLines</a></li><li><a href="global.html#getCascadePreview">getCascadePreview</a></li><li><a href="global.html#getChangedIdx">getChangedIdx</a></li><li><a href="global.html#getContract">getContract</a></li><li><a href="global.html#getDelConfirmText">getDelConfirmText</a></li><li><a href="global.html#getDelImpact">getDelImpact</a></li><li><a href="global.html#getDelRefCount">getDelRefCount</a></li><li><a href="global.html#getDupRowsInconsistent">getDupRowsInconsistent</a></li><li><a href="global.html#getEffMode">getEffMode</a></li><li><a href="global.html#getExternalEdits">getExternalEdits</a></li><li><a href="global.html#getItemWarnText">getItemWarnText</a></li><li><a href="global.html#getKpLossy">getKpLossy</a></li><li><a href="global.html#getLockFields">getLockFields</a></li><li><a href="global.html#getNameErrs">getNameErrs</a></li><li><a href="global.html#getOwn">getOwn</a></li><li><a href="global.html#getPermUserInfor">getPermUserInfor</a></li><li><a href="global.html#getPropKey">getPropKey</a></li><li><a href="global.html#getRawModeMap">getRawModeMap</a></li><li><a href="global.html#getRefRowsExtra">getRefRowsExtra</a></li><li><a href="global.html#getRefState">getRefState</a></li><li><a href="global.html#getRefTarget">getRefTarget</a></li><li><a href="global.html#getRefWarnText">getRefWarnText</a></li><li><a href="global.html#getRefWarns">getRefWarns</a></li><li><a href="global.html#getRowIdxs">getRowIdxs</a></li><li><a href="global.html#getRowState">getRowState</a></li><li><a href="global.html#getRuleEnable">getRuleEnable</a></li><li><a href="global.html#getRuleWarnText">getRuleWarnText</a></li><li><a href="global.html#getRuleWarns">getRuleWarns</a></li><li><a href="global.html#getSavePreview">getSavePreview</a></li><li><a href="global.html#getSavedTables">getSavedTables</a></li><li><a href="global.html#getSyncWarnLines">getSyncWarnLines</a></li><li><a href="global.html#hasDraftNow">hasDraftNow</a></li><li><a href="global.html#hasDupKey">hasDupKey</a></li><li><a href="global.html#hasExternalDiff">hasExternalDiff</a></li><li><a href="global.html#idsOfName">idsOfName</a></li><li><a href="global.html#isAdminRow">isAdminRow</a></li><li><a href="global.html#isAuthMode">isAuthMode</a></li><li><a href="global.html#isBaselineStale">isBaselineStale</a></li><li><a href="global.html#isCellEditing">isCellEditing</a></li><li><a href="global.html#isDraftStale">isDraftStale</a></li><li><a href="global.html#isExternalRow">isExternalRow</a></li><li><a href="global.html#isJsonLossy">isJsonLossy</a></li><li><a href="global.html#isMain">isMain</a></li><li><a href="global.html#isSameFile">isSameFile</a></li><li><a href="global.html#joinList">joinList</a></li><li><a href="global.html#joinNames">joinNames</a></li><li><a href="global.html#keepAssignByEntity">keepAssignByEntity</a></li><li><a href="global.html#keepAssignOnMissing">keepAssignOnMissing</a></li><li><a href="global.html#loginIdOf">loginIdOf</a></li><li><a href="global.html#makeBaseline">makeBaseline</a></li><li><a href="global.html#makeRowStates">makeRowStates</a></li><li><a href="global.html#mapKeyOf">mapKeyOf</a></li><li><a href="global.html#mapNameKp">mapNameKp</a></li><li><a href="global.html#markDataReload">markDataReload</a></li><li><a href="global.html#markHasKey">markHasKey</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#newActiveNames">newActiveNames</a></li><li><a href="global.html#pairRowsToSnapshot">pairRowsToSnapshot</a></li><li><a href="global.html#parseRefDecl">parseRefDecl</a></li><li><a href="global.html#parseSubject">parseSubject</a></li><li><a href="global.html#pickClientOpt">pickClientOpt</a></li><li><a href="global.html#pickUniqueUser">pickUniqueUser</a></li><li><a href="global.html#planDialogSync">planDialogSync</a></li><li><a href="global.html#planDraftSync">planDraftSync</a></li><li><a href="global.html#planFixFromType">planFixFromType</a></li><li><a href="global.html#planPurgeChain">planPurgeChain</a></li><li><a href="global.html#planPurgeFrom">planPurgeFrom</a></li><li><a href="global.html#planRefChanges">planRefChanges</a></li><li><a href="global.html#putRefEntry">putRefEntry</a></li><li><a href="global.html#putRowsToKp">putRowsToKp</a></li><li><a href="global.html#recordPicks">recordPicks</a></li><li><a href="global.html#refsChanged">refsChanged</a></li><li><a href="global.html#removedActiveNames">removedActiveNames</a></li><li><a href="global.html#resolveShellWorker">resolveShellWorker</a></li><li><a href="global.html#restoreExternalOrder">restoreExternalOrder</a></li><li><a href="global.html#restoreServerFields">restoreServerFields</a></li><li><a href="global.html#reuseDeletedIds">reuseDeletedIds</a></li><li><a href="global.html#rewriteRefs">rewriteRefs</a></li><li><a href="global.html#runAuditFrom">runAuditFrom</a></li><li><a href="global.html#runClean">runClean</a></li><li><a href="global.html#runFixFromType">runFixFromType</a></li><li><a href="global.html#runPurgeFrom">runPurgeFrom</a></li><li><a href="global.html#snapRefIds">snapRefIds</a></li><li><a href="global.html#splitCheckedRows">splitCheckedRows</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#syncCore">syncCore</a></li><li><a href="global.html#validateRowsBeforeWrite">validateRowsBeforeWrite</a></li><li><a href="global.html#withTabLocks">withTabLocks</a></li><li><a href="global.html#wrapInjected">wrapInjected</a></li><li><a href="global.html#wrapOperOrm">wrapOperOrm</a></li><li><a href="global.html#writeWithCascade">writeWithCascade</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -51,6 +51,8 @@ import findTouchedDup from '../src/js/findTouchedDup.mjs' //判準單一擁有
|
|
|
51
51
|
|
|
52
52
|
//名稱唯一(F-02)與使用者對應鍵(F-14)之判準, 單一擁有者(規則帳本 R-NAME-UNIQ-01/02、R-MAPKEY-01/02/03, ADR-034):
|
|
53
53
|
// 外部同步(WWebPerm.mjs:syncAndReplaceTabs)、後台整表寫入(procCore.mjs:updateTabItems)、登入查找(WWebPerm.mjs:getTokenUser/getGenUserByKV)只呼叫本檔, 不複製判準.
|
|
54
|
+
//同表寫入互斥(外審 sol R10): 外部同步與後台整表寫入對同一張表須共用同一把鎖(否則兩者各自「先檢查名稱/對應鍵、後寫入」可交錯而略過 F-02/F-14);
|
|
55
|
+
//perm-run01 起該鎖即 w-serv-orm 實例之 withTabLocks(每表一鍵), 由下方 withTabLocks 以階層巢狀取得, 不再有套內自建之鎖鍵(tabWriteKey 已移除).
|
|
54
56
|
//比對一律精確 ===(與伺服端 arrFinder 與 getTokenUser 之 select 一致; 不做大小寫/空白正規化: 正規化後比對會放行伺服端視為不同之名稱, 或拒絕伺服端視為不同之鍵).
|
|
55
57
|
//鍵之值非字串者不參與重複比對(空/非字串另由呼叫端之 isestr 檢查負責). 以 Map/Set 計, 免原型鍵名(constructor、__proto__)誤判(規則帳本 R-KEY-01).
|
|
56
58
|
|
|
@@ -144,37 +146,26 @@ function findKeyOtherFrom(rows, rowsExist, from, key, opt = {}) {
|
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
*
|
|
152
|
-
* @param {String} keyTable 表名
|
|
153
|
-
* @returns {String} 回傳 kmx 鍵
|
|
154
|
-
*/
|
|
155
|
-
function tabWriteKey(keyTable) {
|
|
156
|
-
return 'tabWrite:' + keyTable
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
//取鎖階層(規則帳本 R-WRITE-LOCK-02, ADR-036): 引用鏈序「被引用者先、引用端後」targets → pemis → grups → users(引用端之階層恆高於被引用者); 所有需持多把表鎖之路徑(後台整表寫入、外部同步、日後之外部列保護/清源)只能經 withTabLocks 取鎖,
|
|
161
|
-
//同一把鎖不巢狀(pmKeyMutex 非可重入, 巢狀同鍵與相反次序皆死結, D1 設計稿 probe-mutex 實測); 持鎖後才讀取、預檢與寫入, 使預檢與寫入涵蓋同一版本(外審 A.3)
|
|
149
|
+
//取鎖階層(規則帳本 R-WRITE-LOCK-02, ADR-036; perm-run01 起鎖管理器改為 w-serv-orm 實例之 withTabLocks, R-LOCK-CORE-01): 引用鏈序「被引用者先、引用端後」targets → pemis → grups → users(引用端之階層恆高於被引用者);
|
|
150
|
+
//所有寫入入口(後台整表寫入、外部同步、引用連帶之引用端寫入)取得的是**同一個**鎖管理器(WServOrm 回傳之 withTabLocks, 每表一鍵、不可重入), 與 w-serv-orm 之 guardWrite 共鎖.
|
|
151
|
+
//多把表鎖一律由外而內「依階層」逐表巢狀取鎖(每層一次只宣告一張表), 不使用核心之多表一次宣告(其碼元序與階層序不同, 混用即成環);
|
|
152
|
+
//同一把鎖不巢狀, 持鎖後才讀取、預檢與寫入, 使預檢與寫入涵蓋同一版本(外審 A.3)
|
|
162
153
|
let TAB_LOCK_RANK = { targets: 0, pemis: 1, grups: 2, users: 3 }
|
|
163
154
|
|
|
164
155
|
|
|
165
156
|
/**
|
|
166
|
-
* 依取鎖階層取齊指定表鎖後執行 fn(單一取鎖函數): 表名去重、依 targets → pemis → grups → users 排序(階層外之表名排最後、彼此依字典序), 由外而內巢狀取
|
|
157
|
+
* 依取鎖階層取齊指定表鎖後執行 fn(單一取鎖函數): 表名去重、依 targets → pemis → grups → users 排序(階層外之表名排最後、彼此依字典序), 由外而內巢狀取 lockTabs([表]);
|
|
167
158
|
* 各路徑取鎖次序一致故不成環.
|
|
168
159
|
* 分段取鎖: 先取被引用表之鎖、依該表之新舊資料判定須改寫引用端後, 才在內層以 held 指明已持之表再取引用端表之鎖(寫入引用端表不涉改名/刪除者免取, 免無謂之互等);
|
|
169
160
|
* held 非空時, keyTables 之階層須全數高於 held(否則拋錯, 即違反階層, 不嘗試取鎖).
|
|
170
161
|
*
|
|
171
|
-
* @param {Function}
|
|
162
|
+
* @param {Function} lockTabs 輸入 w-serv-orm 實例之 withTabLocks(tableNames, fn)
|
|
172
163
|
* @param {Array} keyTables 輸入須持鎖之表名陣列
|
|
173
164
|
* @param {Function} fn 輸入持鎖後執行之 async 函數
|
|
174
165
|
* @param {Array} [held=[]] 輸入呼叫端已持有鎖之表名陣列(內層分段取鎖用)
|
|
175
166
|
* @returns {Promise} 回傳 fn 之結果
|
|
176
167
|
*/
|
|
177
|
-
function withTabLocks(
|
|
168
|
+
function withTabLocks(lockTabs, keyTables, fn, held = []) {
|
|
178
169
|
let rank = (t) => (Object.prototype.hasOwnProperty.call(TAB_LOCK_RANK, t) ? TAB_LOCK_RANK[t] : Infinity)
|
|
179
170
|
let ts = [...new Set(keyTables)].sort((a, b) => (rank(a) - rank(b)) || (a < b ? -1 : (a > b ? 1 : 0)))
|
|
180
171
|
if (held.length > 0) {
|
|
@@ -186,8 +177,8 @@ function withTabLocks(kmx, keyTables, fn, held = []) {
|
|
|
186
177
|
let run = fn
|
|
187
178
|
for (let k = ts.length - 1; k >= 0; k--) {
|
|
188
179
|
let inner = run
|
|
189
|
-
let
|
|
190
|
-
run = () =>
|
|
180
|
+
let t = ts[k]
|
|
181
|
+
run = () => lockTabs([t], inner)
|
|
191
182
|
}
|
|
192
183
|
return run()
|
|
193
184
|
}
|
|
@@ -325,7 +316,143 @@ function pickUniqueUser(rs) {
|
|
|
325
316
|
}
|
|
326
317
|
|
|
327
318
|
|
|
328
|
-
|
|
319
|
+
//users 登入對應 mappingBy='id' 之 O1 規則(perm-run04, 規則帳本 R-MAPKEY-04; 規格 dspec/外部匯入之定義與機制.md 第 9 節末, 主控 2026-10-24 定案):
|
|
320
|
+
// 外部列(from 非空)以外部 token 之使用者 id 對 srcKey(其 id 是本系統配發之內部主鍵, 不是登入識別), 後台列(from 空)對 id.
|
|
321
|
+
// perm-run05(主控 2026-10-24 收件裁示): 登入識別值須跨全表唯一, 「不論 isActive」「含他來源」: 不同外部系統之使用者 id 碰撞常見而非同一人, 且停用列可被重新啟用,
|
|
322
|
+
// 故「只有一列有效」不得放行(否則已停用者之 token 會對到他來源之有效列). 撞值之組合: 同一登入識別值出現在兩列, 且該對不是「兩後台列」(同一主鍵)、「同一來源皆有 srcKey 之兩外部列」(srcKeyDuplicate/srcKeyConflict 於同步端另拒)與「同一來源皆無 srcKey 之兩舊外部列」(同一主鍵); 詳見 findLoginIdClashDetail.
|
|
323
|
+
// 匯入批次、後台存檔、登入三處皆拒(原則 3 收嚴+提示、原則 4 所有入口一致); 登入時命中多筆(不論有效與否)即拒絕, 恰 1 筆且停用視同查無.
|
|
324
|
+
// 判準(loginIdOf/findLoginUsers/findLoginIdClashDetail)單一擁有者在本檔; 外部同步(syncCore.mjs)、後台整表寫入(procCore.mjs)、登入查找與 getPermUserInfor(WWebPerm.mjs)只呼叫本檔.
|
|
325
|
+
let isObj = (v) => v !== null && typeof v === 'object' && !Array.isArray(v)
|
|
326
|
+
let isEStr = (v) => isStr(v) && v.length > 0
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* users 列在 mappingBy='id' 下的登入識別值: 後台列(from 空)為 id; 外部列(from 非空)為 srcKey;
|
|
331
|
+
* 遷移前之舊外部列(升版前同步寫入、尚無 srcKey)暫以 id(與升版前行為相同, 首次匯入依規格補上 srcKey 後即改以 srcKey).
|
|
332
|
+
*
|
|
333
|
+
* @param {Object} row users 列
|
|
334
|
+
* @returns {String} 登入識別值; 無可用鍵(非物件、id 空或非字串)為 ''
|
|
335
|
+
*/
|
|
336
|
+
function loginIdOf(row) {
|
|
337
|
+
if (!isObj(row)) {
|
|
338
|
+
return ''
|
|
339
|
+
}
|
|
340
|
+
if (isEStr(row.from) && isEStr(row.srcKey)) {
|
|
341
|
+
return row.srcKey
|
|
342
|
+
}
|
|
343
|
+
return isEStr(row.id) ? row.id : ''
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* 登入查找(getTokenUser/getPermUserInfor): 回 { user, count }(僅恰 1 筆有效列時 user 為該列, 多筆不取首筆).
|
|
349
|
+
* 'email'/'name': 以該欄位查 perm users 中有效(isActive='y')之列(不變, 同 pickUniqueUser).
|
|
350
|
+
* 其餘(含預設 'id'): 後台列對 id、外部列對 srcKey(見上方 O1 規則), 「不論 isActive」計筆(perm-run05): 兩次帶條件之 select(id、srcKey 各一; 不帶 isActive, 不做全表讀取),
|
|
351
|
+
* 合併去重後以 loginIdOf 複判; 多於 1 筆 → count 為筆數、user 為 null(不以「只有一列有效」放行); 恰 1 筆且有效 → 該列; 恰 1 筆但停用 → count 0(視同查無).
|
|
352
|
+
* ORM 讀取失敗原樣拋出(不吞成 0 筆).
|
|
353
|
+
*
|
|
354
|
+
* @param {Object} tabUsers 輸入 users 表之 ORM 物件(select)
|
|
355
|
+
* @param {String} mappingBy 'id'|'email'|'name'(其他值視同 'id')
|
|
356
|
+
* @param {String} vSelf 外部 token 之使用者對應值(須為非空字串)
|
|
357
|
+
* @returns {Promise<Object>} { user, count }
|
|
358
|
+
*/
|
|
359
|
+
async function findLoginUsers(tabUsers, mappingBy, vSelf) {
|
|
360
|
+
let key = mapKeyOf(mappingBy)
|
|
361
|
+
if (key !== null) {
|
|
362
|
+
return pickUniqueUser(await tabUsers.select({ [key]: vSelf, isActive: 'y' }))
|
|
363
|
+
}
|
|
364
|
+
let rsId = await tabUsers.select({ id: vSelf })
|
|
365
|
+
let rsSrc = await tabUsers.select({ srcKey: vSelf })
|
|
366
|
+
let kp = new Map() //以 id 去重(srcKey 等於 id 之遷移後外部列會被兩次查詢各命中一次)
|
|
367
|
+
for (let r of [...(Array.isArray(rsId) ? rsId : []), ...(Array.isArray(rsSrc) ? rsSrc : [])]) {
|
|
368
|
+
if (isObj(r) && isEStr(r.id)) {
|
|
369
|
+
kp.set(r.id, r)
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
let hits = [...kp.values()].filter((r) => loginIdOf(r) === vSelf)
|
|
373
|
+
if (hits.length === 1 && hits[0].isActive !== 'y') {
|
|
374
|
+
return { user: null, count: 0 }
|
|
375
|
+
}
|
|
376
|
+
return pickUniqueUser(hits)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* 登入識別撞值(mappingBy='id'): 回傳寫入後之表 rowsAfter 中第一個「被本次觸及」之列, 其登入識別值(loginIdOf)與另一列相同且屬撞值組合者之細節, 無則 null.
|
|
382
|
+
* 「不論 isActive」「含他來源」(perm-run05): 撞值組合=同一登入識別值出現在兩列, 且該對不是下列三種不屬登入識別撞值者:
|
|
383
|
+
* - 兩後台列(登入識別值=主鍵 id, 同一主鍵於表中不可並存);
|
|
384
|
+
* - 同一來源(from 相同)之兩外部列且皆有 srcKey(srcKeyDuplicate/srcKeyConflict 於同步端另拒);
|
|
385
|
+
* - 同一來源之兩舊外部列(皆無 srcKey, 登入識別值=id, 即同一主鍵).
|
|
386
|
+
* 撞值之種類:
|
|
387
|
+
* - adminId: 一為後台列(from 空)、一為外部列(其 srcKey; 舊外部列無 srcKey 者為其 id)相同;
|
|
388
|
+
* - otherFrom: 兩外部列來源不同而登入識別值相同;
|
|
389
|
+
* - sameFrom: 同一來源之兩外部列, 一有 srcKey、一為舊形(無 srcKey, 以其 id 為登入識別)而該 id 等於對方 srcKey——即同步端之 claimTwice(srcKeyConflict), 登入亦命中兩筆
|
|
390
|
+
* (後台新增外部形列只在 lockExternalRows 為假時可能; 外審 sol 第一輪#1).
|
|
391
|
+
* 歷史既有(未被觸及)之撞值不擋(否則已有歷史資料之庫無法在後台修復; 同 R-MAPKEY-03). 外部列之內部 id(有 srcKey 者)不是登入識別, 不參與.
|
|
392
|
+
*
|
|
393
|
+
* @param {Array} rowsAfter 寫入後之 users 全表(後台整表寫入為送入之整表; 外部匯入為「他 from 之列+本批」)
|
|
394
|
+
* @param {Function} isTouched (row, index) → Boolean, 該列是否為本次造成或觸及
|
|
395
|
+
* @returns {Object|null} { k, kOther, kind: 'adminId'|'otherFrom'|'sameFrom' }(k 為第一個被觸及且撞值之列索引, kOther 為與之撞值的另一列中索引最小者), 無則 null
|
|
396
|
+
*/
|
|
397
|
+
function findLoginIdClashDetail(rowsAfter, isTouched) {
|
|
398
|
+
if (!Array.isArray(rowsAfter)) {
|
|
399
|
+
return null
|
|
400
|
+
}
|
|
401
|
+
let groups = new Map() //登入識別值 → 列索引陣列(以 Map 計, 免原型鍵名誤判)
|
|
402
|
+
rowsAfter.forEach((r, k) => {
|
|
403
|
+
let v = loginIdOf(r)
|
|
404
|
+
if (v === '') {
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
if (!groups.has(v)) {
|
|
408
|
+
groups.set(v, [])
|
|
409
|
+
}
|
|
410
|
+
groups.get(v).push(k)
|
|
411
|
+
})
|
|
412
|
+
for (let k = 0; k < rowsAfter.length; k++) {
|
|
413
|
+
let r = rowsAfter[k]
|
|
414
|
+
let v = loginIdOf(r)
|
|
415
|
+
if (v === '' || !isTouched(r, k)) {
|
|
416
|
+
continue
|
|
417
|
+
}
|
|
418
|
+
let rx = isEStr(r.from)
|
|
419
|
+
for (let kOther of groups.get(v)) {
|
|
420
|
+
if (kOther === k) {
|
|
421
|
+
continue
|
|
422
|
+
}
|
|
423
|
+
let o = rowsAfter[kOther]
|
|
424
|
+
let ox = isEStr(o.from)
|
|
425
|
+
if (!rx && !ox) {
|
|
426
|
+
continue
|
|
427
|
+
}
|
|
428
|
+
if (rx && ox && r.from === o.from) {
|
|
429
|
+
//同一來源: 皆有 srcKey 或皆無 srcKey 者不在此判; 一有一無(claimTwice 形)才撞
|
|
430
|
+
if (isEStr(r.srcKey) === isEStr(o.srcKey)) {
|
|
431
|
+
continue
|
|
432
|
+
}
|
|
433
|
+
return { k, kOther, kind: 'sameFrom' }
|
|
434
|
+
}
|
|
435
|
+
return { k, kOther, kind: (rx && ox) ? 'otherFrom' : 'adminId' }
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return null
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* 登入識別撞值(mappingBy='id'): findLoginIdClashDetail 之索引版, 回第一個被觸及且撞值之列索引, 無則 -1
|
|
444
|
+
*
|
|
445
|
+
* @param {Array} rowsAfter 寫入後之 users 全表
|
|
446
|
+
* @param {Function} isTouched (row, index) → Boolean, 該列是否為本次造成或觸及
|
|
447
|
+
* @returns {Number} 撞值列之索引, 無為 -1
|
|
448
|
+
*/
|
|
449
|
+
function findLoginIdClash(rowsAfter, isTouched) {
|
|
450
|
+
let d = findLoginIdClashDetail(rowsAfter, isTouched)
|
|
451
|
+
return d === null ? -1 : d.k
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
export { findDupIndex, hasDupKey, findKeyOtherFrom, findTouchedDup, withTabLocks, mapKeyOf, checkMapKeyBatch, checkUsersWrite, pickUniqueUser, loginIdOf, findLoginUsers, findLoginIdClash, findLoginIdClashDetail }
|
|
329
456
|
</code></pre>
|
|
330
457
|
</article>
|
|
331
458
|
</section>
|
|
@@ -340,7 +467,7 @@ export { findDupIndex, hasDupKey, findKeyOtherFrom, findTouchedDup, tabWriteKey,
|
|
|
340
467
|
<br class="clear">
|
|
341
468
|
|
|
342
469
|
<footer>
|
|
343
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
470
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Oct 24 2026 17:35:35 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
344
471
|
</footer>
|
|
345
472
|
|
|
346
473
|
<script>prettyPrint();</script>
|
|
@@ -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#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#
|
|
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#activeNames">activeNames</a></li><li><a href="global.html#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#applySavedRows">applySavedRows</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#bindCellEditingStop">bindCellEditingStop</a></li><li><a href="global.html#bindCellEditingStopRetry">bindCellEditingStopRetry</a></li><li><a href="global.html#buildRefDecl">buildRefDecl</a></li><li><a href="global.html#buildReport">buildReport</a></li><li><a href="global.html#buildRowsSend">buildRowsSend</a></li><li><a href="global.html#checkBaseline">checkBaseline</a></li><li><a href="global.html#checkCascadePlan">checkCascadePlan</a></li><li><a href="global.html#checkDbNotInUse">checkDbNotInUse</a></li><li><a href="global.html#checkExternalWrite">checkExternalWrite</a></li><li><a href="global.html#checkMapKeyBatch">checkMapKeyBatch</a></li><li><a href="global.html#checkRefIdentity">checkRefIdentity</a></li><li><a href="global.html#checkSubject">checkSubject</a></li><li><a href="global.html#checkSubjectIdentity">checkSubjectIdentity</a></li><li><a href="global.html#checkUsersWrite">checkUsersWrite</a></li><li><a href="global.html#cleanOutOf">cleanOutOf</a></li><li><a href="global.html#collectChangedNames">collectChangedNames</a></li><li><a href="global.html#collectNewNames">collectNewNames</a></li><li><a href="global.html#compareBaseline">compareBaseline</a></li><li><a href="global.html#countAndRefs">countAndRefs</a></li><li><a href="global.html#countExternalRows">countExternalRows</a></li><li><a href="global.html#countRefMismatch">countRefMismatch</a></li><li><a href="global.html#countSrcKeyRenumber">countSrcKeyRenumber</a></li><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#diffRefTargets">diffRefTargets</a></li><li><a href="global.html#dropServerOnlyDiff">dropServerOnlyDiff</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#fillIdlessIds">fillIdlessIds</a></li><li><a href="global.html#findDupIndex">findDupIndex</a></li><li><a href="global.html#findKeyOtherFrom">findKeyOtherFrom</a></li><li><a href="global.html#findLoginIdClash">findLoginIdClash</a></li><li><a href="global.html#findLoginIdClashDetail">findLoginIdClashDetail</a></li><li><a href="global.html#findLoginUsers">findLoginUsers</a></li><li><a href="global.html#findRefRows">findRefRows</a></li><li><a href="global.html#findTouchedDup">findTouchedDup</a></li><li><a href="global.html#fmtLossyMsg">fmtLossyMsg</a></li><li><a href="global.html#fmtVars">fmtVars</a></li><li><a href="global.html#fmtWarn">fmtWarn</a></li><li><a href="global.html#formatFixReport">formatFixReport</a></li><li><a href="global.html#formatFromAudit">formatFromAudit</a></li><li><a href="global.html#formatPurgeReport">formatPurgeReport</a></li><li><a href="global.html#genLegend">genLegend</a></li><li><a href="global.html#getAddConfirmText">getAddConfirmText</a></li><li><a href="global.html#getAddImpact">getAddImpact</a></li><li><a href="global.html#getBannerLines">getBannerLines</a></li><li><a href="global.html#getCascadePreview">getCascadePreview</a></li><li><a href="global.html#getChangedIdx">getChangedIdx</a></li><li><a href="global.html#getContract">getContract</a></li><li><a href="global.html#getDelConfirmText">getDelConfirmText</a></li><li><a href="global.html#getDelImpact">getDelImpact</a></li><li><a href="global.html#getDelRefCount">getDelRefCount</a></li><li><a href="global.html#getDupRowsInconsistent">getDupRowsInconsistent</a></li><li><a href="global.html#getEffMode">getEffMode</a></li><li><a href="global.html#getExternalEdits">getExternalEdits</a></li><li><a href="global.html#getItemWarnText">getItemWarnText</a></li><li><a href="global.html#getKpLossy">getKpLossy</a></li><li><a href="global.html#getLockFields">getLockFields</a></li><li><a href="global.html#getNameErrs">getNameErrs</a></li><li><a href="global.html#getOwn">getOwn</a></li><li><a href="global.html#getPermUserInfor">getPermUserInfor</a></li><li><a href="global.html#getPropKey">getPropKey</a></li><li><a href="global.html#getRawModeMap">getRawModeMap</a></li><li><a href="global.html#getRefRowsExtra">getRefRowsExtra</a></li><li><a href="global.html#getRefState">getRefState</a></li><li><a href="global.html#getRefTarget">getRefTarget</a></li><li><a href="global.html#getRefWarnText">getRefWarnText</a></li><li><a href="global.html#getRefWarns">getRefWarns</a></li><li><a href="global.html#getRowIdxs">getRowIdxs</a></li><li><a href="global.html#getRowState">getRowState</a></li><li><a href="global.html#getRuleEnable">getRuleEnable</a></li><li><a href="global.html#getRuleWarnText">getRuleWarnText</a></li><li><a href="global.html#getRuleWarns">getRuleWarns</a></li><li><a href="global.html#getSavePreview">getSavePreview</a></li><li><a href="global.html#getSavedTables">getSavedTables</a></li><li><a href="global.html#getSyncWarnLines">getSyncWarnLines</a></li><li><a href="global.html#hasDraftNow">hasDraftNow</a></li><li><a href="global.html#hasDupKey">hasDupKey</a></li><li><a href="global.html#hasExternalDiff">hasExternalDiff</a></li><li><a href="global.html#idsOfName">idsOfName</a></li><li><a href="global.html#isAdminRow">isAdminRow</a></li><li><a href="global.html#isAuthMode">isAuthMode</a></li><li><a href="global.html#isBaselineStale">isBaselineStale</a></li><li><a href="global.html#isCellEditing">isCellEditing</a></li><li><a href="global.html#isDraftStale">isDraftStale</a></li><li><a href="global.html#isExternalRow">isExternalRow</a></li><li><a href="global.html#isJsonLossy">isJsonLossy</a></li><li><a href="global.html#isMain">isMain</a></li><li><a href="global.html#isSameFile">isSameFile</a></li><li><a href="global.html#joinList">joinList</a></li><li><a href="global.html#joinNames">joinNames</a></li><li><a href="global.html#keepAssignByEntity">keepAssignByEntity</a></li><li><a href="global.html#keepAssignOnMissing">keepAssignOnMissing</a></li><li><a href="global.html#loginIdOf">loginIdOf</a></li><li><a href="global.html#makeBaseline">makeBaseline</a></li><li><a href="global.html#makeRowStates">makeRowStates</a></li><li><a href="global.html#mapKeyOf">mapKeyOf</a></li><li><a href="global.html#mapNameKp">mapNameKp</a></li><li><a href="global.html#markDataReload">markDataReload</a></li><li><a href="global.html#markHasKey">markHasKey</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#newActiveNames">newActiveNames</a></li><li><a href="global.html#pairRowsToSnapshot">pairRowsToSnapshot</a></li><li><a href="global.html#parseRefDecl">parseRefDecl</a></li><li><a href="global.html#parseSubject">parseSubject</a></li><li><a href="global.html#pickClientOpt">pickClientOpt</a></li><li><a href="global.html#pickUniqueUser">pickUniqueUser</a></li><li><a href="global.html#planDialogSync">planDialogSync</a></li><li><a href="global.html#planDraftSync">planDraftSync</a></li><li><a href="global.html#planFixFromType">planFixFromType</a></li><li><a href="global.html#planPurgeChain">planPurgeChain</a></li><li><a href="global.html#planPurgeFrom">planPurgeFrom</a></li><li><a href="global.html#planRefChanges">planRefChanges</a></li><li><a href="global.html#putRefEntry">putRefEntry</a></li><li><a href="global.html#putRowsToKp">putRowsToKp</a></li><li><a href="global.html#recordPicks">recordPicks</a></li><li><a href="global.html#refsChanged">refsChanged</a></li><li><a href="global.html#removedActiveNames">removedActiveNames</a></li><li><a href="global.html#resolveShellWorker">resolveShellWorker</a></li><li><a href="global.html#restoreExternalOrder">restoreExternalOrder</a></li><li><a href="global.html#restoreServerFields">restoreServerFields</a></li><li><a href="global.html#reuseDeletedIds">reuseDeletedIds</a></li><li><a href="global.html#rewriteRefs">rewriteRefs</a></li><li><a href="global.html#runAuditFrom">runAuditFrom</a></li><li><a href="global.html#runClean">runClean</a></li><li><a href="global.html#runFixFromType">runFixFromType</a></li><li><a href="global.html#runPurgeFrom">runPurgeFrom</a></li><li><a href="global.html#snapRefIds">snapRefIds</a></li><li><a href="global.html#splitCheckedRows">splitCheckedRows</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#syncCore">syncCore</a></li><li><a href="global.html#validateRowsBeforeWrite">validateRowsBeforeWrite</a></li><li><a href="global.html#withTabLocks">withTabLocks</a></li><li><a href="global.html#wrapInjected">wrapInjected</a></li><li><a href="global.html#wrapOperOrm">wrapOperOrm</a></li><li><a href="global.html#writeWithCascade">writeWithCascade</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -102,7 +102,7 @@ export default createLockSave
|
|
|
102
102
|
<br class="clear">
|
|
103
103
|
|
|
104
104
|
<footer>
|
|
105
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
105
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Oct 24 2026 17:35:35 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
106
106
|
</footer>
|
|
107
107
|
|
|
108
108
|
<script>prettyPrint();</script>
|
|
@@ -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#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#
|
|
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#activeNames">activeNames</a></li><li><a href="global.html#applyPurgePlan">applyPurgePlan</a></li><li><a href="global.html#applySavedRows">applySavedRows</a></li><li><a href="global.html#auditFrom">auditFrom</a></li><li><a href="global.html#auditRefs">auditRefs</a></li><li><a href="global.html#bindCellEditingStop">bindCellEditingStop</a></li><li><a href="global.html#bindCellEditingStopRetry">bindCellEditingStopRetry</a></li><li><a href="global.html#buildRefDecl">buildRefDecl</a></li><li><a href="global.html#buildReport">buildReport</a></li><li><a href="global.html#buildRowsSend">buildRowsSend</a></li><li><a href="global.html#checkBaseline">checkBaseline</a></li><li><a href="global.html#checkCascadePlan">checkCascadePlan</a></li><li><a href="global.html#checkDbNotInUse">checkDbNotInUse</a></li><li><a href="global.html#checkExternalWrite">checkExternalWrite</a></li><li><a href="global.html#checkMapKeyBatch">checkMapKeyBatch</a></li><li><a href="global.html#checkRefIdentity">checkRefIdentity</a></li><li><a href="global.html#checkSubject">checkSubject</a></li><li><a href="global.html#checkSubjectIdentity">checkSubjectIdentity</a></li><li><a href="global.html#checkUsersWrite">checkUsersWrite</a></li><li><a href="global.html#cleanOutOf">cleanOutOf</a></li><li><a href="global.html#collectChangedNames">collectChangedNames</a></li><li><a href="global.html#collectNewNames">collectNewNames</a></li><li><a href="global.html#compareBaseline">compareBaseline</a></li><li><a href="global.html#countAndRefs">countAndRefs</a></li><li><a href="global.html#countExternalRows">countExternalRows</a></li><li><a href="global.html#countRefMismatch">countRefMismatch</a></li><li><a href="global.html#countSrcKeyRenumber">countSrcKeyRenumber</a></li><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#diffRefTargets">diffRefTargets</a></li><li><a href="global.html#dropServerOnlyDiff">dropServerOnlyDiff</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#fillIdlessIds">fillIdlessIds</a></li><li><a href="global.html#findDupIndex">findDupIndex</a></li><li><a href="global.html#findKeyOtherFrom">findKeyOtherFrom</a></li><li><a href="global.html#findLoginIdClash">findLoginIdClash</a></li><li><a href="global.html#findLoginIdClashDetail">findLoginIdClashDetail</a></li><li><a href="global.html#findLoginUsers">findLoginUsers</a></li><li><a href="global.html#findRefRows">findRefRows</a></li><li><a href="global.html#findTouchedDup">findTouchedDup</a></li><li><a href="global.html#fmtLossyMsg">fmtLossyMsg</a></li><li><a href="global.html#fmtVars">fmtVars</a></li><li><a href="global.html#fmtWarn">fmtWarn</a></li><li><a href="global.html#formatFixReport">formatFixReport</a></li><li><a href="global.html#formatFromAudit">formatFromAudit</a></li><li><a href="global.html#formatPurgeReport">formatPurgeReport</a></li><li><a href="global.html#genLegend">genLegend</a></li><li><a href="global.html#getAddConfirmText">getAddConfirmText</a></li><li><a href="global.html#getAddImpact">getAddImpact</a></li><li><a href="global.html#getBannerLines">getBannerLines</a></li><li><a href="global.html#getCascadePreview">getCascadePreview</a></li><li><a href="global.html#getChangedIdx">getChangedIdx</a></li><li><a href="global.html#getContract">getContract</a></li><li><a href="global.html#getDelConfirmText">getDelConfirmText</a></li><li><a href="global.html#getDelImpact">getDelImpact</a></li><li><a href="global.html#getDelRefCount">getDelRefCount</a></li><li><a href="global.html#getDupRowsInconsistent">getDupRowsInconsistent</a></li><li><a href="global.html#getEffMode">getEffMode</a></li><li><a href="global.html#getExternalEdits">getExternalEdits</a></li><li><a href="global.html#getItemWarnText">getItemWarnText</a></li><li><a href="global.html#getKpLossy">getKpLossy</a></li><li><a href="global.html#getLockFields">getLockFields</a></li><li><a href="global.html#getNameErrs">getNameErrs</a></li><li><a href="global.html#getOwn">getOwn</a></li><li><a href="global.html#getPermUserInfor">getPermUserInfor</a></li><li><a href="global.html#getPropKey">getPropKey</a></li><li><a href="global.html#getRawModeMap">getRawModeMap</a></li><li><a href="global.html#getRefRowsExtra">getRefRowsExtra</a></li><li><a href="global.html#getRefState">getRefState</a></li><li><a href="global.html#getRefTarget">getRefTarget</a></li><li><a href="global.html#getRefWarnText">getRefWarnText</a></li><li><a href="global.html#getRefWarns">getRefWarns</a></li><li><a href="global.html#getRowIdxs">getRowIdxs</a></li><li><a href="global.html#getRowState">getRowState</a></li><li><a href="global.html#getRuleEnable">getRuleEnable</a></li><li><a href="global.html#getRuleWarnText">getRuleWarnText</a></li><li><a href="global.html#getRuleWarns">getRuleWarns</a></li><li><a href="global.html#getSavePreview">getSavePreview</a></li><li><a href="global.html#getSavedTables">getSavedTables</a></li><li><a href="global.html#getSyncWarnLines">getSyncWarnLines</a></li><li><a href="global.html#hasDraftNow">hasDraftNow</a></li><li><a href="global.html#hasDupKey">hasDupKey</a></li><li><a href="global.html#hasExternalDiff">hasExternalDiff</a></li><li><a href="global.html#idsOfName">idsOfName</a></li><li><a href="global.html#isAdminRow">isAdminRow</a></li><li><a href="global.html#isAuthMode">isAuthMode</a></li><li><a href="global.html#isBaselineStale">isBaselineStale</a></li><li><a href="global.html#isCellEditing">isCellEditing</a></li><li><a href="global.html#isDraftStale">isDraftStale</a></li><li><a href="global.html#isExternalRow">isExternalRow</a></li><li><a href="global.html#isJsonLossy">isJsonLossy</a></li><li><a href="global.html#isMain">isMain</a></li><li><a href="global.html#isSameFile">isSameFile</a></li><li><a href="global.html#joinList">joinList</a></li><li><a href="global.html#joinNames">joinNames</a></li><li><a href="global.html#keepAssignByEntity">keepAssignByEntity</a></li><li><a href="global.html#keepAssignOnMissing">keepAssignOnMissing</a></li><li><a href="global.html#loginIdOf">loginIdOf</a></li><li><a href="global.html#makeBaseline">makeBaseline</a></li><li><a href="global.html#makeRowStates">makeRowStates</a></li><li><a href="global.html#mapKeyOf">mapKeyOf</a></li><li><a href="global.html#mapNameKp">mapNameKp</a></li><li><a href="global.html#markDataReload">markDataReload</a></li><li><a href="global.html#markHasKey">markHasKey</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#newActiveNames">newActiveNames</a></li><li><a href="global.html#pairRowsToSnapshot">pairRowsToSnapshot</a></li><li><a href="global.html#parseRefDecl">parseRefDecl</a></li><li><a href="global.html#parseSubject">parseSubject</a></li><li><a href="global.html#pickClientOpt">pickClientOpt</a></li><li><a href="global.html#pickUniqueUser">pickUniqueUser</a></li><li><a href="global.html#planDialogSync">planDialogSync</a></li><li><a href="global.html#planDraftSync">planDraftSync</a></li><li><a href="global.html#planFixFromType">planFixFromType</a></li><li><a href="global.html#planPurgeChain">planPurgeChain</a></li><li><a href="global.html#planPurgeFrom">planPurgeFrom</a></li><li><a href="global.html#planRefChanges">planRefChanges</a></li><li><a href="global.html#putRefEntry">putRefEntry</a></li><li><a href="global.html#putRowsToKp">putRowsToKp</a></li><li><a href="global.html#recordPicks">recordPicks</a></li><li><a href="global.html#refsChanged">refsChanged</a></li><li><a href="global.html#removedActiveNames">removedActiveNames</a></li><li><a href="global.html#resolveShellWorker">resolveShellWorker</a></li><li><a href="global.html#restoreExternalOrder">restoreExternalOrder</a></li><li><a href="global.html#restoreServerFields">restoreServerFields</a></li><li><a href="global.html#reuseDeletedIds">reuseDeletedIds</a></li><li><a href="global.html#rewriteRefs">rewriteRefs</a></li><li><a href="global.html#runAuditFrom">runAuditFrom</a></li><li><a href="global.html#runClean">runClean</a></li><li><a href="global.html#runFixFromType">runFixFromType</a></li><li><a href="global.html#runPurgeFrom">runPurgeFrom</a></li><li><a href="global.html#snapRefIds">snapRefIds</a></li><li><a href="global.html#splitCheckedRows">splitCheckedRows</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#syncCore">syncCore</a></li><li><a href="global.html#validateRowsBeforeWrite">validateRowsBeforeWrite</a></li><li><a href="global.html#withTabLocks">withTabLocks</a></li><li><a href="global.html#wrapInjected">wrapInjected</a></li><li><a href="global.html#wrapOperOrm">wrapOperOrm</a></li><li><a href="global.html#writeWithCascade">writeWithCascade</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -163,7 +163,7 @@ export {
|
|
|
163
163
|
<br class="clear">
|
|
164
164
|
|
|
165
165
|
<footer>
|
|
166
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
166
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Oct 24 2026 17:35:35 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
167
167
|
</footer>
|
|
168
168
|
|
|
169
169
|
<script>prettyPrint();</script>
|