fragment-ts 1.0.34 → 1.0.36

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 (72) hide show
  1. package/API.md +248 -38
  2. package/DOCS.md +327 -63
  3. package/NewCLIGENERATECOMMANDS.txt +5 -0
  4. package/README.md +168 -3
  5. package/USAGE.md +395 -2
  6. package/dist/cli/commands/build.command.d.ts.map +1 -1
  7. package/dist/cli/commands/build.command.js +20 -8
  8. package/dist/cli/commands/build.command.js.map +1 -1
  9. package/dist/cli/commands/diagnostics.command.d.ts +1 -2
  10. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -1
  11. package/dist/cli/commands/diagnostics.command.js +37 -23
  12. package/dist/cli/commands/diagnostics.command.js.map +1 -1
  13. package/dist/cli/commands/generate.command.d.ts +5 -1
  14. package/dist/cli/commands/generate.command.d.ts.map +1 -1
  15. package/dist/cli/commands/generate.command.js +171 -39
  16. package/dist/cli/commands/generate.command.js.map +1 -1
  17. package/dist/cli/commands/init.command.d.ts.map +1 -1
  18. package/dist/cli/commands/init.command.js +98 -28
  19. package/dist/cli/commands/init.command.js.map +1 -1
  20. package/dist/cli/commands/migrate.command.d.ts +10 -17
  21. package/dist/cli/commands/migrate.command.d.ts.map +1 -1
  22. package/dist/cli/commands/migrate.command.js +133 -170
  23. package/dist/cli/commands/migrate.command.js.map +1 -1
  24. package/dist/cli/commands/serve.command.d.ts.map +1 -1
  25. package/dist/cli/commands/serve.command.js +9 -4
  26. package/dist/cli/commands/serve.command.js.map +1 -1
  27. package/dist/cli/commands/test.command.d.ts.map +1 -1
  28. package/dist/cli/commands/test.command.js +24 -6
  29. package/dist/cli/commands/test.command.js.map +1 -1
  30. package/dist/core/scanner/component-scanner.d.ts +12 -0
  31. package/dist/core/scanner/component-scanner.d.ts.map +1 -1
  32. package/dist/core/scanner/component-scanner.js +82 -16
  33. package/dist/core/scanner/component-scanner.js.map +1 -1
  34. package/dist/shared/config.utils.d.ts +58 -0
  35. package/dist/shared/config.utils.d.ts.map +1 -0
  36. package/dist/shared/config.utils.js +137 -0
  37. package/dist/shared/config.utils.js.map +1 -0
  38. package/dist/shared/env.utils.d.ts +27 -0
  39. package/dist/shared/env.utils.d.ts.map +1 -0
  40. package/dist/shared/env.utils.js +68 -0
  41. package/dist/shared/env.utils.js.map +1 -0
  42. package/dist/shared/tsconfig.utils.d.ts +122 -0
  43. package/dist/shared/tsconfig.utils.d.ts.map +1 -0
  44. package/dist/shared/tsconfig.utils.js +305 -0
  45. package/dist/shared/tsconfig.utils.js.map +1 -0
  46. package/dist/testing/runner.d.ts +9 -1
  47. package/dist/testing/runner.d.ts.map +1 -1
  48. package/dist/testing/runner.js +50 -10
  49. package/dist/testing/runner.js.map +1 -1
  50. package/dist/typeorm/typeorm-module.d.ts +1 -0
  51. package/dist/typeorm/typeorm-module.d.ts.map +1 -1
  52. package/dist/typeorm/typeorm-module.js +193 -85
  53. package/dist/typeorm/typeorm-module.js.map +1 -1
  54. package/dist/web/application.d.ts +0 -1
  55. package/dist/web/application.d.ts.map +1 -1
  56. package/dist/web/application.js +4 -26
  57. package/dist/web/application.js.map +1 -1
  58. package/package.json +1 -1
  59. package/src/cli/commands/build.command.ts +24 -9
  60. package/src/cli/commands/diagnostics.command.ts +42 -30
  61. package/src/cli/commands/generate.command.ts +212 -52
  62. package/src/cli/commands/init.command.ts +100 -29
  63. package/src/cli/commands/migrate.command.ts +145 -198
  64. package/src/cli/commands/serve.command.ts +181 -170
  65. package/src/cli/commands/test.command.ts +25 -11
  66. package/src/core/scanner/component-scanner.ts +110 -20
  67. package/src/shared/config.utils.ts +148 -0
  68. package/src/shared/env.utils.ts +72 -0
  69. package/src/shared/tsconfig.utils.ts +360 -0
  70. package/src/testing/runner.ts +62 -14
  71. package/src/typeorm/typeorm-module.ts +209 -86
  72. package/src/web/application.ts +4 -33
