@mostajs/orm-cli 0.6.4 → 0.7.0

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 CHANGED
@@ -548,6 +548,10 @@ menu_main() {
548
548
  echo -e " ${CYAN}r${RESET}) ${BOLD}Replicator${RESET} — CQRS master/slave, CDC rules, failover"
549
549
  echo -e " ${GREEN}b${RESET}) ${BOLD}Bootstrap${RESET} — one-shot migration of a Prisma project"
550
550
  echo -e " ${GREEN}i${RESET}) ${BOLD}Install bridge${RESET} — codemod PrismaClient → bridge (dry-run / apply / restore)"
551
+ echo -e " ${GREEN}f${RESET}) ${BOLD}Fix Mongo _id${RESET} — codemod \`obj._id\` → \`obj.id\` after data-plug migration"
552
+ echo -e " ${GREEN}m${RESET}) ${BOLD}Mongo introspect${RESET} — live MongoDB → entities.json (reverse-engineer)"
553
+ echo -e " ${GREEN}v${RESET}) ${BOLD}Validate${RESET} — lint entities.json with the ORM validator (R001–R021)"
554
+ echo -e " ${GREEN}l${RESET}) ${BOLD}Load data${RESET} — .env-piloted cross-dialect load (Mongo/dump/JSON/SQL → DB)"
551
555
  echo -e " ${CYAN}0${RESET}) About / Help"
552
556
  echo
553
557
  echo -e " ${RED}q${RESET}) Quit"
@@ -569,6 +573,10 @@ menu_main() {
569
573
  r|R) menu_replicator ;;
570
574
  b|B) menu_bootstrap ;;
571
575
  i|I) menu_install_bridge ;;
576
+ f|F) menu_fix_ids ;;
577
+ m|M) menu_mongo_introspect ;;
578
+ v|V) menu_validate ;;
579
+ l|L) menu_load_data ;;
572
580
  0) action_about ;;
573
581
  q|Q) exit 0 ;;
574
582
  *) warn "Unknown choice"; pause ;;
@@ -602,6 +610,139 @@ menu_install_bridge() {
602
610
  pause
603
611
  }
604
612
 
