@mostajs/orm-cli 0.5.12 → 0.5.14

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
@@ -268,6 +268,16 @@ detect_project() {
268
268
 
269
269
  [[ ${#JSON_SCHEMAS[@]} -gt 0 ]] && DETECTED_TYPES+=("jsonschema")
270
270
 
271
+ # Native .mjs/.js schemas (schemas.mjs, schemas.js at root)
272
+ NATIVE_SCHEMA=""
273
+ for candidate in schemas.mjs schemas.js schemas.ts src/schemas.mjs src/schemas.js src/schemas.ts; do
274
+ if [[ -f "$PROJECT_ROOT/$candidate" ]]; then
275
+ NATIVE_SCHEMA="$PROJECT_ROOT/$candidate"
276
+ DETECTED_TYPES+=("native")
277
+ break
278
+ fi
279
+ done
280
+
271
281
  # Package manager
272
282
  if [[ -f "$PROJECT_ROOT/pnpm-lock.yaml" ]]; then PKG_MANAGER="pnpm"
273
283
  elif [[ -f "$PROJECT_ROOT/yarn.lock" ]]; then PKG_MANAGER="yarn"
@@ -281,6 +291,71 @@ detect_project() {
281
291
  # npm / npx wrapper — finds the installed adapter or uses npx
282
292
  # ============================================================
283
293
 
294
+ # Convert a native .mjs/.js/.ts file that exports EntitySchema objects.
295
+ # No adapter needed — just import and collect every export that looks like
296
+ # an EntitySchema (has .name + .collection).
297
+ run_native_convert() {
298
+ local input_file="$1"
299
+ local output_file="$2"
300
+ local abs_input
301
+ abs_input="$(cd "$(dirname "$input_file")" && pwd)/$(basename "$input_file")"
302
+
303
+ cat > "$CONFIG_DIR/convert-native.mjs" << NEOF
304
+ import { writeFileSync } from 'fs';
305
+ import { resolve } from 'path';
306
+
307
+ const mod = await import('$abs_input');
308
+ const entities = Object.values(mod).filter(
309
+ v => v && typeof v === 'object' && typeof v.name === 'string' && typeof v.collection === 'string'
310
+ );
311
+
312
+ if (entities.length === 0) {
313
+ console.error('No EntitySchema exports found in $input_file');
314
+ console.error('Expected exports with { name, collection, fields, ... }');
315
+ process.exit(1);
316
+ }
317
+
318
+ console.log('entities : ' + entities.length);
319
+ for (const e of entities) console.log(' • ' + e.name + ' → ' + e.collection);
320
+
321
+ const header = '// Auto-generated by @mostajs/orm-cli v$VERSION at ' + new Date().toISOString() + '\\n';
322
+ const code = header +
323
+ '// Source : $input_file (native import)\\n' +
324
+ '// DO NOT EDIT BY HAND — regenerate with: mostajs convert\\n\\n' +
325
+ 'import type { EntitySchema } from "@mostajs/orm";\\n\\n' +
326
+ 'export const entities: EntitySchema[] = ' + JSON.stringify(entities, null, 2) + ';\\n\\n' +
327
+ 'export const entityByName: Record<string, EntitySchema> = Object.fromEntries(\\n' +
328
+ ' entities.map(e => [e.name, e])\\n' +
329
+ ');\\n';
330
+
331
+ const outTs = '$output_file';
332
+ const outJson = outTs.replace(/\\.ts\$/, '.json');
333
+ writeFileSync(outTs, code);
334
+ writeFileSync(outJson, JSON.stringify(entities, null, 2));
335
+ console.log('✓ Saved : ' + outTs);
336
+ console.log('✓ Saved : ' + outJson);
337
+ NEOF
338
+
339
+ local rc=0
340
+ # .ts input needs tsx/ts-node ; .mjs/.js runs with plain node
341
+ local runner="node"
342
+ if [[ "$input_file" =~ \.ts$ ]]; then
343
+ if command -v tsx >/dev/null 2>&1; then
344
+ runner="tsx"
345
+ elif npx --no-install tsx --version >/dev/null 2>&1; then
346
+ runner="npx tsx"
347
+ else
348
+ warn ".ts file detected but tsx not found — trying node (may fail)"
349
+ fi
350
+ fi
351
+ $runner "$CONFIG_DIR/convert-native.mjs" 2>&1 | tee "$LOG_DIR/convert.log"
352
+ rc=${PIPESTATUS[0]}
353
+ if [[ $rc -ne 0 ]]; then
354
+ err "Conversion exited with code $rc"
355
+ info "See $LOG_DIR/convert.log for details"
356
+ fi
357
+ }
358
+
284
359
  run_adapter_convert() {
285
360
  local input_type="$1" # prisma | jsonschema | openapi
286
361
  local input_file="$2"
@@ -572,6 +647,8 @@ action_convert() {
572
647
  PRISMA_SCHEMA="$f"; DETECTED_TYPES=("prisma")
573
648
  elif [[ "$f" =~ \.ya?ml$ ]] || grep -q "^openapi:" "$f" 2>/dev/null; then
574
649
  OPENAPI_FILE="$f"; DETECTED_TYPES=("openapi")
650
+ elif [[ "$f" =~ \.(mjs|js|ts)$ ]]; then
651
+ NATIVE_SCHEMA="$f"; DETECTED_TYPES=("native")
575
652
  else
576
653
  JSON_SCHEMAS=("$f"); DETECTED_TYPES=("jsonschema")
577
654
  fi
@@ -596,12 +673,19 @@ action_convert() {
596
673
  prisma) input="$PRISMA_SCHEMA" ;;
597
674
  openapi) input="$OPENAPI_FILE" ;;
598
675
  jsonschema) input="${JSON_SCHEMAS[0]}" ;;
676
+ native) input="$NATIVE_SCHEMA" ;;
599
677
  esac
600
678
 
601
679
  info "Input : $input"
602
680
  info "Output: $GENERATED_DIR/entities.ts"
603
681
  echo
604
- run_adapter_convert "$type" "$input" "$GENERATED_DIR/entities.ts"
682
+
683
+ if [[ "$type" == "native" ]]; then
684
+ # Native .mjs/.js/.ts — dynamic import, extract EntitySchema exports
685
+ run_native_convert "$input" "$GENERATED_DIR/entities.ts"
686
+ else
687
+ run_adapter_convert "$type" "$input" "$GENERATED_DIR/entities.ts"
688
+ fi
605
689
  pause
606
690
  }
607
691
 
@@ -1414,6 +1498,8 @@ menu_services() {
1414
1498
  echo -e " ${CYAN}3${RESET}) Stop all tracked services"
1415
1499
  echo -e " ${CYAN}4${RESET}) Status"
1416
1500
  echo -e " ${CYAN}5${RESET}) Show access URLs"
1501
+ echo -e " ${CYAN}6${RESET}) ${BOLD}Setup services${RESET} — scaffold replicator + monitor + config.env + dev:all"
1502
+ echo -e " ${CYAN}7${RESET}) Start all (dev + replicator + monitor via ${DIM}npm run dev:all${RESET})"
1417
1503
  echo
1418
1504
  echo -e " ${CYAN}b${RESET}) Back"
1419
1505
  echo
@@ -1424,6 +1510,8 @@ menu_services() {
1424
1510
  3) svc_stop_all;;
1425
1511
  4) svc_status;;
1426
1512
  5) show_urls;;
1513
+ 6) action_setup_services;;
1514
+ 7) svc_start_dev_all;;
1427
1515
  b|B) return;;