@@ -1,6 +1,8 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { glob } from "glob";
4
+ import { EnvUtils } from "../shared/env.utils";
5
+ import { TsConfigUtils } from "../shared/tsconfig.utils";
4
6
 
5
7
  /* ======================================================
6
8
  * Global augmentation
@@ -42,6 +44,11 @@ export class TestRunner {
42
44
  error: string;
43
45
  stack?: string;
44
46
  }> = [];
47
+ private verbose = false;
48
+
49
+ constructor(options: { verbose?: boolean } = {}) {
50
+ this.verbose = options.verbose ?? false;
51
+ }
45
52
 
46
53
  describe(name: string, fn: () => void): void {
47
54
  const suite: TestSuite = {
@@ -111,7 +118,18 @@ export class TestRunner {
111
118
  this.passed++;
112
119
  } catch (error: any) {
113
120
  console.log(` ✗ ${test.name}`);
114
- console.error(` ${error?.message ?? error}`);
121
+
122
+ if (this.verbose || process.env.DEBUG === "true") {
123
+ console.error(` ${error?.message ?? error}`);
124
+ if (error?.stack) {
125
+ console.error(
126
+ ` Stack: ${error.stack.split("\n").slice(1, 3).join("\n")}`,
127
+ );
128
+ }
129
+ } else {
130
+ console.error(` ${error?.message ?? error}`);
131
+ }
132
+
115
133
  this.failed++;
116
134
  this.errors.push({
117
135
  suite: suite.name,
@@ -134,10 +152,10 @@ export class TestRunner {
134
152
  console.log(` ${err.suite} > ${err.test}`);
135
153
  console.log(` ${err.error}\n`);
136
154
  });
137
- process.exit(1);
155
+ process.exitCode = 1;
138
156
  } else {
139
157
  console.log("✅ All tests passed!\n");
140
- process.exit(0);
158
+ process.exitCode = 0;
141
159
  }
142
160
  }
143
161
 
@@ -168,6 +186,23 @@ export class TestRunner {
168
186
  }
169
187
  }
170
188
  }
189
+
190
+ /**
191
+ * Auto-detect test patterns based on environment and configuration
192
+ */
193
+ getAutoTestPattern(): string {
194
+ const isDevMode = EnvUtils.isDevelopmentMode();
195
+
196
+ if (isDevMode) {
197
+ // Development mode - use TypeScript
198
+ const srcDir = TsConfigUtils.getRootDir();
199
+ return `${path.relative(process.cwd(), srcDir)}/**/*.spec.ts`;
200
+ } else {
201
+ // Production mode - use JavaScript
202
+ const outDir = TsConfigUtils.getOutDir();
203
+ return `${path.relative(process.cwd(), outDir)}/**/*.spec.js`;
204
+ }
205
+ }
171
206
  }
172
207
 