613
+ # ------------------------------------------------------------
614
+ # Interactive wrapper for `fix-ids` codemod (Mongo _id → id)
615
+ # ------------------------------------------------------------
616
+ menu_fix_ids() {
617
+ header
618
+ echo -e "${BOLD}${MAGENTA}▶ Fix Mongo _id → id — post data-plug migration codemod${RESET}"
619
+ echo
620
+ echo -e " ${DIM}@mostajs/orm normalizes ${CYAN}_id${DIM}→${CYAN}id${DIM} for every dialect (mongo included),${RESET}"
621
+ echo -e " ${DIM}so app code must read ${CYAN}obj.id${DIM}. This rewrites stale ${CYAN}obj._id${DIM} reads.${RESET}"
622
+ echo
623
+ echo -e " ${CYAN}1${RESET}) Dry-run : list \`._id\` reads that would be rewritten (default)"
624
+ echo -e " ${CYAN}2${RESET}) Apply : rewrite \`obj._id\` → \`obj.id\` (backups : *.mongoid.bak)"
625
+ echo -e " ${CYAN}3${RESET}) Restore : revert .mongoid.bak files (dry-run)"
626
+ echo -e " ${CYAN}4${RESET}) Restore : revert .mongoid.bak files (apply)"
627
+ echo -e " ${RED}0${RESET}) Back"
628
+ echo
629
+ local cli_dir
630
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
631
+ local choice; choice=$(ask "Choice" "1")
632
+ case "$choice" in
633
+ 1) node "$cli_dir/bin/fix-mongo-id.mjs" --project "$PROJECT_ROOT" ;;
634
+ 2) node "$cli_dir/bin/fix-mongo-id.mjs" --project "$PROJECT_ROOT" --apply ;;
635
+ 3) node "$cli_dir/bin/fix-mongo-id.mjs" --project "$PROJECT_ROOT" --restore ;;
636
+ 4) node "$cli_dir/bin/fix-mongo-id.mjs" --project "$PROJECT_ROOT" --restore --apply ;;
637
+ 0) return ;;
638
+ *) warn "Unknown" ;;
639
+ esac
640
+ pause
641
+ }
642
+
643
+ # ------------------------------------------------------------
644
+ # Interactive wrapper for `mongo-introspect` (live MongoDB → entities.json)
645
+ # ------------------------------------------------------------
646
+ menu_mongo_introspect() {
647
+ load_env
648
+ header
649
+ echo -e "${BOLD}${MAGENTA}▶ Mongo introspect — reverse-engineer a live MongoDB${RESET}"
650
+ echo
651
+ echo -e " ${DIM}Samples documents per collection and infers EntitySchema[] →${RESET}"
652
+ echo -e " ${DIM}${GENERATED_DIR}/entities.json (the ORM drops _id/__v, ObjectId → string id).${RESET}"
653
+ echo
654
+ if [[ "${DB_DIALECT:-}" != "mongodb" ]]; then
655
+ warn "DB_DIALECT is '${DB_DIALECT:-<unset>}', not 'mongodb'."
656
+ info "Set it (menu 2 → i to import from the project .env), or enter a URI now."
657
+ fi
658
+ local uri; uri=$(ask "MongoDB URI" "${SGBD_URI:-mongodb://localhost:27017/mydb}")
659
+ [[ -z "$uri" ]] && { warn "No URI"; pause; return; }
660
+ local sample; sample=$(ask "Docs to sample per collection" "200")
661
+ local cli_dir
662
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
663
+ node "$cli_dir/bin/mongo-introspect.mjs" --uri "$uri" --sample "$sample" --out "$GENERATED_DIR/entities.json" --project "$PROJECT_ROOT"
664
+ pause
665
+ }
666
+
667
+ # ------------------------------------------------------------
668
+ # Interactive wrapper for `validate` (ORM validator over entities.json)
669
+ # ------------------------------------------------------------
670
+ menu_validate() {
671
+ header
672
+ echo -e "${BOLD}${MAGENTA}▶ Validate — ORMConceptValidator (R001–R021)${RESET}"
673
+ echo
674
+ if [[ ! -f "$GENERATED_DIR/entities.json" ]]; then
675
+ err "No entities.json. Run menu 1 (Convert) or menu m (Mongo introspect) first."
676
+ pause; return
677
+ fi
678
+ echo -e " ${CYAN}1${RESET}) Text report (default)"
679
+ echo -e " ${CYAN}2${RESET}) Markdown → report saved next to entities.json"
680
+ echo -e " ${CYAN}3${RESET}) JSON (stdout)"
681
+ echo -e " ${CYAN}4${RESET}) Text + cross-file rules (prompt for --src dir)"
682
+ echo -e " ${RED}0${RESET}) Back"
683
+ echo
684
+ local cli_dir
685
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
686
+ local choice; choice=$(ask "Choice" "1")
687
+ case "$choice" in
688
+ 1) node "$cli_dir/bin/validate.mjs" --project "$PROJECT_ROOT" ;;
689
+ 2) node "$cli_dir/bin/validate.mjs" --project "$PROJECT_ROOT" --format markdown --out "$GENERATED_DIR/validation-report.md" ;;
690
+ 3) node "$cli_dir/bin/validate.mjs" --project "$PROJECT_ROOT" --format json ;;
691
+ 4) local src; src=$(ask "Sources root (e.g. ./src)" "$PROJECT_ROOT/src")
692
+ node "$cli_dir/bin/validate.mjs" --project "$PROJECT_ROOT" --src "$src" ;;
693
+ 0) return ;;
694
+ *) warn "Unknown" ;;
695
+ esac
696
+ pause
697
+ }
698
+
699
+ # ------------------------------------------------------------
700
+ # Interactive wrapper for `load-data` — .env-piloted cross-dialect load
701
+ # (delegates to @mostajs/orm-copy-data's `mostajs-load` bin)
702
+ # ------------------------------------------------------------
703
+ menu_load_data() {
704
+ load_env
705
+ header
706
+ echo -e "${BOLD}${MAGENTA}▶ Load data — charge un dump vers la base .env (cross-dialecte)${RESET}"
707
+ echo
708
+ echo -e " ${DIM}Destination (.env) : ${CYAN}${DB_DIALECT:-<DB_DIALECT non défini>}${DIM} → ${CYAN}${SGBD_URI:-<SGBD_URI non défini>}${RESET}"
709
+ if [[ -f "$GENERATED_DIR/entities.json" ]]; then
710
+ echo -e " ${DIM}Schémas : ${GENERATED_DIR}/entities.json ${GREEN}(présent)${RESET}"
711
+ else
712
+ warn "entities.json absent → lance d'abord le menu ${BOLD}m${RESET} (Mongo introspect) ou ${BOLD}1${RESET} (Convert)."
713
+ fi
714
+ echo
715
+ echo -e " ${BOLD}Source :${RESET}"
716
+ echo -e " ${CYAN}1${RESET}) MongoDB live (URI)"
717
+ echo -e " ${CYAN}2${RESET}) mongodump (dossier BSON → mongorestore)"
718
+ echo -e " ${CYAN}3${RESET}) Export JSON (fichier)"
719
+ echo -e " ${CYAN}4${RESET}) Dump SQL (fichier)"
720
+ echo -e " ${RED}0${RESET}) Retour"
721
+ echo
722
+
723
+ ensure_pkg "@mostajs/orm-copy-data" || { pause; return; }
724
+ local cd_main cd_bin
725
+ cd_main="$(resolve_pkg_path '@mostajs/orm-copy-data')" || { err "copy-data introuvable"; pause; return; }
726
+ cd_bin="$(dirname "$(dirname "$cd_main")")/bin/load-data.mjs"
727
+ [[ -f "$cd_bin" ]] || { err "bin mostajs-load absent — @mostajs/orm-copy-data ≥0.3.0 requis"; pause; return; }
728
+
729
+ local choice; choice=$(ask "Choix" "1")
730
+ case "$choice" in
731
+ 1) local uri; uri=$(ask "URI Mongo source" "${SOURCE_SGBD_URI:-mongodb://127.0.0.1:27017/TicketFlow}")
732
+ node "$cd_bin" --project "$PROJECT_ROOT" --from mongo --source-uri "$uri" ;;
733
+ 2) local dir; dir=$(ask "Dossier mongodump (BSON)" "./dump/TicketFlow")
734
+ local ruri; ruri=$(ask "URI Mongo de restauration" "${SOURCE_SGBD_URI:-mongodb://127.0.0.1:27017/tf_restore}")
735
+ node "$cd_bin" --project "$PROJECT_ROOT" --from mongodump --dump-dir "$dir" --restore-uri "$ruri" ;;
736
+ 3) local f; f=$(ask "Fichier JSON" "./dump.json")
737
+ node "$cd_bin" --project "$PROJECT_ROOT" --from json --source-file "$f" ;;
738
+ 4) local f; f=$(ask "Fichier SQL" "./dump.sql")
739
+ node "$cd_bin" --project "$PROJECT_ROOT" --from sql --source-file "$f" ;;
740
+ 0) return ;;
741
+ *) warn "Inconnu" ;;
742
+ esac
743
+ pause
744
+ }
745
+
605
746
  # ------------------------------------------------------------
