@onebun/core 0.1.17 → 0.1.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onebun/core",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Core package for OneBun framework - decorators, DI, modules, controllers",
5
5
  "license": "LGPL-3.0",
6
6
  "author": "RemRyahirev",
@@ -432,6 +432,236 @@ describe('OneBunApplication', () => {
432
432
  expect(prodApp).toBeInstanceOf(OneBunApplication);
433
433
  });
434
434
 
435
+ test('should use PORT env variable when port is not explicitly provided', () => {
436
+ const originalPort = process.env.PORT;
437
+ const originalHost = process.env.HOST;
438
+ try {
439
+ process.env.PORT = '4567';
440
+ delete process.env.HOST; // Clear HOST to get default
441
+
442
+ @Module({})
443
+ class TestModule {}
444
+
445
+ const app = createTestApp(TestModule);
446
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:4567');
447
+ } finally {
448
+ if (originalPort === undefined) {
449
+ delete process.env.PORT;
450
+ } else {
451
+ process.env.PORT = originalPort;
452
+ }
453
+ if (originalHost === undefined) {
454
+ delete process.env.HOST;
455
+ } else {
456
+ process.env.HOST = originalHost;
457
+ }
458
+ }
459
+ });
460
+
461
+ test('should use HOST env variable when host is not explicitly provided', () => {
462
+ const originalHost = process.env.HOST;
463
+ const originalPort = process.env.PORT;
464
+ try {
465
+ process.env.HOST = '192.168.1.100';
466
+ delete process.env.PORT; // Clear PORT to get default
467
+
468
+ @Module({})
469
+ class TestModule {}
470
+
471
+ const app = createTestApp(TestModule);
472
+ expect(app.getHttpUrl()).toBe('http://192.168.1.100:3000');
473
+ } finally {
474
+ if (originalHost === undefined) {
475
+ delete process.env.HOST;
476
+ } else {
477
+ process.env.HOST = originalHost;
478
+ }
479
+ if (originalPort === undefined) {
480
+ delete process.env.PORT;
481
+ } else {
482
+ process.env.PORT = originalPort;
483
+ }
484
+ }
485
+ });
486
+
487
+ test('should use both PORT and HOST env variables when not explicitly provided', () => {
488
+ const originalPort = process.env.PORT;
489
+ const originalHost = process.env.HOST;
490
+ try {
491
+ process.env.PORT = '8888';
492
+ process.env.HOST = '10.0.0.1';
493
+
494
+ @Module({})
495
+ class TestModule {}
496
+
497
+ const app = createTestApp(TestModule);
498
+ expect(app.getHttpUrl()).toBe('http://10.0.0.1:8888');
499
+ } finally {
500
+ if (originalPort === undefined) {
501
+ delete process.env.PORT;
502
+ } else {
503
+ process.env.PORT = originalPort;
504
+ }
505
+ if (originalHost === undefined) {
506
+ delete process.env.HOST;
507
+ } else {
508
+ process.env.HOST = originalHost;
509
+ }
510
+ }
511
+ });
512
+
513
+ test('should prefer explicit port over PORT env variable', () => {
514
+ const originalPort = process.env.PORT;
515
+ const originalHost = process.env.HOST;
516
+ try {
517
+ process.env.PORT = '9999';
518
+ delete process.env.HOST; // Clear HOST to get default
519
+
520
+ @Module({})
521
+ class TestModule {}
522
+
523
+ const app = createTestApp(TestModule, { port: 5555 });
524
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:5555');
525
+ } finally {
526
+ if (originalPort === undefined) {
527
+ delete process.env.PORT;
528
+ } else {
529
+ process.env.PORT = originalPort;
530
+ }
531
+ if (originalHost === undefined) {
532
+ delete process.env.HOST;
533
+ } else {
534
+ process.env.HOST = originalHost;
535
+ }
536
+ }
537
+ });
538
+
539
+ test('should prefer explicit host over HOST env variable', () => {
540
+ const originalHost = process.env.HOST;
541
+ const originalPort = process.env.PORT;
542
+ try {
543
+ process.env.HOST = '192.168.1.100';
544
+ delete process.env.PORT; // Clear PORT to get default
545
+
546
+ @Module({})
547
+ class TestModule {}
548
+
549
+ const app = createTestApp(TestModule, { host: 'localhost' });
550
+ expect(app.getHttpUrl()).toBe('http://localhost:3000');
551
+ } finally {
552
+ if (originalHost === undefined) {
553
+ delete process.env.HOST;
554
+ } else {
555
+ process.env.HOST = originalHost;
556
+ }
557
+ if (originalPort === undefined) {
558
+ delete process.env.PORT;
559
+ } else {
560
+ process.env.PORT = originalPort;
561
+ }
562
+ }
563
+ });
564
+
565
+ test('should use defaults when env variables are not set', () => {
566
+ const originalPort = process.env.PORT;
567
+ const originalHost = process.env.HOST;
568
+ try {
569
+ delete process.env.PORT;
570
+ delete process.env.HOST;
571
+
572
+ @Module({})
573
+ class TestModule {}
574
+
575
+ const app = createTestApp(TestModule);
576
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:3000');
577
+ } finally {
578
+ if (originalPort !== undefined) {
579
+ process.env.PORT = originalPort;
580
+ }
581
+ if (originalHost !== undefined) {
582
+ process.env.HOST = originalHost;
583
+ }
584
+ }
585
+ });
586
+
587
+ test('should ignore invalid PORT env variable and use default', () => {
588
+ const originalPort = process.env.PORT;
589
+ const originalHost = process.env.HOST;
590
+ try {
591
+ process.env.PORT = 'invalid';
592
+ delete process.env.HOST; // Clear HOST to get default
593
+
594
+ @Module({})
595
+ class TestModule {}
596
+
597
+ const app = createTestApp(TestModule);
598
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:3000');
599
+ } finally {
600
+ if (originalPort === undefined) {
601
+ delete process.env.PORT;
602
+ } else {
603
+ process.env.PORT = originalPort;
604
+ }
605
+ if (originalHost === undefined) {
606
+ delete process.env.HOST;
607
+ } else {
608
+ process.env.HOST = originalHost;
609
+ }
610
+ }
611
+ });
612
+
613
+ test('should ignore empty PORT env variable and use default', () => {
614
+ const originalPort = process.env.PORT;
615
+ const originalHost = process.env.HOST;
616
+ try {
617
+ process.env.PORT = '';
618
+ delete process.env.HOST; // Clear HOST to get default
619
+
620
+ @Module({})
621
+ class TestModule {}
622
+
623
+ const app = createTestApp(TestModule);
624
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:3000');
625
+ } finally {
626
+ if (originalPort === undefined) {
627
+ delete process.env.PORT;
628
+ } else {
629
+ process.env.PORT = originalPort;
630
+ }
631
+ if (originalHost === undefined) {
632
+ delete process.env.HOST;
633
+ } else {
634
+ process.env.HOST = originalHost;
635
+ }
636
+ }
637
+ });
638
+
639
+ test('should ignore empty HOST env variable and use default', () => {
640
+ const originalHost = process.env.HOST;
641
+ const originalPort = process.env.PORT;
642
+ try {
643
+ process.env.HOST = '';
644
+ delete process.env.PORT; // Clear PORT to get default
645
+
646
+ @Module({})
647
+ class TestModule {}
648
+
649
+ const app = createTestApp(TestModule);
650
+ expect(app.getHttpUrl()).toBe('http://0.0.0.0:3000');
651
+ } finally {
652
+ if (originalHost === undefined) {
653
+ delete process.env.HOST;
654
+ } else {
655
+ process.env.HOST = originalHost;
656
+ }
657
+ if (originalPort === undefined) {
658
+ delete process.env.PORT;
659
+ } else {
660
+ process.env.PORT = originalPort;
661
+ }
662
+ }
663
+ });
664
+
435
665
  test('should handle complex envSchema configuration', () => {
436
666
  @Module({})
437
667
  class TestModule {}
@@ -112,17 +112,48 @@ function normalizePath(path: string): string {
112
112
  return path.endsWith('/') ? path.slice(0, -1) : path;
113
113
  }
114
114
 
115
+ /**
116
+ * Resolve port from options, environment variable, or default.
117
+ * Priority: explicit option > PORT env > default (3000)
118
+ */
119
+ function resolvePort(explicitPort: number | undefined): number {
120
+ if (explicitPort !== undefined) {
121
+ return explicitPort;
122
+ }
123
+ const envPort = process.env.PORT;
124
+ if (envPort !== undefined && envPort !== '') {
125
+ const parsed = parseInt(envPort, 10);
126
+ if (!isNaN(parsed) && parsed > 0) {
127
+ return parsed;
128
+ }
129
+ }
130
+
131
+ return 3000;
132
+ }
133
+
134
+ /**
135
+ * Resolve host from options, environment variable, or default.
136
+ * Priority: explicit option > HOST env > default ('0.0.0.0')
137
+ */
138
+ function resolveHost(explicitHost: string | undefined): string {
139
+ if (explicitHost !== undefined) {
140
+ return explicitHost;
141
+ }
142
+ const envHost = process.env.HOST;
143
+ if (envHost !== undefined && envHost !== '') {
144
+ return envHost;
145
+ }
146
+
147
+ return '0.0.0.0';
148
+ }
149
+
115
150
  /**
116
151
  * OneBun Application
117
152
  */
118
153
  export class OneBunApplication {
119
154
  private rootModule: ModuleInstance;
120
155
  private server: ReturnType<typeof Bun.serve> | null = null;
121
- private options: ApplicationOptions = {
122
- port: 3000,
123
- host: '0.0.0.0',
124
- development: process.env.NODE_ENV !== 'production',
125
- };
156
+ private options: ApplicationOptions;
126
157
  private logger: SyncLogger;
127
158
  private config: IConfig<OneBunAppConfig>;
128
159
  private configService: ConfigServiceImpl | null = null;
@@ -144,9 +175,13 @@ export class OneBunApplication {
144
175
  moduleClass: new (...args: unknown[]) => object,
145
176
  options?: Partial<ApplicationOptions>,
146
177
  ) {
147
- if (options) {
148
- this.options = { ...this.options, ...options };
149
- }
178
+ // Resolve port and host with priority: explicit > env > default
179
+ this.options = {
180
+ port: resolvePort(options?.port),
181
+ host: resolveHost(options?.host),
182
+ development: options?.development ?? process.env.NODE_ENV !== 'production',
183
+ ...options,
184
+ };
150
185
 
151
186
  // Initialize configuration - TypedEnv if schema provided, otherwise NotInitializedConfig
152
187
  if (this.options.envSchema) {