@mostajs/orm-cli 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/mostajs.sh +121 -1
  2. package/package.json +1 -1
package/bin/mostajs.sh CHANGED
@@ -594,7 +594,8 @@ prompt_dialect() {
594
594
  sqlite) suggest="./data.sqlite" ;;
595
595
  postgres) suggest="postgres://user:pw@localhost:5432/app" ;;
596
596
  mysql|mariadb) suggest="mysql://user:pw@localhost:3306/app" ;;
597
- mongodb) suggest="mongodb://localhost:27017/app" ;;
597
+ # MongoDB : include ?authSource=admin (common pitfall without it)
598
+ mongodb) suggest="mongodb://devuser:devpass26@localhost:27017/app?authSource=admin" ;;
598
599
  mssql) suggest="mssql://user:pw@localhost:1433/app" ;;
599
600
  oracle) suggest="oracle://user:pw@localhost:1521/ORCLPDB" ;;
600
601
  db2) suggest="db2://user:pw@localhost:50000/app" ;;
@@ -772,6 +773,46 @@ function stripScheme(uri) {
772
773
  return uri;
773
774
  }
774
775
 
776
+ // Provide dialect-specific hints for common auth / connection errors.
777
+ function hintFor(dialect, rawUri, err) {
778
+ const msg = (err && err.message) ? err.message : '';
779
+ const code = err && (err.code ?? err.codeName);
780
+
781
+ // MongoDB code 18 : Authentication failed → missing ?authSource=admin
782
+ if (dialect === 'mongodb' && (code === 18 || /AuthenticationFailed|18/.test(msg))) {
783
+ if (!/authSource=/.test(rawUri)) {
784
+ return 'MongoDB users are usually declared in the admin DB. Add ?authSource=admin to the URI :\n'
785
+ + ' ' + (rawUri.includes('?') ? rawUri + '&authSource=admin' : rawUri + '?authSource=admin');
786
+ }
787
+ return 'Verify credentials (username / password) in the URI.';
788
+ }
789
+
790
+ // PostgreSQL common errors
791
+ if (dialect === 'postgres' || dialect === 'cockroachdb') {
792
+ if (/password authentication failed/i.test(msg)) return 'Wrong PG password. Check the URI or run: psql "' + rawUri + '" -c "SELECT 1"';
793
+ if (/ECONNREFUSED|connect ECONNREFUSED/i.test(msg)) return 'PG server not running on that host/port. Try: pg_isready -h HOST -p PORT';
794
+ if (/no pg_hba.conf entry/i.test(msg)) return 'Server rejects the connection (pg_hba.conf). Add your IP or use SSL.';
795
+ }
796
+
797
+ // MySQL common errors
798
+ if (dialect === 'mysql' || dialect === 'mariadb') {
799
+ if (/Access denied for user/i.test(msg)) return 'Wrong MySQL password. Try: mysql -u USER -p -h HOST';
800
+ if (/ECONNREFUSED/i.test(msg)) return 'MySQL not running. Try: systemctl status mysql';
801
+ }
802
+
803
+ // SQLite common errors
804
+ if (dialect === 'sqlite') {
805
+ if (/SQLITE_CANTOPEN/i.test(msg)) return 'Cannot open SQLite file. Check the path exists and is writable.';
806
+ }
807
+
808
+ // Generic network errors
809
+ if (/ECONNREFUSED/i.test(msg)) return 'Service is not reachable at that host/port.';
810
+ if (/ENOTFOUND|getaddrinfo/i.test(msg)) return 'DNS resolution failed. Check the hostname.';
811
+ if (/ETIMEDOUT/i.test(msg)) return 'Connection timed out. Check firewall / VPN / host.';
812
+
813
+ return null;
814
+ }
815
+
775
816
  let ok = 0, fail = 0;
776
817
  for (const [dialect, rawUri] of pairs) {
777
818
  const uri = dialect === 'sqlite' ? stripScheme(rawUri) : rawUri;
@@ -790,6 +831,9 @@ for (const [dialect, rawUri] of pairs) {
790
831
  } catch (e) {
791
832
  console.error(' \u2717 ' + (e.message ?? e));
792
833
  if (e.code) console.error(' code : ' + e.code);
834
+ if (e.codeName) console.error(' codeName : ' + e.codeName);
835
+ const hint = hintFor(dialect, rawUri, e);
836
+ if (hint) console.error(' \u2192 ' + hint);
793
837
  fail++;
794
838
  }
795
839
  }
@@ -800,7 +844,66 @@ EOF
800
844
 
801
845
  cd "$PROJECT_ROOT"
802
846
  node "$CONFIG_DIR/test-connections.mjs" "${args[@]}" 2>&1 | tee "$LOG_DIR/test-connections.log"
847
+ local test_rc=${PIPESTATUS[0]}
803
848
  echo