606
747
  # Interactive wrapper for `bootstrap` — one-shot full migration
607
748
  # ------------------------------------------------------------
@@ -615,6 +756,7 @@ menu_bootstrap() {
615
756
  echo " 2. Install ${CYAN}@mostajs/orm${RESET} + ${CYAN}@mostajs/orm-bridge${RESET} + ${CYAN}server-only${RESET}"
616
757
  echo " 3. Convert ${CYAN}prisma/schema.prisma${RESET} → ${DIM}.mostajs/generated/entities.json${RESET}"
617
758
  echo " 4. Write ${DIM}.mostajs/config.env${RESET} (default : sqlite ./data.sqlite) and init DDL"
759
+ echo " 5. Scan app code for Mongo residue ${CYAN}obj._id${RESET} / ${CYAN}new ObjectId()${RESET} (dry-run ; ${DIM}fix-ids${RESET})"
618
760
  echo
619
761
  warn "Existing code changes will be backed up but NOT committed — review the diff before pushing."
620
762
  echo
@@ -3939,6 +4081,50 @@ run_subcommand() {
3939
4081
  shift
3940
4082
  node "$cli_dir/bin/install-bridge.mjs" "$@"
3941
4083
  ;;
4084
+ fix-ids|fix-mongo-id|fixids)
4085
+ # mostajs fix-ids [--apply] [--file X] [--project P] [--map old:new] [--restore]
4086
+ # Codemod : repairs Mongo-era `obj._id` reads left in app code after a
4087
+ # Mongoose → @mostajs/orm (data-plug) migration. The ORM's normalizer maps
4088
+ # `_id`→`id` for EVERY dialect (mongo included), so the app must read `.id`.
4089
+ # Dry-run by default ; pass --apply to write (backups : *.mongoid.bak).
4090
+ local cli_dir
4091
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4092
+ shift
4093
+ node "$cli_dir/bin/fix-mongo-id.mjs" "$@"
4094
+ ;;
4095
+ mongo-introspect|introspect|mi)
4096
+ # mostajs mongo-introspect [--uri ...] [--sample N] [--out F] [--project P]
4097
+ # Reverse-engineer a LIVE MongoDB into .mostajs/generated/entities.json by
4098
+ # sampling docs (uses $SGBD_URI if --uri is omitted). The "migrer" step for
4099
+ # Mongo projects that have no Prisma/OpenAPI schema.
4100
+ local cli_dir
4101
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4102
+ shift
4103
+ node "$cli_dir/bin/mongo-introspect.mjs" "$@"
4104
+ ;;
4105
+ validate|val)
4106
+ # mostajs validate [--entities F] [--src DIR] [--format text|json|markdown]
4107
+ # [--ignore r1,r2] [--out F] [--ci] [--max-warnings N]
4108
+ # Run @mostajs/orm's ORMConceptValidator (R001–R021) over entities.json.
4109
+ local cli_dir
4110
+ cli_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4111
+ shift
4112
+ node "$cli_dir/bin/validate.mjs" "$@"
4113
+ ;;
4114
+ load-data|load|ld)
4115
+ # mostajs load-data --from mongo|mongodump|json|sql [...flags]
4116
+ # Thin DELEGATE to @mostajs/orm-copy-data's `mostajs-load` bin (where the
4117
+ # feature lives). Destination from .env (DB_DIALECT/SGBD_URI) ; needs
4118
+ # entities.json (run `mostajs mongo-introspect` first).
4119
+ shift
4120
+ ensure_pkg "@mostajs/orm-copy-data" || exit 1
4121
+ local cd_main cd_bin
4122
+ cd_main="$(resolve_pkg_path '@mostajs/orm-copy-data')" \
4123
+ || { err "@mostajs/orm-copy-data introuvable après installation."; exit 1; }
4124
+ cd_bin="$(dirname "$(dirname "$cd_main")")/bin/load-data.mjs"
4125
+ [[ -f "$cd_bin" ]] || { err "bin mostajs-load absent ($cd_bin) — mets à jour @mostajs/orm-copy-data (≥0.3.0)."; exit 1; }
4126
+ node "$cd_bin" --project "$PROJECT_ROOT" "$@"
4127
+ ;;
3942
4128
  bootstrap|b)