173
208
  /* ======================================================
@@ -177,7 +212,13 @@ let runnerInstance: TestRunner | null = null;
177
212
 
178
213
  export function getTestRunner(): TestRunner {
179
214
  if (!runnerInstance) {
180
- runnerInstance = new TestRunner();
215
+ // Check for verbose mode
216
+ const verbose =
217
+ process.env.TEST_VERBOSE === "true" ||
218
+ process.argv.includes("--verbose") ||
219
+ process.argv.includes("-v");
220
+
221
+ runnerInstance = new TestRunner({ verbose });
181
222
  G.__testRunner = runnerInstance;
182
223
  }
183
224
  return runnerInstance;
@@ -270,7 +311,7 @@ export function expect(actual: any) {
270
311
  }
271
312
  },
272
313
 
273
- toThrow(expectedError?: string) {
314
+ toThrow(expectedError?: string | RegExp) {
274
315
  if (typeof actual !== "function") {
275
316
  throw new Error("toThrow expects a function");
276
317
  }
@@ -288,10 +329,20 @@ export function expect(actual: any) {
288
329
  throw new Error("Expected function to throw an error");
289
330
  }
290
331
 
291
- if (expectedError && error?.message !== expectedError) {
292
- throw new Error(
293
- `Expected error message "${expectedError}" but got "${error?.message}"`,
294
- );
332
+ if (expectedError) {
333
+ if (typeof expectedError === "string") {
334
+ if (error?.message !== expectedError) {
335
+ throw new Error(
336
+ `Expected error message "${expectedError}" but got "${error?.message}"`,
337
+ );
338
+ }
339
+ } else if (expectedError instanceof RegExp) {
340
+ if (!expectedError.test(error?.message)) {
341
+ throw new Error(
342
+ `Expected error message to match ${expectedError}, but got "${error?.message}"`,
343
+ );
344
+ }
345
+ }
295
346
  }
296
347
  },
297
348
 
@@ -355,11 +406,8 @@ if (require.main === module) {
355
406
  try {
356
407
  const runner = getTestRunner();
357
408
 
358
- // Auto-detect TypeScript based on arguments
359
- const isTsNode = process.argv.some(
360
- (arg) => arg.includes("ts-node") || arg.includes("ts-node/register"),
361
- );
362
- const pattern = isTsNode ? "src/**/*.spec.ts" : "dist/**/*.spec.js";
409
+ // Use auto-detection instead of hardcoded patterns
410
+ const pattern = runner.getAutoTestPattern();
363
411
 
364
412
  await runner.loadTestFiles(pattern);
365
413
  await runner.run();
@@ -70,6 +70,16 @@ type SupportedDatabaseConfig =
70
70
  | Partial<CapacitorConnectionOptions>
71
71
  | Partial<SpannerConnectionOptions>;
72
72
 
73
+ // New interface for the fragment.json structure
74
+ interface FragmentConfig {
75
+ development?: {
76
+ database?: SupportedDatabaseConfig;
77
+ };
78
+ production?: {
79
+ database?: SupportedDatabaseConfig;
80
+ };
81
+ }
82
+
73
83
  export class TypeORMModule {
74
84
  private static dataSource: DataSource;
75
85
 
@@ -276,10 +286,16 @@ export class TypeORMModule {
276
286
  database: config.database ?? "database.sqlite",
277
287
  synchronize: config.synchronize ?? false,
278
288
  logging: config.logging ?? false,
279
- entities: config.entities ?? ["dist/**/*.entity.js"],
280
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
281
- subscribers: config.subscribers ?? [],
282
- ...config,
289
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
290
+ ...(config.migrations !== undefined
291
+ ? { migrations: config.migrations }
292
+ : {}),
293
+ ...(config.subscribers !== undefined
294
+ ? { subscribers: config.subscribers }
295
+ : {}),
296
+ ...(config.maxQueryExecutionTime !== undefined
297
+ ? { maxQueryExecutionTime: config.maxQueryExecutionTime }
298
+ : {}),
283
299
  };
284
300
  }
285
301
 
@@ -291,10 +307,13 @@ export class TypeORMModule {
291
307
  database: config.database ?? "database.sqlite",
292
308
  synchronize: config.synchronize ?? false,
293
309
  logging: config.logging ?? false,
294
- entities: config.entities ?? ["dist/**/*.entity.js"],
295
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
296
- subscribers: config.subscribers ?? [],
297
- ...config,
310
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
311
+ ...(config.migrations !== undefined
312
+ ? { migrations: config.migrations }
313
+ : {}),
314
+ ...(config.subscribers !== undefined
315
+ ? { subscribers: config.subscribers }
316
+ : {}),
298
317
  };
299
318
  }
300
319
 
@@ -310,10 +329,16 @@ export class TypeORMModule {
310
329
  database: config.database ?? "app",
311
330
  synchronize: config.synchronize ?? false,
312
331
  logging: config.logging ?? false,
313
- entities: config.entities ?? ["dist/**/*.entity.js"],
314
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
315
- subscribers: config.subscribers ?? [],
316
- ...config,
332
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
333
+ ...(config.migrations !== undefined
334
+ ? { migrations: config.migrations }
335
+ : {}),
336
+ ...(config.subscribers !== undefined
337
+ ? { subscribers: config.subscribers }
338
+ : {}),
339
+ ...(config.maxQueryExecutionTime !== undefined
340
+ ? { maxQueryExecutionTime: config.maxQueryExecutionTime }
341
+ : {}),
317
342
  };
