@mostajs/orm-cli 0.1.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/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ Copyright (c) 2026 Dr Hamid MADANI <drmdh@msn.com>
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Affero General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Affero General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Affero General Public License
17
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+
19
+ COMMERCIAL LICENSE
20
+
21
+ For organizations that cannot comply with the AGPL open-source requirements,
22
+ a commercial license is available. Contact: drmdh@msn.com
23
+
24
+ The commercial license allows you to:
25
+ - Use the software in proprietary/closed-source projects
26
+ - Modify without publishing your source code
27
+ - Get priority support and SLA
28
+
29
+ Contact: Dr Hamid MADANI <drmdh@msn.com>
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # @mostajs/orm-cli
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.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@mostajs/orm-cli.svg)](https://www.npmjs.com/package/@mostajs/orm-cli)
7
+ [![License: AGPL-3.0-or-later](https://img.shields.io/badge/License-AGPL%203.0-blue.svg)](LICENSE)
8
+
9
+ ## Install
10
+
11
+ ### Option 1 — npx (zero install)
12
+
13
+ ```bash
14
+ cd your/project
15
+ npx @mostajs/orm-cli
16
+ ```
17
+
18
+ ### Option 2 — global
19
+
20
+ ```bash
21
+ npm install -g @mostajs/orm-cli
22
+ cd your/project
23
+ mostajs
24
+ ```
25
+
26
+ ### Option 3 — curl one-liner (Unix)
27
+
28
+ ```bash
29
+ curl -fsSL https://raw.githubusercontent.com/apolocine/mosta-orm-cli/main/install.sh | bash
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Interactive menu (recommended)
35
+
36
+ ```bash
37
+ cd your/project
38
+ mostajs
39
+ ```
40
+
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 :
47
+
48
+ ```
49
+ 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)
54
+ 6) Metrics & status
55
+ 7) View logs
56
+ 8) Health checks
57
+ 9) Generate boilerplate (src/db.ts / .env.example)
58
+ 0) About / Help
59
+ ```
60
+
61
+ ### Non-interactive subcommands
62
+
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
+ ```
70
+
71
+ ## What it does
72
+
73
+ ### Tests menu — everything you need to verify
74
+
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
80
+
81
+ ### Config stored per-project
82
+
83
+ ```
84
+ your-project/.mostajs/
85
+ ├── config.env # URIs + ports
86
+ ├── generated/entities.ts # EntitySchema[] (auto-generated)
87
+ └── logs/ # dev / convert / init logs
88
+ ```
89
+
90
+ ### Supported databases (13)
91
+
92
+ PostgreSQL · MySQL · MariaDB · SQLite · MS SQL Server · Oracle · DB2 · HANA · HSQLDB · Spanner · Sybase · CockroachDB · MongoDB
93
+
94
+ ## Example workflow (any Prisma app)
95
+
96
+ ```bash
97
+ $ cd my-nextjs-app
98
+ $ mostajs
99
+
100
+ Project : /path/to/my-nextjs-app
101
+ Manager : pnpm
102
+ Detected:
103
+ ✓ Prisma schema (40 models)
104
+ ⚠ entities.ts not generated
105
+
106
+ Choice [1]: 1 # Convert
107
+ entities : 40
108
+ warnings : 0
109
+ ✓ Saved : .mostajs/generated/entities.ts
110
+
111
+ Choice [1]: 9 # Generate boilerplate
112
+ ✓ Written : src/db.ts (Prisma bridge)
113
+
114
+ # now replace `new PrismaClient()` with `import { prisma } from './db.js'`
115
+ # ... your existing Prisma code runs on 13 databases
116
+ ```
117
+
118
+ ## Strategy
119
+
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
123
+
124
+ ## Links
125
+
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)
129
+
130
+ ## License
131
+
132
+ **AGPL-3.0-or-later** + commercial license available.
133
+
134
+ For commercial use in closed-source projects : drmdh@msn.com
135
+
136
+ ## Author
137
+
138
+ Dr Hamid MADANI <drmdh@msn.com>
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // mostajs-launcher.cjs — cross-platform entry point for `mostajs` command
3
+ // Delegates to mostajs.sh on Unix, mostajs.bat on Windows.
4
+
5
+ const { spawn } = require('child_process');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+
10
+ const isWin = os.platform() === 'win32';
11
+ const binDir = __dirname;
12
+ const script = isWin
13
+ ? path.join(binDir, 'mostajs.bat')
14
+ : path.join(binDir, 'mostajs.sh');
15
+
16
+ if (!fs.existsSync(script)) {
17
+ console.error(`[mostajs] launcher error: ${script} not found.`);
18
+ process.exit(1);
19
+ }
20
+
21
+ // Ensure executable on unix
22
+ if (!isWin) {
23
+ try { fs.chmodSync(script, 0o755); } catch { /* ignore */ }
24
+ }
25
+
26
+ const args = process.argv.slice(2);
27
+ const child = isWin
28
+ ? spawn('cmd', ['/c', script, ...args], { stdio: 'inherit', cwd: process.cwd() })
29
+ : spawn('bash', [script, ...args], { stdio: 'inherit', cwd: process.cwd() });
30
+
31
+ child.on('exit', code => process.exit(code ?? 0));
32
+ child.on('error', err => {
33
+ console.error('[mostajs] launch failed:', err.message);
34
+ process.exit(1);
35
+ });
@@ -0,0 +1,490 @@
1
+ @echo off
2
+ :: mostajs.bat — Universal interactive CLI for @mostajs/orm integration (Windows)
3
+ :: Author: Dr Hamid MADANI drmdh@msn.com
4
+ :: License: AGPL-3.0-or-later
5
+
6
+ setlocal enabledelayedexpansion
7
+
8
+ set "CLI_VERSION=0.1.0"
9
+ set "PROJECT_ROOT=%cd%"
10
+ set "CONFIG_DIR=%PROJECT_ROOT%\.mostajs"
11
+ set "CONFIG_FILE=%CONFIG_DIR%\config.env"
12
+ set "LOG_DIR=%CONFIG_DIR%\logs"
13
+ set "GENERATED_DIR=%CONFIG_DIR%\generated"
14
+
15
+ if not exist "%CONFIG_DIR%" mkdir "%CONFIG_DIR%"
16
+ if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
17
+ if not exist "%GENERATED_DIR%" mkdir "%GENERATED_DIR%"
18
+
19
+ :: ---------- CLI subcommands ----------
20
+ if "%~1"=="" goto INTERACTIVE
21
+ if /i "%~1"=="convert" goto SUB_CONVERT
22
+ if /i "%~1"=="detect" goto SUB_DETECT
23
+ if /i "%~1"=="health" goto ACTION_HEALTH
24
+ if /i "%~1"=="version" (echo mostajs %CLI_VERSION% & exit /b 0)
25
+ if /i "%~1"=="help" goto SHOW_HELP
26
+ echo Unknown command: %~1
27
+ exit /b 1
28
+
29
+ :SHOW_HELP
30
+ echo.
31
+ echo Usage:
32
+ echo mostajs Interactive menu
33
+ echo mostajs convert Run conversion
34
+ echo mostajs detect Print detected schemas
35
+ echo mostajs health Run health checks
36
+ echo mostajs version Print version
37
+ exit /b 0
38
+
39
+ :INTERACTIVE
40
+
41
+ :MAIN_MENU
42
+ cls
43
+ call :LOAD_ENV
44
+ call :DETECT_PROJECT
45
+ echo ============================================================
46
+ echo @mostajs/orm-cli v%CLI_VERSION% - Universal Schema Adapter
47
+ echo ============================================================
48
+ echo.
49
+ echo Project : %PROJECT_ROOT%
50
+ echo Manager : %PKG_MANAGER%
51
+ echo Detected:
52
+ if defined PRISMA_SCHEMA echo [OK] Prisma : !PRISMA_MODELS! models
53
+ if defined OPENAPI_FILE echo [OK] OpenAPI : !OPENAPI_FILE!
54
+ if exist "%GENERATED_DIR%\entities.ts" (
55
+ echo [OK] entities.ts generated
56
+ ) else (
57
+ echo [!!] entities.ts not generated
58
+ )
59
+ echo.
60
+ echo ----- MAIN MENU -----
61
+ echo 1) Convert schema
62
+ echo 2) Configure database URIs
63
+ echo 3) Initialize dialects
64
+ echo 4) Tests menu
65
+ echo 5) Start services
66
+ echo 6) Metrics
67
+ echo 7) View logs
68
+ echo 8) Health checks
69
+ echo 9) Generate boilerplate
70
+ echo 0) About
71
+ echo Q) Quit
72
+ echo.
73
+ set /p "choice=Choice [1]: "
74
+ if "%choice%"=="" set "choice=1"
75
+
76
+ if /i "%choice%"=="1" goto ACTION_CONVERT
77
+ if /i "%choice%"=="2" goto MENU_DB
78
+ if /i "%choice%"=="3" goto ACTION_INIT
79
+ if /i "%choice%"=="4" goto MENU_TESTS
80
+ if /i "%choice%"=="5" goto MENU_SERVICES
81
+ if /i "%choice%"=="6" goto ACTION_METRICS
82
+ if /i "%choice%"=="7" goto ACTION_LOGS
83
+ if /i "%choice%"=="8" goto ACTION_HEALTH
84
+ if /i "%choice%"=="9" goto ACTION_BOILERPLATE
85
+ if /i "%choice%"=="0" goto ACTION_ABOUT
86
+ if /i "%choice%"=="q" goto END
87
+ goto MAIN_MENU
88
+
89
+ :: ============================================================
90
+ :: DETECT PROJECT
91
+ :: ============================================================
92
+ :DETECT_PROJECT
93
+ set "PRISMA_SCHEMA="
94
+ set "OPENAPI_FILE="
95
+ set "PRISMA_MODELS=0"
96
+ set "PKG_MANAGER=npm"
97
+ if exist "%PROJECT_ROOT%\pnpm-lock.yaml" set "PKG_MANAGER=pnpm"
98
+ if exist "%PROJECT_ROOT%\yarn.lock" set "PKG_MANAGER=yarn"
99
+ if exist "%PROJECT_ROOT%\prisma\schema.prisma" (
100
+ set "PRISMA_SCHEMA=%PROJECT_ROOT%\prisma\schema.prisma"
101
+ for /f %%A in ('findstr /c:"^model " "!PRISMA_SCHEMA!" 2^>nul ^| find /c /v ""') do set "PRISMA_MODELS=%%A"
102
+ )
103
+ for %%F in (openapi.yaml openapi.yml openapi.json api.yaml api.json) do (
104
+ if exist "%PROJECT_ROOT%\%%F" set "OPENAPI_FILE=%PROJECT_ROOT%\%%F"
105
+ )
106
+ exit /b 0
107
+
108
+ :: ============================================================
109
+ :: CONVERT
110
+ :: ============================================================
111
+ :ACTION_CONVERT
112
+ cls
113
+ call :DETECT_PROJECT
114
+ echo Converting schema -^> entities.ts
115
+ echo.
116
+ if defined PRISMA_SCHEMA (
117
+ set "INPUT_FILE=!PRISMA_SCHEMA!"
118
+ set "ADAPTER=PrismaAdapter"
119
+ set "IS_JSON=false"
120
+ ) else if defined OPENAPI_FILE (
121
+ set "INPUT_FILE=!OPENAPI_FILE!"
122
+ set "ADAPTER=OpenApiAdapter"
123
+ set "IS_JSON=false"
124
+ ) else (
125
+ echo [ERR] No schema detected.
126
+ pause
127
+ goto MAIN_MENU
128
+ )
129
+ echo Source : !INPUT_FILE!
130
+ echo Output : %GENERATED_DIR%\entities.ts
131
+ echo Adapter : !ADAPTER!
132
+ echo.
133
+
134
+ :: Check adapter installed
135
+ set "ADAPTER_PATH=%PROJECT_ROOT%\node_modules\@mostajs\orm-adapter\dist\index.js"
136
+ if not exist "!ADAPTER_PATH!" (
137
+ echo [!!] @mostajs/orm-adapter not installed in this project.
138
+ set /p "doit=Install now? [y/N]: "
139
+ if /i "!doit!"=="y" (
140
+ cd /d "%PROJECT_ROOT%"
141
+ call %PKG_MANAGER% install --save-dev @mostajs/orm-adapter @mostajs/orm
142
+ ) else (
143
+ pause
144
+ goto MAIN_MENU
145
+ )
146
+ )
147
+
148
+ node --input-type=module -e "import { readFileSync, writeFileSync } from 'fs'; import { !ADAPTER! } from '%PROJECT_ROOT%/node_modules/@mostajs/orm-adapter/dist/index.js'; const src = readFileSync('!INPUT_FILE!','utf8'); const input = '!IS_JSON!' === 'true' ? JSON.parse(src) : src; const w=[]; const e = await new !ADAPTER!().toEntitySchema(input,{onWarning:x=>w.push(x)}); console.log('entities:', e.length, 'warnings:', w.length); writeFileSync('%GENERATED_DIR%/entities.ts','// Auto-generated by @mostajs/orm-cli v%CLI_VERSION%\nimport type { EntitySchema } from \"@mostajs/orm\";\nexport const entities: EntitySchema[] = '+JSON.stringify(e,null,2)+';\nexport const entityByName = Object.fromEntries(entities.map(x=>[x.name,x]));\n');" > "%LOG_DIR%\convert.log" 2>&1
149
+ type "%LOG_DIR%\convert.log"
150
+ pause
151
+ goto MAIN_MENU
152
+
153
+ :SUB_CONVERT
154
+ call :DETECT_PROJECT
155
+ goto ACTION_CONVERT
156
+
157
+ :SUB_DETECT
158
+ call :DETECT_PROJECT
159
+ echo project : %PROJECT_ROOT%
160
+ echo manager : %PKG_MANAGER%
161
+ if defined PRISMA_SCHEMA echo prisma : %PRISMA_SCHEMA% (%PRISMA_MODELS% models)
162
+ if defined OPENAPI_FILE echo openapi : %OPENAPI_FILE%
163
+ exit /b 0
164
+
165
+ :: ============================================================
166
+ :: MENU 2 : DATABASES
167
+ :: ============================================================
168
+ :MENU_DB
169
+ cls
170
+ call :LOAD_ENV
171
+ echo ==== Database configuration ====
172
+ echo 1) MongoDB : %MONGODB_URI%
173
+ echo 2) PostgreSQL : %POSTGRES_URI%
174
+ echo 3) MySQL/MariaDB : %MYSQL_URI%
175
+ echo 4) SQLite : %SQLITE_URI%
176
+ echo 5) Oracle : %ORACLE_URI%
177
+ echo 6) MSSQL : %MSSQL_URI%
178
+ echo 7) DB2 : %DB2_URI%
179
+ echo P) App port : %APP_PORT%
180
+ echo N) mosta-net port : %MOSTA_NET_PORT%
181
+ echo R) Reset config
182
+ echo B) Back
183
+ echo.
184
+ set /p "choice=Choice: "
185
+ if /i "%choice%"=="1" set /p "v=MongoDB URI: " & call :SAVE_ENV MONGODB_URI "!v!" & goto MENU_DB
186
+ if /i "%choice%"=="2" set /p "v=PostgreSQL URI: " & call :SAVE_ENV POSTGRES_URI "!v!" & goto MENU_DB
187
+ if /i "%choice%"=="3" set /p "v=MySQL URI: " & call :SAVE_ENV MYSQL_URI "!v!" & goto MENU_DB
188
+ if /i "%choice%"=="4" set /p "v=SQLite path: " & call :SAVE_ENV SQLITE_URI "!v!" & goto MENU_DB
189
+ if /i "%choice%"=="5" set /p "v=Oracle URI: " & call :SAVE_ENV ORACLE_URI "!v!" & goto MENU_DB
190
+ if /i "%choice%"=="6" set /p "v=MSSQL URI: " & call :SAVE_ENV MSSQL_URI "!v!" & goto MENU_DB
191
+ if /i "%choice%"=="7" set /p "v=DB2 URI: " & call :SAVE_ENV DB2_URI "!v!" & goto MENU_DB
192
+ if /i "%choice%"=="p" set /p "v=App port: " & call :SAVE_ENV APP_PORT "!v!" & goto MENU_DB
193
+ if /i "%choice%"=="n" set /p "v=mosta-net port: " & call :SAVE_ENV MOSTA_NET_PORT "!v!" & goto MENU_DB
194
+ if /i "%choice%"=="r" del "%CONFIG_FILE%" 2>nul & goto MENU_DB
195
+ if /i "%choice%"=="b" goto MAIN_MENU
196
+ goto MENU_DB
197
+
198
+ :: ============================================================
199
+ :: ACTION 3 : INIT
200
+ :: ============================================================
201
+ :ACTION_INIT
202
+ cls
203
+ call :LOAD_ENV
204
+ if not exist "%GENERATED_DIR%\entities.ts" (
205
+ echo [ERR] Run conversion (menu 1) first.
206
+ pause
207
+ goto MAIN_MENU
208
+ )
209
+ echo Will initialize dialects for:
210
+ if defined MONGODB_URI echo - mongodb
211
+ if defined POSTGRES_URI echo - postgres
212
+ if defined MYSQL_URI echo - mysql
213
+ if defined SQLITE_URI echo - sqlite
214
+ if defined ORACLE_URI echo - oracle
215
+ echo.
216
+ set /p "go=Proceed? [y/N]: "
217
+ if /i not "!go!"=="y" goto MAIN_MENU
218
+ node "%GENERATED_DIR%\..\init-all.mjs" > "%LOG_DIR%\init.log" 2>&1
219
+ type "%LOG_DIR%\init.log"
220
+ pause
221
+ goto MAIN_MENU
222
+
223
+ :: ============================================================
224
+ :: MENU 4 : TESTS
225
+ :: ============================================================
226
+ :MENU_TESTS
227
+ cls
228
+ call :LOAD_ENV
229
+ echo ==== Tests menu ====
230
+ echo 1) Open app in browser
231
+ echo 2) Open mosta-net dashboard
232
+ echo 3) Mobile URL (QR if qrencode installed)
233
+ echo 4) MCP endpoint config (Claude/GPT)
234
+ echo 5) curl smoke test
235
+ echo 6) Playwright
236
+ echo B) Back
237
+ echo.
238
+ set /p "choice=Choice [1]: "
239
+ if "%choice%"=="" set "choice=1"
240
+ if /i "%choice%"=="1" start "" "http://localhost:%APP_PORT%" & goto MENU_TESTS
241
+ if /i "%choice%"=="2" start "" "http://localhost:%MOSTA_NET_PORT%" & goto MENU_TESTS
242
+ if /i "%choice%"=="3" goto ACTION_QR
243
+ if /i "%choice%"=="4" goto ACTION_MCP
244
+ if /i "%choice%"=="5" goto ACTION_CURL
245
+ if /i "%choice%"=="6" cd /d "%PROJECT_ROOT%" & call npx playwright test & pause & goto MENU_TESTS
246
+ if /i "%choice%"=="b" goto MAIN_MENU
247
+ goto MENU_TESTS
248
+
249
+ :ACTION_QR
250
+ cls
251
+ for /f "tokens=14" %%A in ('ipconfig ^| findstr /i "IPv4" ^| findstr /v "169.254"') do set "LOCAL_IP=%%A"
252
+ if not defined LOCAL_IP set "LOCAL_IP=localhost"
253
+ set "URL=http://!LOCAL_IP!:%APP_PORT%"
254
+ echo Mobile URL : !URL!
255
+ echo.
256
+ where qrencode >nul 2>nul
257
+ if not errorlevel 1 (qrencode -t ANSIUTF8 "!URL!") else (echo Install qrencode for QR generation)
258
+ pause
259
+ goto MENU_TESTS
260
+
261
+ :ACTION_MCP
262
+ cls
263
+ set "MCP_URL=http://localhost:%MOSTA_NET_PORT%/mcp"
264
+ echo MCP endpoint : !MCP_URL!
265
+ echo.
266
+ echo Claude Desktop config:
267
+ echo {
268
+ echo "mcpServers": {
269
+ for %%A in ("%PROJECT_ROOT%") do echo "%%~nA": { "url": "!MCP_URL!" }
270
+ echo }
271
+ echo }
272
+ pause
273
+ goto MENU_TESTS
274
+
275
+ :ACTION_CURL
276
+ cls
277
+ for %%U in ("http://localhost:%APP_PORT%/" "http://localhost:%APP_PORT%/api/health" "http://localhost:%MOSTA_NET_PORT%/" "http://localhost:%MOSTA_NET_PORT%/mcp") do (
278
+ echo GET %%~U
279
+ curl -s -o nul -w " status=%%{http_code} time=%%{time_total}s\n" --max-time 5 %%U
280
+ )
281
+ pause
282
+ goto MENU_TESTS
283
+
284
+ :: ============================================================
285
+ :: MENU 5 : SERVICES
286
+ :: ============================================================
287
+ :MENU_SERVICES
288
+ cls
289
+ call :LOAD_ENV
290
+ echo ==== Services ====
291
+ echo 1) Start dev server (new window)
292
+ echo 2) Show URLs
293
+ echo B) Back
294
+ echo.
295
+ set /p "choice=Choice [1]: "
296
+ if "%choice%"=="" set "choice=1"
297
+ if /i "%choice%"=="1" (
298
+ cd /d "%PROJECT_ROOT%"
299
+ start "dev" cmd /k "%PKG_MANAGER% run dev"
300
+ call :SHOW_URLS
301
+ pause
302
+ goto MENU_SERVICES
303
+ )
304
+ if /i "%choice%"=="2" call :SHOW_URLS & pause & goto MENU_SERVICES
305
+ if /i "%choice%"=="b" goto MAIN_MENU
306
+ goto MENU_SERVICES
307
+
308
+ :SHOW_URLS
309
+ echo.
310
+ echo Access URLs:
311
+ echo App (local) : http://localhost:%APP_PORT%
312
+ echo mosta-net : http://localhost:%MOSTA_NET_PORT%
313
+ echo MCP endpoint (AI) : http://localhost:%MOSTA_NET_PORT%/mcp
314
+ exit /b 0
315
+
316
+ :: ============================================================
317
+ :: ACTION 6 : METRICS
318
+ :: ============================================================
319
+ :ACTION_METRICS
320
+ cls
321
+ call :DETECT_PROJECT
322
+ echo ==== Metrics ====
323
+ if defined PRISMA_SCHEMA echo Prisma models : !PRISMA_MODELS!
324
+ if exist "%GENERATED_DIR%\entities.ts" (
325
+ for %%A in ("%GENERATED_DIR%\entities.ts") do echo entities.ts : %%~zA bytes
326
+ )
327
+ pause
328
+ goto MAIN_MENU
329
+
330
+ :: ============================================================
331
+ :: ACTION 7 : LOGS
332
+ :: ============================================================
333
+ :ACTION_LOGS
334
+ cls
335
+ echo ==== Logs ====
336
+ set "i=0"
337
+ for %%A in ("%LOG_DIR%\*.log") do (
338
+ set /a "i+=1"
339
+ echo !i!^) %%~nxA
340
+ set "LOG_!i!=%%A"
341
+ )
342
+ if %i%==0 (echo No logs yet & pause & goto MAIN_MENU)
343
+ set /p "c=File #: "
344
+ if defined LOG_%c% (call set "F=%%LOG_%c%%%" & type "!F!")
345
+ pause
346
+ goto MAIN_MENU
347
+
348
+ :: ============================================================
349
+ :: ACTION 8 : HEALTH
350
+ :: ============================================================
351
+ :ACTION_HEALTH
352
+ cls
353
+ call :DETECT_PROJECT
354
+ echo ==== Health checks ====
355
+ where node >nul 2>nul && (echo [OK] node) || (echo [ERR] node missing)
356
+ where %PKG_MANAGER% >nul 2>nul && (echo [OK] %PKG_MANAGER%) || (echo [ERR] %PKG_MANAGER% missing)
357
+ if exist "%PROJECT_ROOT%\package.json" (echo [OK] package.json) else (echo [!!] package.json missing)
358
+ if defined PRISMA_SCHEMA (echo [OK] Prisma schema ^(!PRISMA_MODELS! models^)) else (echo [!!] no Prisma schema)
359
+ if defined OPENAPI_FILE (echo [OK] OpenAPI file) else (echo [!!] no OpenAPI)
360
+ if exist "%GENERATED_DIR%\entities.ts" (echo [OK] entities generated) else (echo [!!] not generated)
361
+ where curl >nul 2>nul && (echo [OK] curl) || (echo [!!] curl missing)
362
+ where qrencode >nul 2>nul && (echo [OK] qrencode) || (echo [!!] qrencode optional - missing)
363
+ pause
364
+ goto MAIN_MENU
365
+
366
+ :: ============================================================
367
+ :: ACTION 9 : BOILERPLATE
368
+ :: ============================================================
369
+ :ACTION_BOILERPLATE
370
+ cls
371
+ echo ==== Boilerplate ====
372
+ echo 1) src\db.ts (Prisma bridge wrapper)
373
+ echo 2) src\mosta-orm.ts (direct usage)
374
+ echo 3) .env.example
375
+ echo.
376
+ set /p "c=Choice [1]: "
377
+ if "%c%"=="" set "c=1"
378
+ if "%c%"=="1" goto GEN_BRIDGE
379
+ if "%c%"=="2" goto GEN_DIRECT
380
+ if "%c%"=="3" goto GEN_ENV
381
+ goto MAIN_MENU
382
+
383
+ :GEN_BRIDGE
384
+ if not exist "%PROJECT_ROOT%\src" mkdir "%PROJECT_ROOT%\src"
385
+ (
386
+ echo // Auto-generated by @mostajs/orm-cli
387
+ echo import { PrismaClient } from '@prisma/client';
388
+ echo import { mostaExtension } from '@mostajs/orm-bridge/prisma';
389
+ echo import { entityByName } from '../.mostajs/generated/entities.js';
390
+ echo.
391
+ echo export const prisma = new PrismaClient^(^).$extends^(mostaExtension^({
392
+ echo models: {
393
+ echo // AuditLog: { dialect: 'mongodb', url: process.env.MONGODB_URI!, schema: entityByName.AuditLog },
394
+ echo },
395
+ echo fallback: 'source',
396
+ echo }^)^);
397
+ ) > "%PROJECT_ROOT%\src\db.ts"
398
+ echo [OK] Written src\db.ts
399
+ pause
400
+ goto MAIN_MENU
401
+
402
+ :GEN_DIRECT
403
+ if not exist "%PROJECT_ROOT%\src" mkdir "%PROJECT_ROOT%\src"
404
+ (
405
+ echo // Auto-generated by @mostajs/orm-cli
406
+ echo import { getDialect } from '@mostajs/orm';
407
+ echo import { entities } from '../.mostajs/generated/entities.js';
408
+ echo.
409
+ echo export async function createOrm^(^) {
410
+ echo const dialect = await getDialect^({ dialect: 'postgres', uri: process.env.DATABASE_URL! }^);
411
+ echo await dialect.initSchema^(entities^);
412
+ echo return { dialect, entities };
413
+ echo }
414
+ ) > "%PROJECT_ROOT%\src\mosta-orm.ts"
415
+ echo [OK] Written src\mosta-orm.ts
416
+ pause
417
+ goto MAIN_MENU
418
+
419
+ :GEN_ENV
420
+ (
421
+ echo MONGODB_URI=mongodb://localhost:27017/app
422
+ echo POSTGRES_URI=postgres://user:pw@localhost:5432/app
423
+ echo MYSQL_URI=mysql://user:pw@localhost:3306/app
424
+ echo APP_PORT=3000
425
+ echo MOSTA_NET_PORT=4447
426
+ ) > "%PROJECT_ROOT%\.env.example"
427
+ echo [OK] Written .env.example
428
+ pause
429
+ goto MAIN_MENU
430
+
431
+ :: ============================================================
432
+ :: ACTION 0 : ABOUT
433
+ :: ============================================================
434
+ :ACTION_ABOUT
435
+ cls
436
+ echo ============================================================
437
+ echo mostajs-cli v%CLI_VERSION%
438
+ echo ============================================================
439
+ echo.
440
+ echo Convert schemas to @mostajs/orm EntitySchema[]
441
+ echo Gain access to 13 databases without rewriting code.
442
+ echo.
443
+ echo Inputs : Prisma, OpenAPI, JSON Schema
444
+ echo DBs : PostgreSQL, MySQL, MariaDB, SQLite, MSSQL, Oracle,
445
+ echo DB2, CockroachDB, HANA, HSQLDB, Spanner, Sybase, MongoDB
446
+ echo.
447
+ echo Packages:
448
+ echo @mostajs/orm
449
+ echo @mostajs/orm-adapter
450
+ echo @mostajs/orm-bridge
451
+ echo.
452
+ echo Author : Dr Hamid MADANI ^<drmdh@msn.com^>
453
+ echo License : AGPL-3.0-or-later
454
+ pause
455
+ goto MAIN_MENU
456
+
457
+ :: ============================================================
458
+ :: HELPERS
459
+ :: ============================================================
460
+ :LOAD_ENV
461
+ set "MONGODB_URI="
462
+ set "POSTGRES_URI="
463
+ set "MYSQL_URI="
464
+ set "SQLITE_URI="
465
+ set "ORACLE_URI="
466
+ set "MSSQL_URI="
467
+ set "DB2_URI="
468
+ set "APP_PORT=3000"
469
+ set "MOSTA_NET_PORT=4447"
470
+ if exist "%CONFIG_FILE%" (
471
+ for /f "tokens=1,* delims==" %%A in ('type "%CONFIG_FILE%"') do set "%%A=%%B"
472
+ )
473
+ exit /b 0
474
+
475
+ :SAVE_ENV
476
+ set "KEY=%~1"
477
+ set "VAL=%~2"
478
+ if not exist "%CONFIG_FILE%" (
479
+ echo %KEY%=%VAL%> "%CONFIG_FILE%"
480
+ ) else (
481
+ findstr /v "^%KEY%=" "%CONFIG_FILE%" > "%CONFIG_FILE%.tmp" 2>nul
482
+ echo %KEY%=%VAL%>> "%CONFIG_FILE%.tmp"
483
+ move /y "%CONFIG_FILE%.tmp" "%CONFIG_FILE%" >nul
484
+ )
485
+ echo [OK] Saved %KEY%
486
+ exit /b 0
487
+
488
+ :END
489
+ endlocal
490
+ exit /b 0