3943
4129
  # mostajs bootstrap : the full zero-touch migration for a Prisma project.
3944
4130
  # 1. Rewrite every `new PrismaClient(...)` site (install-bridge --apply)
@@ -4358,8 +4544,16 @@ TREE
4358
4544
  ;;
4359
4545
  esac
4360
4546
 
4361
- # ─── Step 5 : Summary ───
4362
- echo -e "\n\e[1m▶ Step 5/6 : Summary\e[0m"
4547
+ # ─── Step : repair Mongo _id / ObjectId residue in app code ───
4548
+ # @mostajs/orm exposes ids as `id` (string) for EVERY dialect (mongo via its
4549
+ # normalizer), so app code must stop reading `obj._id` / wrapping `new ObjectId()`.
4550
+ # Run as a DRY-RUN here (non-destructive / CI-safe) and tell the user to apply.
4551
+ echo -e "\n\e[1m▶ Step 5/6 : repair Mongo _id / ObjectId in app code (codemod, dry-run)\e[0m"
4552
+ node "$cli_dir/bin/fix-mongo-id.mjs" --project "$PROJECT_ROOT" 2>&1 | sed 's/^/ /' || true
4553
+ info " To apply : ${CLI_NAME} fix-ids --apply (backups *.mongoid.bak ; undo: --restore --apply)"
4554
+
4555
+ # ─── Step 6 : Summary ───
4556
+ echo -e "\n\e[1m▶ Step 6/6 : Summary\e[0m"
4363
4557
  if (( BS_OK_CODEMOD && BS_OK_DEPS && BS_OK_CONVERT && BS_OK_DDL )); then