318
343
  }
319
344
 
@@ -329,10 +354,16 @@ export class TypeORMModule {
329
354
  database: config.database ?? "app",
330
355
  synchronize: config.synchronize ?? false,
331
356
  logging: config.logging ?? false,
332
- entities: config.entities ?? ["dist/**/*.entity.js"],
333
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
334
- subscribers: config.subscribers ?? [],
335
- ...config,
357
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
358
+ ...(config.migrations !== undefined
359
+ ? { migrations: config.migrations }
360
+ : {}),
361
+ ...(config.subscribers !== undefined
362
+ ? { subscribers: config.subscribers }
363
+ : {}),
364
+ ...(config.maxQueryExecutionTime !== undefined
365
+ ? { maxQueryExecutionTime: config.maxQueryExecutionTime }
366
+ : {}),
336
367
  };
337
368
  }
338
369
 
@@ -348,11 +379,14 @@ export class TypeORMModule {
348
379
  database: config.database ?? "defaultdb",
349
380
  synchronize: config.synchronize ?? false,
350
381
  logging: config.logging ?? false,
351
- entities: config.entities ?? ["dist/**/*.entity.js"],
352
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
353
- subscribers: config.subscribers ?? [],
354
382
  timeTravelQueries: config.timeTravelQueries ?? false,
355
- ...config,
383
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
384
+ ...(config.migrations !== undefined
385
+ ? { migrations: config.migrations }
386
+ : {}),
387
+ ...(config.subscribers !== undefined
388
+ ? { subscribers: config.subscribers }
389
+ : {}),
356
390
  };
357
391
  }
358
392
 
@@ -368,11 +402,14 @@ export class TypeORMModule {
368
402
  database: config.database ?? "master",
369
403
  synchronize: config.synchronize ?? false,
370
404
  logging: config.logging ?? false,
371
- entities: config.entities ?? ["dist/**/*.entity.js"],
372
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
373
- subscribers: config.subscribers ?? [],
374
- options: config.options,
375
- ...config,
405
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
406
+ ...(config.migrations !== undefined
407
+ ? { migrations: config.migrations }
408
+ : {}),
409
+ ...(config.subscribers !== undefined
410
+ ? { subscribers: config.subscribers }
411
+ : {}),
412
+ ...(config.options !== undefined ? { options: config.options } : {}),
376
413
  };
377
414
  }
378
415
 
@@ -388,10 +425,13 @@ export class TypeORMModule {
388
425
  sid: config.sid ?? "xe",
389
426
  synchronize: config.synchronize ?? false,
390
427
  logging: config.logging ?? false,
391
- entities: config.entities ?? ["dist/**/*.entity.js"],
392
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
393
- subscribers: config.subscribers ?? [],
394
- ...config,
428
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
429
+ ...(config.migrations !== undefined
430
+ ? { migrations: config.migrations }
431
+ : {}),
432
+ ...(config.subscribers !== undefined
433
+ ? { subscribers: config.subscribers }
434
+ : {}),
395
435
  };
396
436
  }
397
437
 
@@ -404,13 +444,16 @@ export class TypeORMModule {
404
444
  port: config.port ?? 30015,
405
445
  username: config.username ?? "SYSTEM",
406
446
  password: config.password ?? "",
407
- schema: config.schema,
408
447
  synchronize: config.synchronize ?? false,
409
448
  logging: config.logging ?? false,
410
- entities: config.entities ?? ["dist/**/*.entity.js"],
411
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
412
- subscribers: config.subscribers ?? [],
413
- ...config,
449
+ ...(config.schema !== undefined ? { schema: config.schema } : {}),
450
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
451
+ ...(config.migrations !== undefined
452
+ ? { migrations: config.migrations }
453
+ : {}),
454
+ ...(config.subscribers !== undefined
455
+ ? { subscribers: config.subscribers }
456
+ : {}),
414
457
  };
415
458
  }
416
459
 