1428
1516
  *) warn Unknown;;
1429
1517
  esac
@@ -1431,6 +1519,38 @@ menu_services() {
1431
1519
  menu_services
1432
1520
  }
1433
1521
 
1522
+ action_setup_services() {
1523
+ header
1524
+ echo -e "${BOLD}${MAGENTA}▶ Setup services (scaffold + config)${RESET}"
1525
+ echo
1526
+ echo -e " This will :"
1527
+ echo -e " 1. Scaffold ${CYAN}services/replicator.mjs${RESET} + ${CYAN}services/monitor.mjs${RESET}"
1528
+ echo -e " 2. Patch ${CYAN}package.json${RESET} scripts (replicator / monitor / dev:all)"
1529
+ echo -e " 3. Write ${CYAN}.mostajs/config.env${RESET} (MONITOR_PORT, REPLICATOR_INTERVAL_MS)"
1530
+ echo -e " 4. Create ${CYAN}.env${RESET} if missing"
1531
+ echo -e " 5. Install ${CYAN}concurrently${RESET} if missing"
1532
+ echo
1533
+ if ! confirm "Proceed?"; then return; fi
1534
+
1535
+ # Reuse the replicator scaffold action (menu r → s) which does all of the above
1536
+ action_rep_scaffold_services
1537
+ }
1538
+
1539
+ svc_start_dev_all() {
1540
+ cd "$PROJECT_ROOT" || return
1541
+ if [[ ! -f package.json ]]; then err "No package.json"; return; fi
1542
+ local has_devall
1543
+ has_devall=$(node -e "try{const p=JSON.parse(require('fs').readFileSync('package.json','utf8'));console.log(p.scripts?.['dev:all']?'yes':'no')}catch{console.log('no')}" 2>/dev/null)
1544
+ if [[ "$has_devall" != "yes" ]]; then
1545
+ warn "script 'dev:all' not found in package.json"
1546
+ info "Run menu 5 → 6 (Setup services) first to scaffold + patch."
1547
+ return
1548
+ fi
1549
+ info "Starting dev:all (logs → terminal, Ctrl+C to stop)"
1550
+ echo
1551
+ "$PKG_MANAGER" run dev:all
1552
+ }
1553
+
1434
1554
  svc_start_dev() {
1435
1555
  cd "$PROJECT_ROOT"
1436
1556
  if [[ ! -f package.json ]]; then err "No package.json"; return; fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/orm-cli",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
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",