4364
4558
  cat <<DONE
4365
4559
 
@@ -4408,6 +4602,15 @@ Usage :
4408
4602
  $CLI_NAME install-bridge Codemod only (dry-run ; add --apply to write)
4409
4603
  $CLI_NAME install-bridge --apply Rewrite PrismaClient sites to use @mostajs/orm-bridge
4410
4604
  $CLI_NAME install-bridge --restore --apply Undo a prior install-bridge
4605
+ $CLI_NAME fix-ids Codemod : Mongo \`obj._id\`→\`obj.id\` + \`new ObjectId(x)\`→\`x\`
4606
+ (dry-run ; add --apply to write, --restore to undo)
4607
+ $CLI_NAME mongo-introspect Reverse-engineer a live MongoDB → entities.json
4608
+ (--uri ... --sample N ; uses \$SGBD_URI by default)
4609
+ $CLI_NAME validate Lint entities.json with the ORM validator (R001–R021)
4610
+ (--format text|json|markdown --src DIR --ci)
4611
+ $CLI_NAME load-data --from mongo|mongodump|json|sql …
4612
+ .env-piloted cross-dialect load (delegates to
4613
+ @mostajs/orm-copy-data ; dest = DB_DIALECT/SGBD_URI)
4411
4614
  $CLI_NAME convert Run conversion (auto-detect schema type)
4412
4615
  $CLI_NAME detect Print detected schemas
4413
4616
  $CLI_NAME health Run health checks
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ // validate.mjs — run @mostajs/orm's ORMConceptValidator over the entities the CLI
3
+ // generated (`.mostajs/generated/entities.json`). Thin wrapper around the
4
+ // published validator API (validateSchemas + reporters), so a migrated Mongo (or
5
+ // any) project can be linted for schema anti-patterns (R001–R021).
6
+ //
7
+ // @author Dr Hamid MADANI <drmdh@msn.com>
8
+ // License: AGPL-3.0-or-later
9
+ //
10
+ // Usage (invoked by bin/mostajs.sh as `mostajs validate`) :
11
+ //
12
+ // node validate.mjs # text report on entities.json
13
+ // node validate.mjs --entities path.json # explicit entities file
14
+ // node validate.mjs --src ./src # enable cross-file rules (R005…)
15
+ // node validate.mjs --format markdown --out report.md
16
+ // node validate.mjs --ignore R015,R017
17
+ // node validate.mjs --ci --max-warnings 0 # exit 1 if findings ≥ threshold
18
+
19
+ import { readFileSync, writeFileSync } from 'node:fs';
20
+ import { resolve } from 'node:path';
21
+ import { createRequire } from 'node:module';
22
+ import { pathToFileURL } from 'node:url';
23
+
24
+ const require = createRequire(import.meta.url);
25
+ const argv = process.argv.slice(2);
26
+ const flag = (n) => argv.includes(`--${n}`);
27
+ const val = (n, d) => { const i = argv.indexOf(`--${n}`); return i >= 0 ? argv[i + 1] : d; };
28
+
29
+ const ROOT = resolve(val('project', process.cwd()));
30
+ const ENTITIES = resolve(val('entities', `${ROOT}/.mostajs/generated/entities.json`));
31
+ const SRC = val('src') ? resolve(val('src')) : undefined;
32
+ let FORMAT = val('format', 'text'); if (FORMAT === 'md') FORMAT = 'markdown';
33
+ const OUT = val('out') ? resolve(val('out')) : undefined;
34
+ const IGNORE = (val('ignore', '') || '').split(',').map((s) => s.trim()).filter(Boolean);
35
+ const CI = flag('ci');
36
+ const MAXW = Number(val('max-warnings', '0')) || 0;
37
+
38
+ const c = { red: s => `\x1b[31m${s}\x1b[0m`, yellow: s => `\x1b[33m${s}\x1b[0m`, green: s => `\x1b[32m${s}\x1b[0m`, cyan: s => `\x1b[36m${s}\x1b[0m`, bold: s => `\x1b[1m${s}\x1b[0m`, dim: s => `\x1b[2m${s}\x1b[0m` };
39
+
40
+ // ── Load entities.json (array of EntitySchema, as produced by convert / introspect) ──
41
+ let schemas;
42
+ try {
43
+ const raw = JSON.parse(readFileSync(ENTITIES, 'utf8'));
44
+ schemas = Array.isArray(raw) ? raw : (Array.isArray(raw.entities) ? raw.entities : null);
45
+ if (!schemas) throw new Error('not an EntitySchema[] (nor { entities: [...] })');
46
+ } catch (e) {
47
+ console.error(c.red(`✗ Cannot read entities : ${ENTITIES}`));
48
+ console.error(c.dim(` ${e.message}`));
49
+ console.error(` Generate it first : ${c.cyan('mostajs convert')} or ${c.cyan('mostajs mongo-introspect')}`);
50
+ process.exit(2);
51
+ }
52
+
53
+ // ── Resolve the validator from the project first, then the CLI's own deps ──
54
+ let validator;
55
+ const cliDir = resolve(new URL('..', import.meta.url).pathname);
56
+ for (const base of [ROOT, cliDir]) {
57
+ try {
58
+ const p = require.resolve('@mostajs/orm/validator', { paths: [base] });
59
+ validator = await import(pathToFileURL(p).href);
60
+ break;
61
+ } catch { /* try next */ }
62
+ }
63
+ // Final fallback : bare specifier resolves against the CLI's own node_modules.
64
+ if (!validator) {
65
+ try { validator = await import('@mostajs/orm/validator'); } catch { /* give up below */ }
66
+ }
67
+ if (!validator) {
68
+ console.error(c.red('✗ @mostajs/orm (validator) not found in project or CLI.'));
69
+ console.error(` Install it : ${c.cyan('npm i @mostajs/orm')}`);
70
+ process.exit(2);
71
+ }
72
+
73
+ const { validateSchemas, formatText, formatJson, formatMarkdown } = validator;
74
+
75
+ // ── Run ──
76
+ const report = await validateSchemas(schemas, { sourceRoot: SRC, ignore: IGNORE });
77
+
78
+ const rendered = FORMAT === 'json' ? formatJson(report, true)
79
+ : FORMAT === 'markdown' ? formatMarkdown(report)
80
+ : formatText(report, { verbose: flag('verbose') });
81
+
82
+ if (OUT) { writeFileSync(OUT, rendered); console.error(c.green(`✓ Report written : ${OUT}`)); }
83
+ else { console.log(rendered); }
84
+
85
+ // ── Summary line + CI gate ──
86
+ const sev = report.countBySeverity || {};
87
+ const warnOrWorse = (sev.error || 0) + (sev.warning || 0);
88
+ console.error(
89
+ `\n${c.bold('Validate')} : ${report.schemaCount} schema(s) · ` +
90
+ `${c.red((sev.error || 0) + ' error')} · ${c.yellow((sev.warning || 0) + ' warning')} · ` +
91
+ `${c.dim((sev.info || 0) + ' info')} ${c.dim(`(${report.durationMs}ms)`)}`,
92
+ );
93
+
94
+ if (CI && warnOrWorse > MAXW) {
95
+ console.error(c.red(`✗ CI gate : ${warnOrWorse} finding(s) ≥ max-warnings (${MAXW})`));
96
+ process.exit(1);
97
+ }
98
+ process.exit(0);
package/llms.txt ADDED
@@ -0,0 +1,75 @@
1
+ # @mostajs/orm-cli — fiche LLM
2
+ > CLI universelle pour intégrer @mostajs/orm — `mostajs bootstrap` migre un projet Prisma vers 13 bases sans toucher au code.
3
+
4
+ - Version: 0.6.4 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
5
+ - Chemin: mostajs/mosta-orm-cli · Statut audit: partiel (paquet bin/ uniquement, pas de dist/ TS exporté)
6
+
7
+ ## RÔLE
8
+ Outil en ligne de commande. La commande phare `mostajs bootstrap` migre un projet Prisma
9
+ existant vers @mostajs/orm en une passe : codemod (réécriture des `new PrismaClient(...)`),
10
+ installation des runtimes, conversion du schéma, application du DDL. Aucun changement de code
11
+ applicatif n'est requis. Fournit aussi un menu interactif et des sous-commandes utilitaires.
12
+ Ce paquet est un exécutable (bin), pas une bibliothèque importable.
13
+
14
+ ## INSTALLATION
15
+ npx @mostajs/orm-cli bootstrap # zero-install (recommandé)
16
+ npm install -g @mostajs/orm-cli # global -> commande `mostajs`
17
+
18
+ ## EXPORTS
19
+ Aucun export de bibliothèque. Le paquet expose un binaire :
20
+ - `mostajs` -> ./bin/mostajs-launcher.cjs
21
+ Fichiers bin : mostajs-launcher.cjs, install-bridge.mjs, mostajs.sh, mostajs.bat.
22
+
23
+ ## API — SOUS-COMMANDES
24
+ - `mostajs bootstrap` — migration complète : codemod + install + convert + DDL
25
+ (chaque étape s'arrête à la première erreur, v0.4.1+)
26
+ - `mostajs install-bridge` — lance le codemod en dry-run (rapport, aucune écriture)
27
+ - `mostajs install-bridge --apply` — applique les changements du codemod
28
+ - `mostajs install-bridge --file <path>` — restreint le codemod à un fichier
29
+ - `mostajs install-bridge --restore --apply` — restaure les sauvegardes `*.prisma.bak`
30
+ - `mostajs convert` — auto-détecte le schéma (Prisma / OpenAPI / JSONSchema) et le convertit
31
+ - `mostajs detect` — affiche ce qui est détecté dans le projet
32
+ - `mostajs health` — vérifie Node / pnpm / schémas / état de entities.json
33
+ - `mostajs hash <password> [cost]` — hash bcrypt d'un mot de passe (données de seed)
34
+ - `mostajs verify <password> <hash>` — vérifie une paire mot de passe / hash
35
+ - `mostajs diagnose [email] [password]` — diagnostic de login
36
+ - `mostajs help` / `mostajs version`
37
+ - `mostajs` (sans argument) — menu interactif (convert, config URIs, init dialectes,
38
+ tests, services, métriques, logs, health, génération boilerplate, seeding, bootstrap)
39
+
40
+ ## TYPES CLÉS
41
+ Sans objet — paquet purement CLI.
42
+
43
+ ## PATTERN
44
+ ```bash
45
+ cd my-existing-prisma-app
46
+ npx @mostajs/orm-cli bootstrap
47
+ npm run dev
48
+ # db.User.findMany(...) tourne maintenant sur l'un des 13 SGBD. Zéro changement de code.
49
+
50
+ # pour annuler :
51
+ npx @mostajs/orm-cli install-bridge --restore --apply
52
+ ```
53
+ Le codemod réécrit chaque site `new PrismaClient(...)` en `createPrismaLikeDb()` importé
54
+ de `@mostajs/orm-bridge/prisma-client`, sauvegarde l'original en `<fichier>.prisma.bak`,
55
+ et préserve la forme d'export (`const db`, `const prisma`, `export default`…).
56
+ Le bootstrap produit `.mostajs/config.env`, `.mostajs/generated/entities.json`,
57
+ `.mostajs/seeds/*.json` et `.mostajs/logs/`.
58
+
59
+ ## DÉPEND DE
60
+ - @mostajs/orm (dependency directe). À l'exécution, installe aussi dans le projet cible
61
+ @mostajs/orm-bridge et @mostajs/orm-adapter.
62
+ - bcryptjs (hash/verify), better-sqlite3 (DDL SQLite par défaut)
63
+
64
+ ## PIÈGES
65
+ - `install-bridge` est dry-run PAR DÉFAUT — il faut `--apply` pour écrire les fichiers.
66
+ - Détection codemod : fichier devant contenir `import ... from '@prisma/client'` ET
67
+ `new PrismaClient(`. Les fichiers déjà migrés vers `@mostajs/orm-bridge/prisma-client`
68
+ sont ignorés (ré-exécution idempotente).
69
+ - Conversion de schéma : passe par @mostajs/orm-adapter (Prisma / OpenAPI / JSON Schema).
70
+ - Le bootstrap configure SQLite par défaut ; changer ensuite `DB_DIALECT` + `SGBD_URI`
71
+ dans `.mostajs/config.env` (ou `.env`) pour cibler un autre des 13 SGBD.
72
+ - Paquet non importable — ne pas tenter `import ... from '@mostajs/orm-cli'`.
73
+
74
+ ## RÉFÉRENCES
75
+ - README.md · CHANGELOG.md · docs/How2.md, docs/MONITORING.md · install.sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/orm-cli",
3
- "version": "0.6.4",
3
+ "version": "0.7.0",
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",
@@ -11,7 +11,9 @@
11
11
  "files": [
12
12
  "bin",
13
13
  "LICENSE",
14
- "README.md"
14
+ "README.md",
15
+ "llms.txt",
16
+ "CHANGELOG.md"
15
17
  ],
16
18
  "keywords": [
17
19
  "mostajs",
@@ -42,8 +44,8 @@
42
44
  "win32"
43
45
  ],
44
46
  "dependencies": {
45
- "@mostajs/orm": "^1.9.2",
47
+ "@mostajs/orm": "^2.6.0",
46
48
  "bcryptjs": "^2.4.3",
47
49
  "better-sqlite3": "^12.9.0"
48
50
  }
49
- }
51
+ }