@@ -442,14 +485,24 @@ export class TypeORMModule {
442
485
  password: config.password ?? "",
443
486
  synchronize: config.synchronize ?? false,
444
487
  logging: config.logging ?? false,
445
- entities: config.entities ?? ["dist/**/*.entity.js"],
446
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
447
- subscribers: config.subscribers ?? [],
448
- driver: config.driver,
449
- serviceConfigOptions: config.serviceConfigOptions,
450
- formatOptions: config.formatOptions,
451
- legacySpatialSupport: config.legacySpatialSupport,
452
- ssl: config.ssl,
488
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
489
+ ...(config.migrations !== undefined
490
+ ? { migrations: config.migrations }
491
+ : {}),
492
+ ...(config.subscribers !== undefined
493
+ ? { subscribers: config.subscribers }
494
+ : {}),
495
+ ...(config.driver !== undefined ? { driver: config.driver } : {}),
496
+ ...(config.serviceConfigOptions !== undefined
497
+ ? { serviceConfigOptions: config.serviceConfigOptions }
498
+ : {}),
499
+ ...(config.formatOptions !== undefined
500
+ ? { formatOptions: config.formatOptions }
501
+ : {}),
502
+ ...(config.legacySpatialSupport !== undefined
503
+ ? { legacySpatialSupport: config.legacySpatialSupport }
504
+ : {}),
505
+ ...(config.ssl !== undefined ? { ssl: config.ssl } : {}),
453
506
  };
454
507
  }
455
508
 
@@ -476,14 +529,26 @@ export class TypeORMModule {
476
529
  database: config.database ?? "app",
477
530
  synchronize: config.synchronize ?? false,
478
531
  logging: config.logging ?? false,
479
- entities: config.entities ?? ["dist/**/*.entity.js"],
480
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
481
- subscribers: config.subscribers ?? [],
482
- driver: config.driver,
483
- transformParameters: config.transformParameters,
484
- poolErrorHandler: config.poolErrorHandler,
485
- serviceConfigOptions: config.serviceConfigOptions,
486
- formatOptions: config.formatOptions,
532
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
533
+ ...(config.migrations !== undefined
534
+ ? { migrations: config.migrations }
535
+ : {}),
536
+ ...(config.subscribers !== undefined
537
+ ? { subscribers: config.subscribers }
538
+ : {}),
539
+ ...(config.driver !== undefined ? { driver: config.driver } : {}),
540
+ ...(config.transformParameters !== undefined
541
+ ? { transformParameters: config.transformParameters }
542
+ : {}),
543
+ ...(config.poolErrorHandler !== undefined
544
+ ? { poolErrorHandler: config.poolErrorHandler }
545
+ : {}),
546
+ ...(config.serviceConfigOptions !== undefined
547
+ ? { serviceConfigOptions: config.serviceConfigOptions }
548
+ : {}),
549
+ ...(config.formatOptions !== undefined
550
+ ? { formatOptions: config.formatOptions }
551
+ : {}),
487
552
  };
488
553
  }
489
554
 
@@ -497,10 +562,13 @@ export class TypeORMModule {
497
562
  databaseId: config.databaseId ?? "",
498
563
  synchronize: config.synchronize ?? false,
499
564
  logging: config.logging ?? false,
500
- entities: config.entities ?? ["dist/**/*.entity.js"],
501
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
502
- subscribers: config.subscribers ?? [],
503
- ...config,
565
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
566
+ ...(config.migrations !== undefined
567
+ ? { migrations: config.migrations }
568
+ : {}),
569
+ ...(config.subscribers !== undefined
570
+ ? { subscribers: config.subscribers }
571
+ : {}),
504
572
  };
505
573
  }
506
574
 
@@ -517,8 +585,7 @@ export class TypeORMModule {
517
585
  database: config.database ?? "app",
518
586
  synchronize: config.synchronize ?? false,
519
587
  logging: config.logging ?? false,
520
- entities: config.entities ?? ["dist/**/*.entity.js"],
521
- ...config,
588
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
522
589
  };
523
590
  }
524
591
 
@@ -534,10 +601,13 @@ export class TypeORMModule {
534
601
  location: config.location ?? "default",
535
602
  synchronize: config.synchronize ?? false,
536
603
  logging: config.logging ?? false,
537
- entities: config.entities ?? ["dist/**/*.entity.js"],
538
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
539
- subscribers: config.subscribers ?? [],
540
- ...config,
604
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
605
+ ...(config.migrations !== undefined
606
+ ? { migrations: config.migrations }
607
+ : {}),
608
+ ...(config.subscribers !== undefined
609
+ ? { subscribers: config.subscribers }
610
+ : {}),
541
611
  };
542
612
  }
543
613
 
