@mostajs/orm-cli 0.5.9 → 0.5.11
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/bin/mostajs.sh +67 -24
- package/package.json +1 -1
package/bin/mostajs.sh
CHANGED
|
@@ -1921,13 +1921,57 @@ action_rep_scaffold_services() {
|
|
|
1921
1921
|
fi
|
|
1922
1922
|
fi
|
|
1923
1923
|
|
|
1924
|
+
# Write env vars to .mostajs/config.env (monitor port, replicator interval)
|
|
1925
|
+
echo
|
|
1926
|
+
echo -e "${CYAN}▶ writing config to .mostajs/config.env${RESET}"
|
|
1927
|
+
local config_env="$PROJECT_ROOT/.mostajs/config.env"
|
|
1928
|
+
mkdir -p "$PROJECT_ROOT/.mostajs"
|
|
1929
|
+
|
|
1930
|
+
# Ask for monitor port
|
|
1931
|
+
local mon_port
|
|
1932
|
+
mon_port=$(ask "Monitor dashboard port" "4477")
|
|
1933
|
+
|
|
1934
|
+
# Ask for replicator sync interval
|
|
1935
|
+
local rep_interval
|
|
1936
|
+
rep_interval=$(ask "Replicator sync interval (ms)" "30000")
|
|
1937
|
+
|
|
1938
|
+
# Write/update config.env — preserve existing values, update only ours
|
|
1939
|
+
touch "$config_env"
|
|
1940
|
+
PROJECT="$PROJECT_ROOT" MON_PORT="$mon_port" REP_INT="$rep_interval" node --input-type=module -e "
|
|
1941
|
+
const fs = await import('node:fs');
|
|
1942
|
+
const path = process.env.PROJECT + '/.mostajs/config.env';
|
|
1943
|
+
let content = '';
|
|
1944
|
+
try { content = fs.readFileSync(path, 'utf8'); } catch {}
|
|
1945
|
+
|
|
1946
|
+
const set = (key, val) => {
|
|
1947
|
+
const re = new RegExp('^' + key + '=.*$', 'm');
|
|
1948
|
+
if (re.test(content)) {
|
|
1949
|
+
content = content.replace(re, key + '=' + val);
|
|
1950
|
+
console.log(' • updated ' + key + '=' + val);
|
|
1951
|
+
} else {
|
|
1952
|
+
content += (content && !content.endsWith('\n') ? '\n' : '') + key + '=' + val + '\n';
|
|
1953
|
+
console.log(' ✓ added ' + key + '=' + val);
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1956
|
+
|
|
1957
|
+
set('MONITOR_PORT', process.env.MON_PORT);
|
|
1958
|
+
set('MONITOR_HOST', '127.0.0.1');
|
|
1959
|
+
set('REPLICATOR_INTERVAL_MS', process.env.REP_INT);
|
|
1960
|
+
|
|
1961
|
+
fs.writeFileSync(path, content);
|
|
1962
|
+
" 2>&1 | sed 's/^/ /'
|
|
1963
|
+
|
|
1924
1964
|
echo
|
|
1925
1965
|
echo -e "${BOLD}${GREEN}✓ Scaffold complete.${RESET}"
|
|
1926
1966
|
echo
|
|
1967
|
+
echo -e " ${BOLD}Config written to :${RESET} .mostajs/config.env"
|
|
1968
|
+
echo -e " MONITOR_PORT=${mon_port} REPLICATOR_INTERVAL_MS=${rep_interval}"
|
|
1969
|
+
echo
|
|
1927
1970
|
echo -e " ${BOLD}Next steps :${RESET}"
|
|
1928
1971
|
echo -e " 1. ${CYAN}mostajs${RESET} → menu r → add replicas + CDC rules (writes replicator-tree.json)"
|
|
1929
1972
|
echo -e " 2. ${CYAN}npm run dev:all${RESET} — starts Next + replicator + monitor in parallel"
|
|
1930
1973
|
echo -e " or individually : ${CYAN}npm run replicator${RESET} / ${CYAN}npm run monitor${RESET}"
|
|
1974
|
+
echo -e " 3. Open ${CYAN}http://localhost:${mon_port}${RESET} for the live dashboard"
|
|
1931
1975
|
echo -e " 3. Open ${CYAN}http://localhost:14499${RESET} for the live dashboard"
|
|
1932
1976
|
pause
|
|
1933
1977
|
}
|
|
@@ -2071,10 +2115,24 @@ action_rep_promote() {
|
|
|
2071
2115
|
project=$(_pick_project)
|
|
2072
2116
|
name=$(ask "Slave to promote" "slave-1")
|
|
2073
2117
|
if ! confirm "Promote '$name' to master on project '$project'?"; then return; fi
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2118
|
+
# Direct tree patch — loadFromFile doesn't reconnect replicas, so the
|
|
2119
|
+
# ReplicationManager in-memory approach fails with "no replicas". Promote
|
|
2120
|
+
# is just a role swap in the JSON — no DB connection needed.
|
|
2121
|
+
_tree_patch "
|
|
2122
|
+
const reps = tree.replicas['$project'];
|
|
2123
|
+
if (!reps) { console.log(' ✗ project \"$project\" not found'); return; }
|
|
2124
|
+
if (!reps['$name']) { console.log(' ✗ replica \"$name\" not found in $project'); return; }
|
|
2125
|
+
if (reps['$name'].role === 'master') { console.log(' • $name is already master'); return; }
|
|
2126
|
+
// Demote current master(s) to slave
|
|
2127
|
+
for (const [n, cfg] of Object.entries(reps)) {
|
|
2128
|
+
if (cfg.role === 'master') {
|
|
2129
|
+
cfg.role = 'slave';
|
|
2130
|
+
console.log(' ↓ ' + n + ' demoted to slave');
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
// Promote target to master
|
|
2134
|
+
reps['$name'].role = 'master';
|
|
2135
|
+
console.log(' ★ $name promoted to master');
|
|
2078
2136
|
"
|
|
2079
2137
|
pause
|
|
2080
2138
|
}
|
|
@@ -2115,29 +2173,14 @@ action_rep_add_rule() {
|
|
|
2115
2173
|
target=$(ask "Target project" "$src_default")
|
|
2116
2174
|
mode=$(ask "Mode (snapshot | cdc | bidirectional)" "cdc")
|
|
2117
2175
|
echo
|
|
2118
|
-
dim " Collections : '*' = all tables
|
|
2119
|
-
dim "
|
|
2176
|
+
dim " Collections : '*' = all tables of the master DB — resolved LIVE at"
|
|
2177
|
+
dim " each sync tick from the master's table catalogue"
|
|
2178
|
+
dim " (so new tables added later are picked up automatically)."
|
|
2179
|
+
dim " Or : explicit comma-separated list (User,Member,Payment)"
|
|
2120
2180
|
colls=$(ask "Collections" "*")
|
|
2121
2181
|
conflict=$(ask "Conflict resolution (source-wins | target-wins | timestamp)" "source-wins")
|
|
2122
|
-
|
|
2123
|
-
# Expand '*' into the full list of entity NAMES from entities.json. Keeps
|
|
2124
|
-
# the tree self-contained — no special-case needed in replicator.mjs.
|
|
2125
2182
|
if [[ "$colls" == "*" ]]; then
|
|
2126
|
-
|
|
2127
|
-
if [[ -f "$ents_json" ]]; then
|
|
2128
|
-
colls=$(node -e "try{const e=JSON.parse(require('fs').readFileSync('$ents_json','utf8'));console.log(e.map(x=>x.name).join(','))}catch{console.log('')}" 2>/dev/null)
|
|
2129
|
-
if [[ -z "$colls" ]]; then
|
|
2130
|
-
warn " entities.json empty or unreadable — keeping '*' as wildcard placeholder"
|
|
2131
|
-
colls="*"
|
|
2132
|
-
else
|
|
2133
|
-
local count; count=$(echo "$colls" | tr ',' '\n' | wc -l)
|
|
2134
|
-
ok " expanded '*' → ${count} tables from entities.json"
|
|
2135
|
-
dim " ${colls}"
|
|
2136
|
-
fi
|
|
2137
|
-
else
|
|
2138
|
-
warn " no entities.json found at $ents_json — keeping '*' as wildcard placeholder"
|
|
2139
|
-
warn " (run menu 1 'Convert' first, then re-add the rule to expand)"
|
|
2140
|
-
fi
|
|
2183
|
+
dim " → '*' stored as-is ; replicator.mjs will introspect the master DB at run-time."
|
|
2141
2184
|
fi
|
|
2142
2185
|
|
|
2143
2186
|
_tree_patch "
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/orm-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.11",
|
|
4
4
|
"description": "Universal CLI to integrate @mostajs/orm into any project — one-shot `mostajs bootstrap` migrates a Prisma project (codemod + deps + schema convert + DDL) to 13 databases with zero code change.",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|