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.
- package/README.md +158 -123
- package/dist/css/app.f09c7433.css +1 -0
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.8af87052.js +1 -0
- package/dist/js/app.8af87052.js +1 -0
- package/dist/js/{chunk-vendors.3e9e3ef1.js → chunk-vendors-legacy.ece5a361.js} +1 -1
- package/dist/js/{chunk-vendors-legacy.3e9e3ef1.js → chunk-vendors.ece5a361.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 +84 -4
- package/docs/global.html +23023 -1125
- package/docs/index.html +2 -2
- package/docs/server_WWebPerm.mjs.html +232 -32
- package/docs/server_cascadeWrite.mjs.html +225 -0
- package/docs/server_dataChannel.mjs.html +2 -2
- package/docs/server_keyCheck.mjs.html +353 -0
- package/docs/server_lockSave.mjs.html +2 -2
- package/docs/server_maskLog.mjs.html +2 -2
- package/docs/server_procCore.mjs.html +180 -41
- package/docs/server_staLogs_resolveShellWorker.mjs.html +2 -2
- package/docs/server_syncKeep.mjs.html +311 -0
- package/docs/server_tools_authRefsAudit.mjs.html +247 -0
- package/docs/server_tools_authRefsClean.mjs.html +335 -0
- package/docs/server_tools_fromTools.mjs.html +797 -0
- package/docs/server_tools_isMain.mjs.html +103 -0
- package/docs/server_tools_nameDupReport.mjs.html +280 -0
- package/docs/server_validateRows.mjs.html +2 -2
- package/docs/server_wrapInjected.mjs.html +3 -3
- package/docs/src_fetchJson.mjs.html +2 -2
- package/docs/src_js_cvKpToArr.mjs.html +2 -2
- package/docs/src_js_cvKpToObj.mjs.html +44 -33
- package/docs/src_js_draftSync.mjs.html +142 -0
- package/docs/src_js_eachOwn.mjs.html +3 -3
- package/docs/src_js_editorRefRows.mjs.html +356 -0
- package/docs/src_js_externalRows.mjs.html +338 -0
- package/docs/src_js_externalUi.mjs.html +230 -0
- package/docs/src_js_findRefRows.mjs.html +107 -0
- package/docs/src_js_findTouchedDup.mjs.html +150 -0
- package/docs/src_js_fmtLossyMsg.mjs.html +2 -2
- package/docs/src_js_fromAudit.mjs.html +489 -0
- package/docs/src_js_getAddImpact.mjs.html +269 -0
- package/docs/src_js_getAuthWarn.mjs.html +463 -0
- package/docs/src_js_getCascadePreview.mjs.html +258 -0
- package/docs/src_js_getDelRefCount.mjs.html +210 -0
- package/docs/src_js_getEffMode.mjs.html +92 -0
- package/docs/src_js_getKpLossy.mjs.html +47 -52
- package/docs/src_js_getNameErrs.mjs.html +266 -0
- package/docs/src_js_getOwn.mjs.html +3 -3
- package/docs/src_js_getPropKey.mjs.html +109 -0
- package/docs/src_js_getRuleEnable.mjs.html +2 -2
- package/docs/src_js_isAuthMode.mjs.html +4 -4
- 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 +156 -0
- package/docs/src_js_refAudit.mjs.html +359 -0
- package/docs/src_js_refCascade.mjs.html +572 -0
- package/docs/src_js_relDialogSend.mjs.html +199 -0
- package/docs/src_js_rowDigest.mjs.html +265 -0
- package/docs/src_plugins_dataReloadGuard.mjs.html +109 -0
- package/docs/src_plugins_reuseDeletedIds.mjs.html +2 -2
- package/docs/src_plugins_submitGuard.mjs.html +2 -2
- package/g_authRefsClean.mjs +79 -0
- package/g_fixFromType.mjs +92 -0
- package/g_initialData.mjs +3 -3
- package/g_purgeFrom.mjs +127 -0
- package/package.json +1 -1
- package/server/WWebPerm.mjs +230 -30
- package/server/cascadeWrite.mjs +153 -0
- package/server/keyCheck.mjs +281 -0
- package/server/procCore.mjs +178 -39
- package/server/procLang.mjs +270 -3
- package/server/syncKeep.mjs +239 -0
- package/server/tools/authRefsAudit.mjs +175 -0
- package/server/tools/authRefsClean.mjs +263 -0
- package/server/tools/fromTools.mjs +725 -0
- package/server/tools/isMain.mjs +31 -0
- package/server/tools/nameDupReport.mjs +208 -0
- package/server/wrapInjected.mjs +1 -1
- package/src/components/LayoutContentGrups.vue +396 -75
- package/src/components/LayoutContentPemis.vue +395 -75
- package/src/components/LayoutContentTargets.vue +261 -25
- package/src/components/LayoutContentUsers.vue +334 -97
- package/src/components/VeCgrups.vue +88 -129
- package/src/components/VeCpemis.vue +86 -129
- package/src/components/VeCrules.vue +15 -5
- package/src/components/VeGrupBlngUsers.vue +202 -89
- package/src/components/VePemiBlngGrups.vue +209 -99
- package/src/js/cvKpToObj.mjs +42 -31
- package/src/js/draftSync.mjs +70 -0
- package/src/js/eachOwn.mjs +1 -1
- package/src/js/editorRefRows.mjs +284 -0
- package/src/js/externalRows.mjs +266 -0
- package/src/js/externalUi.mjs +158 -0
- package/src/js/findRefRows.mjs +35 -0
- package/src/js/findTouchedDup.mjs +78 -0
- package/src/js/fromAudit.mjs +417 -0
- package/src/js/getAddImpact.mjs +197 -0
- package/src/js/getAuthWarn.mjs +391 -0
- package/src/js/getCascadePreview.mjs +186 -0
- package/src/js/getDelRefCount.mjs +138 -0
- package/src/js/getEffMode.mjs +20 -0
- package/src/js/getKpLossy.mjs +44 -49
- package/src/js/getNameErrs.mjs +194 -0
- package/src/js/getOwn.mjs +1 -1
- package/src/js/getPropKey.mjs +37 -0
- package/src/js/isAuthMode.mjs +2 -2
- package/src/js/pairRowsToSnapshot.mjs +84 -0
- package/src/js/refAudit.mjs +287 -0
- package/src/js/refCascade.mjs +500 -0
- package/src/js/relDialogSend.mjs +127 -0
- package/src/js/rowDigest.mjs +193 -0
- package/src/plugins/dataReloadGuard.mjs +37 -0
- package/src/plugins/mShare.mjs +144 -140
- package/src/plugins/mUI.mjs +3 -8
- package/src/schema/tables/users.mjs +152 -152
- package/dist/css/app.6918ec45.css +0 -1
- package/dist/js/app-legacy.7cb7e394.js +0 -1
- package/dist/js/app.7cb7e394.js +0 -1
- package/docs/src_js_getKeyOrderLost.mjs.html +0 -121
- package/docs/src_js_getKpWriteLost.mjs.html +0 -100
- package/docs/src_js_keepKeyOrder.mjs.html +0 -139
- package/src/js/getKeyOrderLost.mjs +0 -49
- package/src/js/getKpWriteLost.mjs +0 -28
- package/src/js/keepKeyOrder.mjs +0 -67
|
@@ -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#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#
|
|
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#buildReport">buildReport</a></li><li><a href="global.html#buildRowsSend">buildRowsSend</a></li><li><a href="global.html#buildSyncRowsNew">buildSyncRowsNew</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#checkUsersWrite">checkUsersWrite</a></li><li><a href="global.html#cleanOutOf">cleanOutOf</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#countIdRenumber">countIdRenumber</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#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#getBaselineDigest">getBaselineDigest</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#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#getDigestFields">getDigestFields</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#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#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#getSyncWarnLines">getSyncWarnLines</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#isAuthMode">isAuthMode</a></li><li><a href="global.html#isBaselineStale">isBaselineStale</a></li><li><a href="global.html#isBaselineValid">isBaselineValid</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#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#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#pairRowsToSnapshot">pairRowsToSnapshot</a></li><li><a href="global.html#pickUniqueUser">pickUniqueUser</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#refsChanged">refsChanged</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#rowDigest">rowDigest</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#splitCheckedRows">splitCheckedRows</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#tabWriteKey">tabWriteKey</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
|
|
|
@@ -123,7 +123,7 @@ export default reuseDeletedIds
|
|
|
123
123
|
<br class="clear">
|
|
124
124
|
|
|
125
125
|
<footer>
|
|
126
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
126
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Oct 23 2026 10:56:39 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
127
127
|
</footer>
|
|
128
128
|
|
|
129
129
|
<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#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#
|
|
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#buildReport">buildReport</a></li><li><a href="global.html#buildRowsSend">buildRowsSend</a></li><li><a href="global.html#buildSyncRowsNew">buildSyncRowsNew</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#checkUsersWrite">checkUsersWrite</a></li><li><a href="global.html#cleanOutOf">cleanOutOf</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#countIdRenumber">countIdRenumber</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#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#getBaselineDigest">getBaselineDigest</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#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#getDigestFields">getDigestFields</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#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#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#getSyncWarnLines">getSyncWarnLines</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#isAuthMode">isAuthMode</a></li><li><a href="global.html#isBaselineStale">isBaselineStale</a></li><li><a href="global.html#isBaselineValid">isBaselineValid</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#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#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#pairRowsToSnapshot">pairRowsToSnapshot</a></li><li><a href="global.html#pickUniqueUser">pickUniqueUser</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#refsChanged">refsChanged</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#rowDigest">rowDigest</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#splitCheckedRows">splitCheckedRows</a></li><li><a href="global.html#submitGuard">submitGuard</a></li><li><a href="global.html#tabWriteKey">tabWriteKey</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
|
|
|
@@ -150,7 +150,7 @@ export default submitGuard
|
|
|
150
150
|
<br class="clear">
|
|
151
151
|
|
|
152
152
|
<footer>
|
|
153
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
153
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Oct 23 2026 10:56:39 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
154
154
|
</footer>
|
|
155
155
|
|
|
156
156
|
<script>prettyPrint();</script>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import WOrm from 'w-orm-lmdb/src/WOrmLmdb.mjs'
|
|
4
|
+
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
5
|
+
import ds from './src/schema/index.mjs'
|
|
6
|
+
import getSettings from './g_getSettings.mjs'
|
|
7
|
+
import { runClean } from './server/tools/authRefsClean.mjs'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
//懸空引用之一次性清理(升版工具; 適用表 n 上線前之舊資料可能已有查無實體之引用: users.cgrups 引用不存在之群組、grups.cpemis 引用不存在之權限、pemis.crules 引用不存在之管控對象 id)
|
|
11
|
+
//效果等同舊版「找不到即忽略」: 把懸空項目自授權字串移除(不論 isActive); 經 ORM 寫入, 只改該欄位.
|
|
12
|
+
//
|
|
13
|
+
//用法(自專案根):
|
|
14
|
+
// node g_authRefsClean.mjs 只列不改(預設): 連專案資料庫(./db)稽核並輸出報告
|
|
15
|
+
// node g_authRefsClean.mjs --apply 寫入: 先備份資料庫(backup-時間.json, 於工作目錄)與將改寫之三張引用端表全部列(./authRefsClean-backup-時間.json), 任一備份失敗即中止、不寫入; 寫完重新稽核, 應為 0 懸空
|
|
16
|
+
// node g_authRefsClean.mjs --apply --backup <檔> 指定引用端表備份檔路徑(不覆寫既有檔)
|
|
17
|
+
// node g_authRefsClean.mjs --db <資料夾> 覆寫資料庫位置(同 g_getSettings 之 dbUrl; 資料庫名稱仍為 dbName), 供測試用臨時資料庫; 資料夾不存在即中止(不憑空建立空庫)
|
|
18
|
+
//離線版(只讀匯出檔、不連庫): node server/tools/authRefsAudit.mjs <匯出檔.json> [--json] [--clean-out <檔>]
|
|
19
|
+
//
|
|
20
|
+
//不清理者(報告列為「須人工處理」, 非失敗): 壞 JSON、名稱非字串之引用、缺字串主鍵之列, 以及含 JSON5 Infinity/NaN 數值而命中須改寫之授權欄位(JSON.stringify 會把它編成 null, 作規則名時改指別的規則); 寫後重新稽核時其懸空項為已知殘留.
|
|
21
|
+
//--backup 路徑以 wx 建立: 同名既有檔(含資料庫檔、別名——大小寫不同、相對/絕對、硬連結)一律拒絕、不覆寫, 失敗於備份階段(零寫入).
|
|
22
|
+
//離開碼: 0 成功(含只列不改與無須清理); 1 失敗(備份失敗、資料於稽核後被改動、寫入有 ok:0、寫後重稽核不為 0 等, 報告會列出); 2 參數錯誤.
|
|
23
|
+
//建議於停服(或無人編輯)時 --apply, 完成後重啟服務. 備份檔含 email 等個資, 請妥善保管、勿外傳、勿納入版控.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
let args = process.argv.slice(2)
|
|
28
|
+
let flag = (k) => args.includes(k)
|
|
29
|
+
let val = (k) => {
|
|
30
|
+
let i = args.indexOf(k)
|
|
31
|
+
return i >= 0 ? args[i + 1] : undefined
|
|
32
|
+
}
|
|
33
|
+
let known = ['--apply', '--backup', '--db', '--help']
|
|
34
|
+
let bad = args.filter((a, k) => (a.startsWith('--') ? !known.includes(a) : !(k > 0 && ['--backup', '--db'].includes(args[k - 1]))))
|
|
35
|
+
let missing = ['--backup', '--db'].some((k) => flag(k) && (val(k) === undefined || val(k).startsWith('--')))
|
|
36
|
+
if (flag('--help') || bad.length > 0 || missing) {
|
|
37
|
+
console.log('用法: node g_authRefsClean.mjs [--apply] [--backup <檔>] [--db <資料夾>]')
|
|
38
|
+
process.exitCode = flag('--help') ? 0 : 2
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//連線: 預設走 g_mOrm.mjs(專案資料庫, 動態載入——靜態 import 會於載入時即開啟 ./db); --db 則依指定資料夾自建(WServOrm 組裝同 g_mOrm.mjs)
|
|
43
|
+
let st = getSettings()
|
|
44
|
+
let url = flag('--db') ? val('--db') : st.dbUrl
|
|
45
|
+
if (!fs.existsSync(path.join(url, st.dbName))) {
|
|
46
|
+
console.log(`資料庫不存在: ${path.resolve(url, st.dbName)}(不憑空建立空庫, 已中止)`)
|
|
47
|
+
process.exitCode = 1
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
let woItems = null
|
|
51
|
+
let closeAll = null
|
|
52
|
+
if (flag('--db')) {
|
|
53
|
+
let r = WServOrm(ds, WOrm, url, st.dbName)
|
|
54
|
+
woItems = r.woItems
|
|
55
|
+
closeAll = r.closeAll
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
woItems = (await import('./g_mOrm.mjs')).woItems
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
let res = await runClean({ woItems, apply: flag('--apply'), backupPath: val('--backup') })
|
|
63
|
+
if (!res.ok) {
|
|
64
|
+
process.exitCode = 1
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
if (closeAll) {
|
|
69
|
+
await closeAll()
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
main()
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
console.log('authRefsClean catch', err)
|
|
78
|
+
process.exitCode = 1 //失敗以非 0 離開碼表達(規則帳本 R-SEED-01、R-ERR-01: 未 await 之 promise 於源頭 catch)
|
|
79
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import WOrm from 'w-orm-lmdb/src/WOrmLmdb.mjs'
|
|
4
|
+
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
5
|
+
import ds from './src/schema/index.mjs'
|
|
6
|
+
import getSettings from './g_getSettings.mjs'
|
|
7
|
+
import { checkDbNotInUse, runFixFromType } from './server/tools/fromTools.mjs'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
//來源欄 from 之型別正規化(升版工具; F-23 外部列受保護, 規則帳本 R-PRINCIPLE-00 原則 5): 升版後後台寫入起拒收非字串 from, 既有資料中 from 為 null/數字/布林/物件/陣列者須先正規化為 ''(後台列).
|
|
11
|
+
//外部列=from 為非空字串者; ''、缺欄、非字串皆為後台列, 故本工具只把「非字串」改為 '', 不改變任何列是否為外部列; 缺欄視同 ''(已是後台列), 不改; 非空字串(外部列)不動.
|
|
12
|
+
//經 ORM 寫入, 只改 from 欄(不動其餘欄位與更新者/更新時間).
|
|
13
|
+
//
|
|
14
|
+
//用法(自專案根):
|
|
15
|
+
// node g_fixFromType.mjs 只列不改(預設): 連專案資料庫(./db)列出各表非字串 from 之列數、型別分佈與前 10 個 id
|
|
16
|
+
// node g_fixFromType.mjs --apply 寫入: 後端須先停止(偵測到資料庫被占用即拒絕); 先備份資料庫(backup-時間.json, 於工作目錄)與四表全部列(./fixFromType-backup-時間.json), 任一備份失敗即中止、不寫入; 寫完回讀驗證(預期結果逐位元相同、已無非字串 from)
|
|
17
|
+
// node g_fixFromType.mjs --apply --backup <檔> 指定四表備份檔路徑(不覆寫既有檔)
|
|
18
|
+
// node g_fixFromType.mjs --db <資料夾> 覆寫資料庫位置(同 g_getSettings 之 dbUrl; 資料庫名稱仍為 dbName), 供測試用臨時資料庫; 資料夾不存在即中止(不憑空建立空庫)
|
|
19
|
+
//
|
|
20
|
+
//後端占用偵測(--apply 時, 於開啟資料庫之前; 僅 Windows 可偵測, 其他平台請自行確認後端已停止): 被占用即拒絕、零寫入(離開碼 1).
|
|
21
|
+
//冪等: 失敗後修正原因可原樣重跑; 已正規化者不再出現. 備份檔含 email 等個資, 請妥善保管、勿外傳、勿納入版控.
|
|
22
|
+
//離開碼: 0 成功(含只列不改與無須修正); 1 失敗(資料庫不存在、被占用、備份失敗、資料於稽核後被改動、寫入有失敗、寫後驗證不符等, 報告會列出); 2 參數錯誤.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
let args = process.argv.slice(2)
|
|
27
|
+
let flag = (k) => args.includes(k)
|
|
28
|
+
let val = (k) => {
|
|
29
|
+
let i = args.indexOf(k)
|
|
30
|
+
return i >= 0 ? args[i + 1] : undefined
|
|
31
|
+
}
|
|
32
|
+
let known = ['--apply', '--backup', '--db', '--help']
|
|
33
|
+
let bad = args.filter((a, k) => (a.startsWith('--') ? !known.includes(a) : !(k > 0 && ['--backup', '--db'].includes(args[k - 1]))))
|
|
34
|
+
let missing = ['--backup', '--db'].some((k) => flag(k) && (val(k) === undefined || val(k).startsWith('--')))
|
|
35
|
+
if (flag('--help') || bad.length > 0 || missing) {
|
|
36
|
+
console.log('用法: node g_fixFromType.mjs [--apply] [--backup <檔>] [--db <資料夾>]')
|
|
37
|
+
process.exitCode = flag('--help') ? 0 : 2
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//連線: 預設走 g_mOrm.mjs(專案資料庫, 動態載入——靜態 import 會於載入時即開啟 ./db); --db 則依指定資料夾自建(WServOrm 組裝同 g_mOrm.mjs)
|
|
42
|
+
let st = getSettings()
|
|
43
|
+
let url = flag('--db') ? val('--db') : st.dbUrl
|
|
44
|
+
if (!fs.existsSync(path.join(url, st.dbName))) {
|
|
45
|
+
console.log(`資料庫不存在: ${path.resolve(url, st.dbName)}(不憑空建立空庫, 已中止)`)
|
|
46
|
+
process.exitCode = 1
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//後端占用偵測(寫入前, 且須於本行程開啟資料庫之前)
|
|
51
|
+
if (flag('--apply')) {
|
|
52
|
+
let u = checkDbNotInUse({ url, dbName: st.dbName })
|
|
53
|
+
if (!u.ok) {
|
|
54
|
+
console.log(`失敗(階段 inuse): ${u.err}`)
|
|
55
|
+
process.exitCode = 1
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
if (!u.checked) {
|
|
59
|
+
console.log('(此平台無法自動偵測後端是否占用資料庫, 請自行確認後端已停止)')
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let woItems = null
|
|
64
|
+
let closeAll = null
|
|
65
|
+
if (flag('--db')) {
|
|
66
|
+
let r = WServOrm(ds, WOrm, url, st.dbName)
|
|
67
|
+
woItems = r.woItems
|
|
68
|
+
closeAll = r.closeAll
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
woItems = (await import('./g_mOrm.mjs')).woItems
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
let res = await runFixFromType({ woItems, apply: flag('--apply'), backupPath: val('--backup') })
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
process.exitCode = 1
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
if (closeAll) {
|
|
82
|
+
await closeAll()
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
main()
|
|
89
|
+
.catch((err) => {
|
|
90
|
+
console.log('fixFromType catch', err)
|
|
91
|
+
process.exitCode = 1 //失敗以非 0 離開碼表達(規則帳本 R-SEED-01、R-ERR-01: 未 await 之 promise 於源頭 catch)
|
|
92
|
+
})
|
package/g_initialData.mjs
CHANGED
|
@@ -143,7 +143,7 @@ async function initialData() {
|
|
|
143
143
|
|
|
144
144
|
rs = [
|
|
145
145
|
|
|
146
|
-
['peter', '
|
|
146
|
+
['peter', '', `
|
|
147
147
|
{
|
|
148
148
|
'權限群組M1': {
|
|
149
149
|
'mode': 'OR',
|
|
@@ -151,7 +151,7 @@ async function initialData() {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
`, 'n'],
|
|
154
|
-
['mary', '
|
|
154
|
+
['mary', '', `
|
|
155
155
|
{
|
|
156
156
|
'權限群組M2': {
|
|
157
157
|
'mode': 'OR',
|
|
@@ -159,7 +159,7 @@ async function initialData() {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
`, 'n'],
|
|
162
|
-
['john', '
|
|
162
|
+
['john', '', `
|
|
163
163
|
{
|
|
164
164
|
'權限群組M3': {
|
|
165
165
|
'mode': 'OR',
|
package/g_purgeFrom.mjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import WOrm from 'w-orm-lmdb/src/WOrmLmdb.mjs'
|
|
4
|
+
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
5
|
+
import ds from './src/schema/index.mjs'
|
|
6
|
+
import getSettings from './g_getSettings.mjs'
|
|
7
|
+
import { checkDbNotInUse, runAuditFrom, runPurgeFrom } from './server/tools/fromTools.mjs'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
//來源欄 from 之整來源清除(升版工具; F-23 外部列受保護, 規則帳本 R-PRINCIPLE-00 原則 5): 升版後 from 為非空字串之列為外部列, 後台唯讀(不得改、不得刪);
|
|
11
|
+
//某外部來源已不再同步而須整批移除時, 以本工具清除該來源寫入之全部列, 並於同一次清理引用(效果同後台刪除該些列: users.cgrups 引用被清除群組、grups.cpemis 引用被清除權限、pemis.crules 引用被清除標的者, 自授權字串移除; 與伺服端同一純函數 refCascade.planRefChanges).
|
|
12
|
+
//比對為精確 ===(不 trim、不分大小寫、不模糊); from 不可為空字串(拒絕); 不做「認領」(外部列改成後台列); 不得有自動刪除之預設——預設只列, 明確加 --apply 才寫入.
|
|
13
|
+
//
|
|
14
|
+
//用法(自專案根):
|
|
15
|
+
// node g_purgeFrom.mjs 只列(預設): 各表 (表, from 值型別/值) 之筆數(含 '' 與非字串者之摘要), 並標示非空 from 為外部列
|
|
16
|
+
// node g_purgeFrom.mjs --table <targets|pemis|grups|users|all> --from <來源名>
|
|
17
|
+
// 只列出將被清除之列與將被連帶清理之引用端筆數(dry-run, 不寫); all 為四表依 targets → pemis → grups → users 之引用鏈序逐表處理
|
|
18
|
+
// node g_purgeFrom.mjs --table <表|all> --from <來源名> --apply 寫入(不可逆): 後端須先停止(偵測到資料庫被占用即拒絕); 先備份資料庫(backup-時間.json, 於工作目錄)與四表全部列(./purgeFrom-backup-時間.json), 任一備份失敗即中止、不寫入;
|
|
19
|
+
// 逐表先寫引用端改寫、後刪被清除列; 任一步失敗即中止並提示依備份回復; 寫完回驗(與預測狀態逐位元相同、指定表已無該來源之列、未製造新的懸空引用)
|
|
20
|
+
// --backup <檔> 指定四表備份檔路徑(不覆寫既有檔)
|
|
21
|
+
// --db <資料夾> 覆寫資料庫位置(同 g_getSettings 之 dbUrl; 資料庫名稱仍為 dbName), 供測試用臨時資料庫; 資料夾不存在即中止(不憑空建立空庫)
|
|
22
|
+
//
|
|
23
|
+
//拒絕(零寫入): from 為空字串(--from '' 於部分 shell 會被吃掉而成缺值, 亦視為參數錯誤); 被清除列缺非空字串主鍵; 引用端授權字串含無法安全重新編碼之內容(JSON5 Infinity/NaN 數值, 清理會改指別的規則, 須先人工處理該引用端列).
|
|
24
|
+
//冪等: 失敗後修正原因可原樣重跑同一指令. 備份檔含 email 等個資, 請妥善保管、勿外傳、勿納入版控. 輸出可列 id 與群組/權限/標的名稱, 不列使用者姓名與 email.
|
|
25
|
+
//離開碼: 0 成功(含只列與無須清除); 1 失敗(資料庫不存在、被占用、規劃被拒、備份失敗、資料於稽核後被改動、寫入有失敗、寫後驗證不符等, 報告會列出; 規劃被拒於 dry-run 亦為 1, 表示 --apply 亦將拒絕); 2 參數錯誤.
|
|
26
|
+
|
|
27
|
+
const TABLE_NAMES = ['targets', 'pemis', 'grups', 'users', 'all']
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async function main() {
|
|
31
|
+
let args = process.argv.slice(2)
|
|
32
|
+
let flag = (k) => args.includes(k)
|
|
33
|
+
let val = (k) => {
|
|
34
|
+
let i = args.indexOf(k)
|
|
35
|
+
return i >= 0 ? args[i + 1] : undefined
|
|
36
|
+
}
|
|
37
|
+
let USAGE = '用法: node g_purgeFrom.mjs [--table <targets|pemis|grups|users|all> --from <來源名> [--apply] [--backup <檔>]] [--db <資料夾>]'
|
|
38
|
+
let known = ['--apply', '--backup', '--db', '--table', '--from', '--help']
|
|
39
|
+
let valueFlags = ['--backup', '--db', '--table', '--from']
|
|
40
|
+
let bad = args.filter((a, k) => (a.startsWith('--') ? !known.includes(a) : !(k > 0 && valueFlags.includes(args[k - 1]))))
|
|
41
|
+
let missing = valueFlags.some((k) => flag(k) && (val(k) === undefined || val(k).startsWith('--')))
|
|
42
|
+
if (flag('--help') || bad.length > 0 || missing) {
|
|
43
|
+
console.log(USAGE)
|
|
44
|
+
process.exitCode = flag('--help') ? 0 : 2
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
let table = val('--table')
|
|
48
|
+
let from = val('--from')
|
|
49
|
+
let usageErr = (msg) => {
|
|
50
|
+
console.log(`${msg}\n${USAGE}`)
|
|
51
|
+
process.exitCode = 2
|
|
52
|
+
}
|
|
53
|
+
if (flag('--from') && from === '') {
|
|
54
|
+
usageErr('--from 不可為空字串(空字串為後台列, 不是一個來源)')
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
if (flag('--table') !== flag('--from')) {
|
|
58
|
+
usageErr('--table 與 --from 須同時給')
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
if (flag('--table') && !TABLE_NAMES.includes(table)) {
|
|
62
|
+
usageErr(`--table 須為 ${TABLE_NAMES.join('/')} 之一`)
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
if (flag('--apply') && !flag('--table')) {
|
|
66
|
+
usageErr('--apply 須搭配 --table 與 --from(不提供無條件清除)')
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//連線: 預設走 g_mOrm.mjs(專案資料庫, 動態載入——靜態 import 會於載入時即開啟 ./db); --db 則依指定資料夾自建(WServOrm 組裝同 g_mOrm.mjs)
|
|
71
|
+
let st = getSettings()
|
|
72
|
+
let url = flag('--db') ? val('--db') : st.dbUrl
|
|
73
|
+
if (!fs.existsSync(path.join(url, st.dbName))) {
|
|
74
|
+
console.log(`資料庫不存在: ${path.resolve(url, st.dbName)}(不憑空建立空庫, 已中止)`)
|
|
75
|
+
process.exitCode = 1
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//後端占用偵測(寫入前, 且須於本行程開啟資料庫之前)
|
|
80
|
+
if (flag('--apply')) {
|
|
81
|
+
let u = checkDbNotInUse({ url, dbName: st.dbName })
|
|
82
|
+
if (!u.ok) {
|
|
83
|
+
console.log(`失敗(階段 inuse): ${u.err}`)
|
|
84
|
+
process.exitCode = 1
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
if (!u.checked) {
|
|
88
|
+
console.log('(此平台無法自動偵測後端是否占用資料庫, 請自行確認後端已停止)')
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let woItems = null
|
|
93
|
+
let closeAll = null
|
|
94
|
+
if (flag('--db')) {
|
|
95
|
+
let r = WServOrm(ds, WOrm, url, st.dbName)
|
|
96
|
+
woItems = r.woItems
|
|
97
|
+
closeAll = r.closeAll
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
woItems = (await import('./g_mOrm.mjs')).woItems
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
let res = null
|
|
105
|
+
if (flag('--table')) {
|
|
106
|
+
res = await runPurgeFrom({ woItems, table, from, apply: flag('--apply'), backupPath: val('--backup') })
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
res = await runAuditFrom({ woItems })
|
|
110
|
+
}
|
|
111
|
+
if (!res.ok) {
|
|
112
|
+
process.exitCode = 1
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
if (closeAll) {
|
|
117
|
+
await closeAll()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
main()
|
|
124
|
+
.catch((err) => {
|
|
125
|
+
console.log('purgeFrom catch', err)
|
|
126
|
+
process.exitCode = 1 //失敗以非 0 離開碼表達(規則帳本 R-SEED-01、R-ERR-01: 未 await 之 promise 於源頭 catch)
|
|
127
|
+
})
|