@mostajs/orm-cli 0.5.11 → 0.5.13

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 +96 -12
  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
 
@@ -2120,19 +2204,19 @@ action_rep_promote() {
2120
2204
  # is just a role swap in the JSON — no DB connection needed.
2121
2205
  _tree_patch "
2122
2206
  const reps = tree.replicas['$project'];
2123
- if (!reps) { console.log(' ✗ project \"$project\" not found'); return; }
2124
- if (!reps['$name']) { console.log(' ✗ replica \"$name\" not found in $project'); return; }
2125
- if (reps['$name'].role === 'master') { console.log(' • $name is already master'); return; }
2126
- // Demote current master(s) to slave
2127
- for (const [n, cfg] of Object.entries(reps)) {
2128
- if (cfg.role === 'master') {
2129
- cfg.role = 'slave';
2130
- console.log(' ↓ ' + n + ' demoted to slave');
2207
+ if (!reps) { console.log(' ✗ project \"$project\" not found'); }
2208
+ else if (!reps['$name']) { console.log(' ✗ replica \"$name\" not found in $project'); }
2209
+ else if (reps['$name'].role === 'master') { console.log(' • $name is already master'); }
2210
+ else {
2211
+ for (const [n, cfg] of Object.entries(reps)) {
2212
+ if (cfg.role === 'master') {
2213
+ cfg.role = 'slave';
2214
+ console.log(' ↓ ' + n + ' demoted to slave');
2215
+ }
2131
2216
  }
2217
+ reps['$name'].role = 'master';
2218
+ console.log(' ★ $name promoted to master');
2132
2219
  }
2133
- // Promote target to master
2134
- reps['$name'].role = 'master';
2135
- console.log(' ★ $name promoted to master');
2136
2220
  "
2137
2221
  pause
2138
2222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/orm-cli",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
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",