@@ -555,17 +625,22 @@ export class TypeORMModule {
555
625
  database: config.database ?? "app.db",
556
626
  driver: config.driver,
557
627
  readOnly: config.readOnly ?? false,
558
- key: config.key,
559
628
  multithreading: config.multithreading ?? false,
560
629
  migrate: config.migrate ?? false,
561
- iosFlags: config.iosFlags,
562
- androidFlags: config.androidFlags,
563
630
  synchronize: config.synchronize ?? false,
564
631
  logging: config.logging ?? false,
565
- entities: config.entities ?? ["dist/**/*.entity.js"],
566
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
567
- subscribers: config.subscribers ?? [],
568
- ...config,
632
+ ...(config.key !== undefined ? { key: config.key } : {}),
633
+ ...(config.iosFlags !== undefined ? { iosFlags: config.iosFlags } : {}),
634
+ ...(config.androidFlags !== undefined
635
+ ? { androidFlags: config.androidFlags }
636
+ : {}),
637
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
638
+ ...(config.migrations !== undefined
639
+ ? { migrations: config.migrations }
640
+ : {}),
641
+ ...(config.subscribers !== undefined
642
+ ? { subscribers: config.subscribers }
643
+ : {}),
569
644
  };
570
645
  }
571
646
 
@@ -578,10 +653,13 @@ export class TypeORMModule {
578
653
  location: config.location ?? "default",
579
654
  synchronize: config.synchronize ?? false,
580
655
  logging: config.logging ?? false,
581
- entities: config.entities ?? ["dist/**/*.entity.js"],
582
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
583
- subscribers: config.subscribers ?? [],
584
- ...config,
656
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
657
+ ...(config.migrations !== undefined
658
+ ? { migrations: config.migrations }
659
+ : {}),
660
+ ...(config.subscribers !== undefined
661
+ ? { subscribers: config.subscribers }
662
+ : {}),
585
663
  };
586
664
  }
587
665
 
@@ -594,10 +672,13 @@ export class TypeORMModule {
594
672
  location: config.location ?? "browser",
595
673
  synchronize: config.synchronize ?? false,
596
674
  logging: config.logging ?? false,
597
- entities: config.entities ?? ["dist/**/*.entity.js"],
598
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
599
- subscribers: config.subscribers ?? [],
600
- ...config,
675
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
676
+ ...(config.migrations !== undefined
677
+ ? { migrations: config.migrations }
678
+ : {}),
679
+ ...(config.subscribers !== undefined
680
+ ? { subscribers: config.subscribers }
681
+ : {}),
601
682
  };
602
683
  }
603
684
 
@@ -616,10 +697,13 @@ export class TypeORMModule {
616
697
  driver: config.driver,
617
698
  synchronize: config.synchronize ?? false,
618
699
  logging: config.logging ?? false,
619
- entities: config.entities ?? ["dist/**/*.entity.js"],
620
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
621
- subscribers: config.subscribers ?? [],
622
- ...config,
700
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
701
+ ...(config.migrations !== undefined
702
+ ? { migrations: config.migrations }
703
+ : {}),
704
+ ...(config.subscribers !== undefined
705
+ ? { subscribers: config.subscribers }
706
+ : {}),
623
707
  };
624
708
  }
625
709
 
@@ -638,15 +722,18 @@ export class TypeORMModule {
638
722
  driver: config.driver,
639
723
  synchronize: config.synchronize ?? false,
640
724
  logging: config.logging ?? false,
641
- entities: config.entities ?? ["dist/**/*.entity.js"],
642
- migrations: config.migrations ?? ["dist/migrations/**/*.js"],
643
- subscribers: config.subscribers ?? [],
644
- ...config,
725
+ ...(config.entities !== undefined ? { entities: config.entities } : {}),
726
+ ...(config.migrations !== undefined
727
+ ? { migrations: config.migrations }
728
+ : {}),
729
+ ...(config.subscribers !== undefined
730
+ ? { subscribers: config.subscribers }
731
+ : {}),
645
732
  };
646
733
  }
647
734
 
648
735
  /* ======================================================
649
- * fragment.json loader
736
+ * fragment.json loader - UPDATED FOR NEW STRUCTURE
650
737
  * ====================================================== */
