@mostajs/orm-cli 0.4.1 → 0.4.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.
package/README.md CHANGED
@@ -1,137 +1,189 @@
1
1
  # @mostajs/orm-cli
2
2
 
3
- > **Universal interactive CLI for @mostajs/orm integration.**
4
- > Auto-detects Prisma / OpenAPI / JSON Schema in any project, converts to EntitySchema[], tests with humans / mobiles / AI agents, and launches everything.
3
+ > **Automated migration from Prisma to @mostajs/orm.**
4
+ >
5
+ > `npx @mostajs/orm-cli bootstrap` scans your Prisma project, rewrites every `new PrismaClient(...)` site to use the @mostajs/orm-bridge (backing up the originals), installs the runtime, converts your schema, and applies DDL — in one command.
5
6
 
6
7
  [![npm version](https://img.shields.io/npm/v/@mostajs/orm-cli.svg)](https://www.npmjs.com/package/@mostajs/orm-cli)
7
8
  [![License: AGPL-3.0-or-later](https://img.shields.io/badge/License-AGPL%203.0-blue.svg)](LICENSE)
8
9
 
9
- ## Install
10
-
11
- ### Option 1 — npx (zero install)
10
+ ## Zero-touch migration
12
11
 
13
12
  ```bash
14
- cd your/project
15
- npx @mostajs/orm-cli
13
+ cd my-existing-prisma-app
14
+ npx @mostajs/orm-cli bootstrap
15
+ npm run dev
16
+ # db.User.findMany(...) now runs on any of 13 databases. Zero code change.
16
17
  ```
17
18
 
18
- ### Option 2 global
19
+ That single command does :
20
+
21
+ 1. **Codemod** — scans the repo for `new PrismaClient(...)`, detects each export name (`prisma`, `db`, `client`, default), and rewrites each site to `createPrismaLikeDb()` from `@mostajs/orm-bridge`. Originals backed up as `*.prisma.bak`.
22
+ 2. **Install** — `@mostajs/orm` + `@mostajs/orm-bridge` + `@mostajs/orm-adapter` + `server-only`.
23
+ 3. **Convert** — `prisma/schema.prisma` → `.mostajs/generated/entities.json`.
24
+ 4. **DDL** — writes `.mostajs/config.env` (SQLite defaults) and creates tables.
25
+
26
+ **Every step stops on error** (v0.4.1+) so you never see a lying success banner.
27
+
28
+ To undo :
19
29
 
20
30
  ```bash
21
- npm install -g @mostajs/orm-cli
22
- cd your/project
23
- mostajs
31
+ npx @mostajs/orm-cli install-bridge --restore --apply
24
32
  ```
25
33
 
26
- ### Option 3 — curl one-liner (Unix)
34
+ ## Install
35
+
36
+ ### Zero-install (recommended)
27
37
 
28
38
  ```bash
29
- curl -fsSL https://raw.githubusercontent.com/apolocine/mosta-orm-cli/main/install.sh | bash
39
+ npx @mostajs/orm-cli bootstrap
30
40
  ```
31
41
 
32
- ## Usage
42
+ ### Global
43
+
44
+ ```bash
45
+ npm install -g @mostajs/orm-cli
46
+ cd your/project
47
+ mostajs bootstrap
48
+ ```
33
49
 
34
- ### Interactive menu (recommended)
50
+ ## Subcommands
51
+
52
+ | Command | What it does |
53
+ |---|---|
54
+ | `mostajs bootstrap` | Full migration : codemod + install + convert + DDL |
55
+ | `mostajs install-bridge` | Run the codemod (dry-run by default) |
56
+ | `mostajs install-bridge --apply` | Write the codemod changes |
57
+ | `mostajs install-bridge --file <path>` | Restrict to one file |
58
+ | `mostajs install-bridge --restore --apply` | Revert `.prisma.bak` backups |
59
+ | `mostajs convert` | Auto-detect schema (Prisma / OpenAPI / JSONSchema) and convert |
60
+ | `mostajs detect` | Print what's detected in the project |
61
+ | `mostajs health` | Verify Node / pnpm / schemas / entities.json state |
62
+ | `mostajs hash <password> [cost]` | Bcrypt a password (for seed data) |
63
+ | `mostajs verify <password> <hash>` | Check a password/hash pair |
64
+ | `mostajs diagnose [email] [password]` | Walk through login diagnostics |
65
+ | `mostajs help` | Usage |
66
+ | `mostajs version` | Print version |
67
+
68
+ ## Interactive menu
35
69
 
36
70
  ```bash
37
71
  cd your/project
38
72
  mostajs
39
73
  ```
40
74
 
41
- The CLI auto-detects :
42
- - **Prisma** : `prisma/schema.prisma`
43
- - **OpenAPI** : `openapi.yaml`, `openapi.json`, `api.yaml`, `spec/openapi.yaml`, etc.
44
- - **JSON Schema** : `schemas/*.json`
45
-
46
- Menu :
75
+ Detected schemas are listed. Pick :
47
76
 
48
77
  ```
49
78
  1) Convert schema → EntitySchema[]
50
- 2) Configure database URIs (13 databases)
51
- 3) Initialize dialects (connect + create tables)
52
- 4) Tests menu (human / mobile / AI / curl / playwright)
53
- 5) Start services (Next.js + mosta-net)
79
+ 2) Configure database URIs
80
+ 3) Initialize dialects (connect + create tables)
81
+ 4) Tests menu (human / mobile / AI agent / curl / playwright)
82
+ 5) Start services
54
83
  6) Metrics & status
55
84
  7) View logs
56
85
  8) Health checks
57
- 9) Generate boilerplate (src/db.ts / .env.example)
86
+ 9) Generate boilerplate (src/db.ts / .env.example)
87
+ s) Seeding (upload / validate / hash / apply)
88
+ b) Bootstrap — one-shot Prisma migration
89
+ i) Install bridge (codemod)
58
90
  0) About / Help
91
+ q) Quit
59
92
  ```
60
93
 
61
- ### Non-interactive subcommands
94
+ ## The codemod, in detail
95
+
96
+ `mostajs install-bridge` is safe by default — **dry-run** reports what it would change, without touching files :
62
97
 
63
- ```bash
64
- mostajs convert # auto-detect + convert
65
- mostajs detect # print detected schemas
66
- mostajs health # check tools + project state
67
- mostajs version
68
- mostajs help
69
98
  ```
99
+ $ mostajs install-bridge
100
+ ▶ mostajs install-bridge — scanning /home/me/my-app
70
101
 
71
- ## What it does
102
+ Found 3 PrismaClient instantiation site(s):
103
+ → src/lib/db.ts (const db)
104
+ → src/server/prisma.ts (const prisma)
105
+ → scripts/seed.ts (const prisma)
72
106
 
73
- ### Tests menu everything you need to verify
107
+ Dry-run no files written. Re-run with --apply to execute.
108
+ ```
74
109
 
75
- - **Human** : opens browser on `http://localhost:3000`
76
- - **Mobile** : generates QR code for LAN URL (needs `qrencode`)
77
- - **AI** : displays ready-to-paste Claude Desktop MCP config
78
- - **curl** : smoke-tests all endpoints with status codes + times
79
- - **Playwright** : runs existing test suite
110
+ Detection rules :
111
+ - Must contain `import ... from '@prisma/client'` AND `new PrismaClient(`
112
+ - Files that already use `@mostajs/orm-bridge/prisma-client` are skipped (idempotent re-runs)
113
+ - Export shape is preserved : `const db`, `const prisma`, `let client`, `export default`, and `const x = ...; export { x }`
80
114
 
81
- ### Config stored per-project
115
+ Replacement format :
82
116
 
83
- ```
84
- your-project/.mostajs/
85
- ├── config.env # URIs + ports
86
- ├── generated/entities.ts # EntitySchema[] (auto-generated)
87
- └── logs/ # dev / convert / init logs
117
+ ```ts
118
+ // Auto-generated by `mostajs install-bridge` on 2026-04-14T02:03:38Z
119
+ // Original file backed up as <this-file>.prisma.bak
120
+ // Every db/prisma/client call is now routed to @mostajs/orm (13 dialects).
121
+ import { createPrismaLikeDb } from '@mostajs/orm-bridge/prisma-client'
122
+
123
+ export const db = createPrismaLikeDb()
88
124
  ```
89
125
 
90
- ### Supported databases (13)
126
+ ## Supported schemas at input
91
127
 
92
- PostgreSQL · MySQL · MariaDB · SQLite · MS SQL Server · Oracle · DB2 · HANA · HSQLDB · Spanner · Sybase · CockroachDB · MongoDB
128
+ The CLI auto-detects :
129
+ - **Prisma** — `prisma/schema.prisma`
130
+ - **OpenAPI** — `openapi.yaml`, `openapi.json`, `api.yaml`, `spec/openapi.yaml`, …
131
+ - **JSON Schema** — `schemas/*.json`
93
132
 
94
- ## Example workflow (any Prisma app)
133
+ Conversion goes through `@mostajs/orm-adapter` (4 adapters).
95
134
 
96
- ```bash
97
- $ cd my-nextjs-app
98
- $ mostajs
135
+ ## Supported databases (13)
99
136
 
100
- Project : /path/to/my-nextjs-app
101
- Manager : pnpm
102
- Detected:
103
- ✓ Prisma schema (40 models)
104
- ⚠ entities.ts not generated
137
+ SQLite · PostgreSQL · MySQL · MariaDB · MongoDB · Oracle · SQL Server · CockroachDB · DB2 · SAP HANA · HSQLDB · Spanner · Sybase
105
138
 
106
- Choice [1]: 1 # Convert
107
- entities : 40
108
- warnings : 0
109
- ✓ Saved : .mostajs/generated/entities.ts
139
+ Switch database by editing `.mostajs/config.env` (or `.env`) :
110
140
 
111
- Choice [1]: 9 # Generate boilerplate
112
- ✓ Written : src/db.ts (Prisma bridge)
141
+ ```bash
142
+ DB_DIALECT=postgres
143
+ SGBD_URI=postgres://user:pass@host:5432/mydb
144
+ ```
145
+
146
+ Then re-run `mostajs` → menu 3 (init DDL) → menu S → 4 (apply seeds). Same code.
113
147
 
114
- # now replace `new PrismaClient()` with `import { prisma } from './db.js'`
115
- # ... your existing Prisma code runs on 13 databases
148
+ ## Project layout
149
+
150
+ ```
151
+ your-project/
152
+ ├── prisma/schema.prisma # unchanged
153
+ ├── src/lib/db.ts # 3 lines now (createPrismaLikeDb)
154
+ ├── src/lib/db.ts.prisma.bak # original, in case you want to revert
155
+ └── .mostajs/
156
+ ├── config.env # DB_DIALECT, SGBD_URI, DB_SCHEMA_STRATEGY
157
+ ├── generated/entities.json # converted schema (13-DB-ready)
158
+ ├── seeds/*.json # one per entity, hashed by menu S → h
159
+ └── logs/ # convert / init / seed / dev
116
160
  ```
117
161
 
118
- ## Strategy
162
+ ## Example — FitZoneGym
119
163
 
120
- - **Schema conversion** : via [@mostajs/orm-adapter](https://www.npmjs.com/package/@mostajs/orm-adapter) 4 adapters (Prisma, JSON Schema, OpenAPI, Native)
121
- - **Runtime interception** : via [@mostajs/orm-bridge](https://www.npmjs.com/package/@mostajs/orm-bridge) — route Prisma calls to any of the 13 databases
122
- - **Zero rewrite** : your existing `prisma.user.findMany()` stays unchanged
164
+ FitZoneGym (production-grade Next.js 15 + Prisma, 40 models, 67 files importing Prisma) was migrated end-to-end with :
123
165
 
124
- ## Links
166
+ ```bash
167
+ cd FitZoneGym
168
+ npx @mostajs/orm-cli bootstrap # 15 PrismaClient sites rewritten, schema converted, DDL applied
169
+ # manually : add seeds to .mostajs/seeds/User.json
170
+ # manually : mostajs — menu S → h → 4
171
+ npm run dev # login alice@example.com / alice123 → 302 + session
172
+ ```
125
173
 
126
- - npm : https://www.npmjs.com/package/@mostajs/orm-cli
127
- - GitHub : https://github.com/apolocine/mosta-orm-cli
128
- - Ecosystem : [@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm), [@mostajs/orm-adapter](https://www.npmjs.com/package/@mostajs/orm-adapter), [@mostajs/orm-bridge](https://www.npmjs.com/package/@mostajs/orm-bridge)
174
+ Files modified by the user : **0** (codemod owned them all). Login, dashboard, API routes all work on SQLite instead of MongoDB.
129
175
 
130
176
  ## License
131
177
 
132
178
  **AGPL-3.0-or-later** + commercial license available.
133
179
 
134
- For commercial use in closed-source projects : drmdh@msn.com
180
+ For closed-source commercial use : drmdh@msn.com
181
+
182
+ ## Ecosystem
183
+
184
+ - [@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm) — the ORM (13 databases)
185
+ - [@mostajs/orm-bridge](https://www.npmjs.com/package/@mostajs/orm-bridge) — runtime drop-in for PrismaClient
186
+ - [@mostajs/orm-adapter](https://www.npmjs.com/package/@mostajs/orm-adapter) — schema format converters
135
187
 
136
188
  ## Author
137
189
 
@@ -95,7 +95,13 @@ function detectExportShape(source) {
95
95
 
96
96
  // ---------- Rewrite ----------
97
97
  function buildReplacement(shape) {
98
- const header = `// Auto-generated by \`mostajs install-bridge\` on ${new Date().toISOString()}\n// Original file backed up as <this-file>.prisma.bak\n// Every db/prisma/client call is now routed to @mostajs/orm (13 dialects).\nimport 'server-only'\nimport { createPrismaLikeDb } from '@mostajs/orm-bridge/prisma-client'\n`;
98
+ // Note : we do NOT emit `import 'server-only'` because FitZoneGym-class
99
+ // codebases often mix pages/ and app/ directories. `server-only` crashes
100
+ // the pages/ build even though the actual bundle never evaluates the
101
+ // forbidden import chain (lazy dialect loading in @mostajs/orm@1.9.3+).
102
+ // Projects that want the extra guarantee can add `import 'server-only'`
103
+ // manually — but it's not necessary for correctness.
104
+ const header = `// Auto-generated by \`mostajs install-bridge\` on ${new Date().toISOString()}\n// Original file backed up as <this-file>.prisma.bak\n// Every db/prisma/client call is now routed to @mostajs/orm (13 dialects).\nimport { createPrismaLikeDb } from '@mostajs/orm-bridge/prisma-client'\n`;
99
105
  if (shape.kind === 'default') {
100
106
  return `${header}\nexport default createPrismaLikeDb()\n`;
101
107
  }
package/bin/mostajs.sh CHANGED
@@ -2515,14 +2515,69 @@ run_subcommand() {
2515
2515
  fi
2516
2516
 
2517
2517
  mkdir -p "$CONFIG_DIR"
2518
- if [[ ! -f "$CONFIG_DIR/config.env" ]]; then
2518
+ # ── Database choice ──
2519
+ # Resolution order :
2520
+ # 1. existing .mostajs/config.env → honour it (user may have set it with `mostajs` menu 2)
2521
+ # 2. --dialect / --uri / --strategy CLI flags → non-interactive scripting
2522
+ # 3. $DB_DIALECT + $SGBD_URI env vars → non-interactive, no files on disk
2523
+ # 4. interactive prompt (default)
2524
+ if [[ -f "$CONFIG_DIR/config.env" ]]; then
2525
+ load_env
2526
+ info " using existing $CONFIG_DIR/config.env (dialect=$DB_DIALECT uri=$SGBD_URI)"
2527
+ else
2528
+ local bs_dialect="" bs_uri="" bs_strategy="update"
2529
+ for arg in "$@"; do
2530
+ case "$arg" in
2531
+ --dialect=*) bs_dialect="${arg#--dialect=}" ;;
2532
+ --uri=*) bs_uri="${arg#--uri=}" ;;
2533
+ --strategy=*) bs_strategy="${arg#--strategy=}" ;;
2534
+ esac
2535
+ done
2536
+ # Fall back to env vars
2537
+ [[ -z "$bs_dialect" ]] && bs_dialect="${DB_DIALECT:-}"
2538
+ [[ -z "$bs_uri" ]] && bs_uri="${SGBD_URI:-}"
2539
+
2540
+ if [[ -z "$bs_dialect" || -z "$bs_uri" ]]; then
2541
+ echo
2542
+ echo -e "${BOLD}▶ Database choice${RESET} ${DIM}(run \`$CLI_NAME\` then menu 2 beforehand to skip this prompt)${RESET}"
2543
+ echo
2544
+ echo " ${CYAN}1${RESET}) SQLite ${DIM}./data.sqlite (zero setup, recommended for trying out)${RESET}"
2545
+ echo " ${CYAN}2${RESET}) PostgreSQL ${DIM}postgres://user:pass@host:5432/db${RESET}"
2546
+ echo " ${CYAN}3${RESET}) MongoDB ${DIM}mongodb://user:pass@host:27017/db${RESET}"
2547
+ echo " ${CYAN}4${RESET}) MySQL ${DIM}mysql://user:pass@host:3306/db${RESET}"
2548
+ echo " ${CYAN}5${RESET}) MariaDB ${DIM}mariadb://user:pass@host:3306/db${RESET}"
2549
+ echo " ${CYAN}6${RESET}) Oracle ${DIM}oracle://user:pass@host:1521/XE${RESET}"
2550
+ echo " ${CYAN}7${RESET}) SQL Server ${DIM}mssql://user:pass@host:1433/db${RESET}"
2551
+ echo " ${CYAN}8${RESET}) CockroachDB ${DIM}postgresql://user:pass@host:26257/db?sslmode=disable${RESET}"
2552
+ echo " ${CYAN}9${RESET}) DB2 / HANA / HSQLDB / Spanner / Sybase / other (enter manually)"
2553
+ echo
2554
+ local c; c=$(ask "Choice" "1")
2555
+ case "$c" in
2556
+ 1) bs_dialect="sqlite"; bs_uri=$(ask "SQLite path" "./data.sqlite") ;;
2557
+ 2) bs_dialect="postgres"; bs_uri=$(ask "Postgres URI" "postgres://user:pass@localhost:5432/mydb") ;;
2558
+ 3) bs_dialect="mongodb"; bs_uri=$(ask "MongoDB URI" "mongodb://localhost:27017/mydb") ;;
2559
+ 4) bs_dialect="mysql"; bs_uri=$(ask "MySQL URI" "mysql://user:pass@localhost:3306/mydb") ;;
2560
+ 5) bs_dialect="mariadb"; bs_uri=$(ask "MariaDB URI" "mariadb://user:pass@localhost:3306/mydb") ;;
2561
+ 6) bs_dialect="oracle"; bs_uri=$(ask "Oracle URI" "oracle://user:pass@localhost:1521/XE") ;;
2562
+ 7) bs_dialect="mssql"; bs_uri=$(ask "SQL Server URI" "mssql://user:pass@localhost:1433/mydb") ;;
2563
+ 8) bs_dialect="cockroachdb"; bs_uri=$(ask "CockroachDB URI" "postgresql://root@localhost:26257/mydb?sslmode=disable") ;;
2564
+ 9) bs_dialect=$(ask "Dialect (db2|hana|hsqldb|spanner|sybase|other)" "")
2565
+ bs_uri=$(ask "URI" "") ;;
2566
+ *) err "Invalid choice"; exit 1 ;;
2567
+ esac
2568
+ [[ -z "$bs_dialect" || -z "$bs_uri" ]] && { err "dialect and uri are required"; exit 1; }
2569
+
2570
+ local chosen_strategy
2571
+ chosen_strategy=$(ask "Schema strategy (validate|update|create|create-drop|none)" "$bs_strategy")
2572
+ bs_strategy="$chosen_strategy"
2573
+ fi
2574
+
2519
2575
  cat > "$CONFIG_DIR/config.env" <<CFG
2520
- DB_DIALECT=sqlite
2521
- SGBD_URI=./data.sqlite
2522
- DB_SCHEMA_STRATEGY=update
2576
+ DB_DIALECT=$bs_dialect
2577
+ SGBD_URI=$bs_uri
2578
+ DB_SCHEMA_STRATEGY=$bs_strategy
2523
2579
  CFG
2524
- ok " wrote $CONFIG_DIR/config.env (defaults: sqlite ./data.sqlite)"
2525
- # Reload config so action_init_dialects picks up the new values
2580
+ ok " wrote $CONFIG_DIR/config.env (dialect=$bs_dialect)"
2526
2581
  load_env
2527
2582
  fi
2528
2583
 
@@ -2542,7 +2597,7 @@ CFG
2542
2597
 
2543
2598
  ✓ Bridge installed in-place. Original files backed up as *.prisma.bak
2544
2599
  ✓ Schema converted : $GENERATED_DIR/entities.json
2545
- ✓ DDL applied (DB_DIALECT=\$(grep ^DB_DIALECT $CONFIG_DIR/config.env | cut -d= -f2))
2600
+ ✓ DDL applied (DB_DIALECT=$DB_DIALECT SGBD_URI=$SGBD_URI)
2546
2601
 
2547
2602
  Next :
2548
2603
  - Add seeds to $CONFIG_DIR/seeds/*.json (one file per entity)
@@ -2566,8 +2621,11 @@ DONE
2566
2621
  cat <<EOF
2567
2622
  Usage :
2568
2623
  $CLI_NAME Interactive menu
2569
- $CLI_NAME bootstrap One-shot migration : codemod + deps + convert + DDL
2570
- $CLI_NAME install-bridge Codemod only (dry-run ; add --apply to write)
2624
+ $CLI_NAME bootstrap One-shot migration : codemod + deps + convert + DDL
2625
+ (interactive database picker unless config exists)
2626
+ $CLI_NAME bootstrap --dialect=postgres --uri=postgres://... --strategy=update
2627
+ Non-interactive bootstrap (for CI / scripts)
2628
+ $CLI_NAME install-bridge Codemod only (dry-run ; add --apply to write)
2571
2629
  $CLI_NAME install-bridge --apply Rewrite PrismaClient sites to use @mostajs/orm-bridge
2572
2630
  $CLI_NAME install-bridge --restore --apply Undo a prior install-bridge
2573
2631
  $CLI_NAME convert Run conversion (auto-detect schema type)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/orm-cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
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",