849
+
850
+ # Offer to auto-fix common MongoDB auth issue (missing ?authSource=admin)
851
+ if [[ $test_rc -ne 0 ]] && grep -qE "authSource=admin|AuthenticationFailed|code : 18" "$LOG_DIR/test-connections.log"; then
852
+ echo
853
+ warn "Detected MongoDB authentication failure that is usually fixed by adding"
854
+ warn " ?authSource=admin to the URI."
855
+ if confirm "Append '?authSource=admin' to your MongoDB URI now?"; then
856
+ # Fix the primary SGBD_URI if it's mongodb
857
+ if [[ "${DB_DIALECT:-}" == "mongodb" ]] && [[ -n "${SGBD_URI:-}" ]] && [[ ! "$SGBD_URI" =~ authSource= ]]; then
858
+ local new_uri
859
+ if [[ "$SGBD_URI" =~ \? ]]; then
860
+ new_uri="${SGBD_URI}&authSource=admin"
861
+ else
862
+ new_uri="${SGBD_URI}?authSource=admin"
863
+ fi
864
+ save_var SGBD_URI "$new_uri"
865
+ ok "Updated SGBD_URI : $new_uri"
866
+ fi
867
+ # Fix any MongoDB extra binding missing authSource
868
+ if [[ -n "${EXTRA_BINDINGS:-}" ]]; then
869
+ local new_bindings=""
870
+ local IFS=';'
871
+ for b in $EXTRA_BINDINGS; do
872
+ local name="${b%%:*}"
873
+ local rest="${b#*:}"
874
+ local dialect="${rest%%:*}"
875
+ local uri="${rest#*:}"
876
+ if [[ "$dialect" == "mongodb" ]] && [[ ! "$uri" =~ authSource= ]]; then
877
+ if [[ "$uri" =~ \? ]]; then
878
+ uri="${uri}&authSource=admin"
879
+ else
880
+ uri="${uri}?authSource=admin"
881
+ fi
882
+ fi
883
+ new_bindings+="${new_bindings:+;}${name}:${dialect}:${uri}"
884
+ done
885
+ IFS=$' \t\n'
886
+ save_var EXTRA_BINDINGS "$new_bindings"
887
+ ok "Updated EXTRA_BINDINGS"
888
+ fi
889
+ echo
890
+ info "Re-running the test with the fixed URI..."
891
+ # Rebuild args with fresh env
892
+ load_env
893
+ args=()
894
+ [[ -n "${DB_DIALECT:-}" && -n "${SGBD_URI:-}" ]] && args+=("${DB_DIALECT}|${SGBD_URI}")
895
+ if [[ -n "${EXTRA_BINDINGS:-}" ]]; then
896
+ local IFS=';'
897
+ for b in $EXTRA_BINDINGS; do
898
+ local rest="${b#*:}"
899
+ args+=("${rest%%:*}|${rest#*:}")
900
+ done
901
+ IFS=$' \t\n'
902
+ fi
903
+ node "$CONFIG_DIR/test-connections.mjs" "${args[@]}" 2>&1 | tee "$LOG_DIR/test-connections.log"
904
+ fi
905
+ fi
906
+
804
907
  pause
805
908
  }
806
909
 
@@ -908,6 +1011,21 @@ const schemaStrategy = process.env.DB_SCHEMA_STRATEGY ?? 'update';
908
1011
  const poolSize = parseInt(process.env.DB_POOL_SIZE ?? '20', 10);
909
1012
  const showSql = process.env.DB_SHOW_SQL === 'true';
910
1013
 
1014
+ function hintFor(dialect, rawUri, err) {
1015
+ const msg = (err && err.message) ? err.message : '';
1016
+ const code = err && (err.code ?? err.codeName);
1017
+ if (dialect === 'mongodb' && (code === 18 || /AuthenticationFailed|18/.test(msg))) {
1018
+ if (!/authSource=/.test(rawUri)) {
1019
+ return 'Missing ?authSource=admin on MongoDB URI. Try :\n '
1020
+ + (rawUri.includes('?') ? rawUri + '&authSource=admin' : rawUri + '?authSource=admin');
1021
+ }
1022
+ }
1023
+ if (/ECONNREFUSED/i.test(msg)) return 'Service not running at that host/port';
1024
+ if (/ENOTFOUND/i.test(msg)) return 'DNS resolution failed';
1025
+ if (/ETIMEDOUT/i.test(msg)) return 'Connection timed out';
1026
+ return null;
1027
+ }
1028
+
911
1029
  for (const [dialect, rawUri] of pairs) {
912
1030
  const uri = dialect === 'sqlite' ? stripScheme(rawUri) : rawUri;
913
1031
  process.stdout.write('→ ' + dialect.padEnd(12) + ' : ' + rawUri + '\n');
@@ -920,6 +1038,8 @@ for (const [dialect, rawUri] of pairs) {
920
1038
  } catch (e) {
921
1039
  console.error(' ✗ ' + dialect + ' failed : ' + (e.message ?? e));
922
1040
  if (e.code) console.error(' code : ' + e.code);
1041
+ const hint = hintFor(dialect, rawUri, e);
1042
+ if (hint) console.error(' → ' + hint);
923
1043
  fail++;
924
1044
  }
925
1045
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/orm-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Universal CLI to integrate @mostajs/orm into any project — auto-detects Prisma, OpenAPI, JSON Schema. Interactive menu + subcommands. 13 databases.",
5
5
  "author": "Dr Hamid MADANI <drmdh@msn.com>",
6
6
  "license": "AGPL-3.0-or-later",