651
738
  private static loadFileConfig(): SupportedDatabaseConfig {
652
739
  const configPath = path.join(process.cwd(), "fragment.json");
@@ -656,8 +743,25 @@ export class TypeORMModule {
656
743
  }
657
744
 
658
745
  try {
659
- const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
660
- const dbConfig = raw.database ?? {};
746
+ const raw = JSON.parse(
747
+ fs.readFileSync(configPath, "utf-8"),
748
+ ) as FragmentConfig;
749
+
750
+ // Determine environment mode
751
+ const isDevMode = this.isDevelopmentMode();
752
+ console.log(`Detected ${isDevMode ? "development" : "production"} mode`);
753
+
754
+ // Get the appropriate config section
755
+ let dbConfig = {};
756
+ if (isDevMode && raw.development?.database) {
757
+ dbConfig = raw.development.database;
758
+ } else if (!isDevMode && raw.production?.database) {
759
+ dbConfig = raw.production.database;
760
+ } else if (raw.development?.database) {
761
+ // Fallback to development if production not found
762
+ dbConfig = raw.development.database;
763
+ console.warn("Production config not found, using development config");
764
+ }
661
765
 
662
766
  // Interpolate environment variables
663
767
  return this.interpolateEnvVars(dbConfig);
@@ -667,6 +771,25 @@ export class TypeORMModule {
667
771
  }
668
772
  }
669
773
 
774
+ /* ======================================================
775
+ * Environment detection
776
+ * ====================================================== */
777
+ private static isDevelopmentMode(): boolean {
778
+ // Check explicit environment variable
779
+ if (process.env.FRAGMENT_DEV_MODE !== undefined) {
780
+ return process.env.FRAGMENT_DEV_MODE === "true";
781
+ }
782
+
783
+ // Check NODE_ENV
784
+ if (process.env.NODE_ENV) {
785
+ return process.env.NODE_ENV === "development";
786
+ }
787
+
788
+ // Check if we're running TypeScript files directly (dev mode)
789
+ const mainFile = require.main?.filename || "";
790
+ return mainFile.includes(".ts") || mainFile.includes("ts-node");
791
+ }
792
+
670
793
  /* ======================================================
671
794
  * Utilities
672
795
  * ====================================================== */
@@ -19,6 +19,7 @@ import {
19
19
  Interceptor,
20
20
  ExceptionFilter,
21
21
  } from "./interfaces";
22
+ import { EnvUtils } from "../shared/env.utils";
22
23
 
23
24
  export class FragmentWebApplication {
24
25
  private app: Express;
@@ -93,8 +94,8 @@ export class FragmentWebApplication {
93
94
  console.log(`📁 dist/ exists: ${distExists}`);
94
95
  console.log(`📁 src/ exists: ${srcExists}`);
95
96
 
96
- // Determine if we're running TypeScript directly (dev) or compiled JS (prod)
97
- const isDevMode = this.isRunningTypeScript();
97
+ // Use EnvUtils for consistent environment detection
98
+ const isDevMode = EnvUtils.isDevelopmentMode();
98
99
  console.log(
99
100
  `💻 Running in ${isDevMode ? "development" : "production"} mode`,
100
101
  );
@@ -112,37 +113,7 @@ export class FragmentWebApplication {
112
113
  }
113
114
  }
114
115
 
115
- private isRunningTypeScript(): boolean {
116
- // Check if ts-node is in require.extensions
117
- if (require.extensions[".ts"]) {
118
- return true;
119
- }
120
-
121
- // Check if process is running with ts-node or tsx
122
- const execPath = process.argv[0];
123
- const scriptPath = process.argv[1] || "";
124
-
125
- if (
126
- execPath.includes("ts-node") ||
127
- execPath.includes("tsx") ||
128
- scriptPath.includes("ts-node") ||
129
- scriptPath.includes("tsx")
130
- ) {
131
- return true;
132
- }
133
-
134
- // Check if main module has .ts extension
135
- if (require.main?.filename.endsWith(".ts")) {
136
- return true;
137
- }
138
-
139
- // Check NODE_ENV or explicit flag
140
- if (process.env.FRAGMENT_DEV_MODE === "true") {
141
- return true;
142
- }
143
-
144
- return false;
145
- }
116
+ // Remove the old isRunningTypeScript method since we're using EnvUtils
146
117
 
147
118
  private discoverAndRegisterComponents(): void {
148
119
  const classes = this.metadataStorage.getAllClasses();