roster-server 1.9.4 → 1.9.6

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/README.md CHANGED
@@ -205,27 +205,11 @@ const roster = new Roster({
205
205
  });
206
206
  ```
207
207
 
208
- ### Getting Local URLs
208
+ ### Getting URLs
209
209
 
210
- RosterServer provides two methods to get the local URL for a domain:
210
+ RosterServer provides a method to get the URL for a domain that adapts automatically to your environment:
211
211
 
212
- **1. Static Method (Predictable, No Instance Required):**
213
-
214
- ```javascript
215
- // Get the URL before starting the server (using default range 4000-9999)
216
- const url = Roster.getLocalUrl('example.com');
217
- console.log(url); // http://localhost:9465
218
-
219
- // Or specify custom port range
220
- const customUrl = Roster.getLocalUrl('example.com', {
221
- minLocalPort: 5000,
222
- maxLocalPort: 6000
223
- });
224
- ```
225
-
226
- This static method calculates the port deterministically using CRC32, so you can predict the URL before even creating a Roster instance.
227
-
228
- **2. Instance Method (After Registration):**
212
+ **Instance Method: `roster.getUrl(domain)`**
229
213
 
230
214
  ```javascript
231
215
  const roster = new Roster({ local: true });
@@ -233,29 +217,43 @@ roster.register('example.com', handler);
233
217
 
234
218
  await roster.start();
235
219
 
236
- // Get the actual URL assigned to the domain
237
- const url = roster.getLocalUrl('example.com');
238
- console.log(url); // http://localhost:9465
220
+ // Get the URL - automatically adapts to environment
221
+ const url = roster.getUrl('example.com');
222
+ console.log(url);
223
+ // Local mode: http://localhost:9465
224
+ // Production mode: https://example.com
239
225
  ```
240
226
 
241
- This instance method returns the actual URL assigned to the domain after the server starts. It's useful when you need to confirm the URL or when there might be port collisions.
227
+ This method:
228
+ - Returns the correct URL based on your environment (`local: true/false`)
229
+ - In **local mode**: Returns `http://localhost:{port}` with the assigned port
230
+ - In **production mode**: Returns `https://{domain}` (or with custom port if configured)
231
+ - Handles `www.` prefix automatically (returns same URL)
232
+ - Returns `null` for domains that aren't registered
242
233
 
243
234
  **Example Usage:**
244
235
 
245
236
  ```javascript
246
- const roster = new Roster({ local: true });
247
-
248
- roster.register('example.com', (httpsServer) => {
249
- return (req, res) => {
250
- res.writeHead(200);
251
- res.end('Hello World!');
252
- };
253
- });
254
-
255
- roster.start().then(() => {
256
- const url = roster.getLocalUrl('example.com');
257
- console.log(`Server available at: ${url}`);
258
- });
237
+ // Local development
238
+ const localRoster = new Roster({ local: true });
239
+ localRoster.register('example.com', handler);
240
+ await localRoster.start();
241
+ console.log(localRoster.getUrl('example.com'));
242
+ // → http://localhost:9465
243
+
244
+ // Production
245
+ const prodRoster = new Roster({ local: false });
246
+ prodRoster.register('example.com', handler);
247
+ await prodRoster.start();
248
+ console.log(prodRoster.getUrl('example.com'));
249
+ // → https://example.com
250
+
251
+ // Production with custom port
252
+ const customRoster = new Roster({ local: false, port: 8443 });
253
+ customRoster.register('api.example.com', handler);
254
+ await customRoster.start();
255
+ console.log(customRoster.getUrl('api.example.com'));
256
+ // → https://api.example.com:8443
259
257
  ```
260
258
 
261
259
  ## 🧂 A Touch of Magic
@@ -7,15 +7,7 @@ const roster = new Roster({
7
7
  maxLocalPort: 5100 // Custom maximum port
8
8
  });
9
9
 
10
- console.log('\n📍 Static URL Prediction with custom range (5000-5100):');
11
- console.log('example.com →', Roster.getLocalUrl('example.com', {
12
- minLocalPort: 5000,
13
- maxLocalPort: 5100
14
- }));
15
- console.log('api.example.com →', Roster.getLocalUrl('api.example.com', {
16
- minLocalPort: 5000,
17
- maxLocalPort: 5100
18
- }));
10
+ console.log('\n🔧 Creating server with custom port range (5000-5100)...\n');
19
11
 
20
12
  roster.register('example.com', (httpsServer) => {
21
13
  return (req, res) => {
@@ -32,9 +24,9 @@ roster.register('api.example.com', (httpsServer) => {
32
24
  });
33
25
 
34
26
  roster.start().then(() => {
35
- console.log('\n🚀 Server Started with custom port range:');
36
- console.log('example.com →', roster.getLocalUrl('example.com'));
37
- console.log('api.example.com →', roster.getLocalUrl('api.example.com'));
27
+ console.log('🚀 Server Started with custom port range:');
28
+ console.log('example.com →', roster.getUrl('example.com'));
29
+ console.log('api.example.com →', roster.getUrl('api.example.com'));
38
30
 
39
31
  console.log('\n✅ Both domains running in custom port range (5000-5100)!');
40
32
  });
@@ -0,0 +1,55 @@
1
+ const Roster = require('../index.js');
2
+
3
+ // Example 1: Local mode
4
+ console.log('\n📍 EXAMPLE 1: Local Development Mode\n');
5
+ const localRoster = new Roster({ local: true });
6
+
7
+ localRoster.register('example.com', (httpsServer) => {
8
+ return (req, res) => {
9
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
10
+ res.end('Hello from local!');
11
+ };
12
+ });
13
+
14
+ localRoster.start().then(() => {
15
+ console.log('Local URL:', localRoster.getUrl('example.com'));
16
+ console.log('→ Returns: http://localhost:{port}\n');
17
+ });
18
+
19
+ // Example 2: Production mode (simulated, without actually starting)
20
+ console.log('📍 EXAMPLE 2: Production Mode (simulated)\n');
21
+ const prodRoster = new Roster({
22
+ local: false,
23
+ email: 'admin@example.com'
24
+ });
25
+
26
+ prodRoster.register('example.com', (httpsServer) => {
27
+ return (req, res) => {
28
+ res.writeHead(200);
29
+ res.end('Hello from production!');
30
+ };
31
+ });
32
+
33
+ // Don't actually start (would need real SSL), just show what URL would be
34
+ console.log('Production URL (without starting):', 'https://example.com');
35
+ console.log('→ Would return: https://example.com\n');
36
+
37
+ // Example 3: Production with custom port
38
+ console.log('📍 EXAMPLE 3: Production with Custom Port (simulated)\n');
39
+ const customPortRoster = new Roster({
40
+ local: false,
41
+ port: 8443,
42
+ email: 'admin@example.com'
43
+ });
44
+
45
+ customPortRoster.register('api.example.com', (httpsServer) => {
46
+ return (req, res) => {
47
+ res.writeHead(200);
48
+ res.end('API');
49
+ };
50
+ });
51
+
52
+ console.log('Custom port URL (without starting):', 'https://api.example.com:8443');
53
+ console.log('→ Would return: https://api.example.com:8443\n');
54
+
55
+ console.log('✅ getUrl() adapts to the environment automatically!');
@@ -1,12 +1,8 @@
1
1
  const Roster = require('../index.js');
2
2
 
3
- // Example 1: Get URL before creating instance (static method)
4
- console.log('\n📍 Static URL Prediction (before server starts):');
5
- console.log('example.com →', Roster.getLocalUrl('example.com'));
6
- console.log('api.example.com →', Roster.getLocalUrl('api.example.com'));
7
- console.log('test.example.com →', Roster.getLocalUrl('test.example.com'));
3
+ // Example: Get URL after registration (adapts to environment)
4
+ console.log('\n🔧 Creating local development server...\n');
8
5
 
9
- // Example 2: Get URL after registration (instance method)
10
6
  const roster = new Roster({ local: true });
11
7
 
12
8
  roster.register('example.com', (httpsServer) => {
@@ -24,17 +20,17 @@ roster.register('api.example.com', (httpsServer) => {
24
20
  });
25
21
 
26
22
  roster.start().then(() => {
27
- console.log('\n🚀 Server Started - Actual URLs:');
28
- console.log('example.com →', roster.getLocalUrl('example.com'));
29
- console.log('api.example.com →', roster.getLocalUrl('api.example.com'));
23
+ console.log('🚀 Server Started - URLs (based on environment):');
24
+ console.log('example.com →', roster.getUrl('example.com'));
25
+ console.log('api.example.com →', roster.getUrl('api.example.com'));
30
26
 
31
27
  // Test with www prefix (should return same URL)
32
28
  console.log('\n🔄 Testing www prefix handling:');
33
- console.log('www.example.com →', roster.getLocalUrl('www.example.com'));
29
+ console.log('www.example.com →', roster.getUrl('www.example.com'));
34
30
 
35
31
  // Test non-existent domain
36
32
  console.log('\n❌ Testing non-existent domain:');
37
- console.log('nonexistent.com →', roster.getLocalUrl('nonexistent.com') || 'null (domain not registered)');
33
+ console.log('nonexistent.com →', roster.getUrl('nonexistent.com') || 'null (domain not registered)');
38
34
 
39
35
  console.log('\n✅ All domains running!');
40
36
  });
package/demo/socketio.js CHANGED
@@ -27,11 +27,7 @@ roster.register('example.com', (httpsServer) => {
27
27
  });
28
28
 
29
29
  roster.start().then(() => {
30
- // Get local URL for registered domain (requires instance)
31
- const url = roster.getLocalUrl('example.com');
30
+ // Get URL for registered domain (adapts to environment)
31
+ const url = roster.getUrl('example.com');
32
32
  console.log(`✅ Socket.IO server available at: ${url}`);
33
-
34
- // Get local URL without instance (static method - predictable port)
35
- const staticUrl = Roster.getLocalUrl('example.com');
36
- console.log(`ℹ️ Static prediction: ${staticUrl}`);
37
33
  });
@@ -0,0 +1,64 @@
1
+ const Roster = require('../index.js');
2
+
3
+ console.log('\n🧪 Testing getUrl() method in different scenarios\n');
4
+
5
+ // Test 1: Local mode with default port
6
+ console.log('TEST 1: Local mode (default port)');
7
+ const local1 = new Roster({ local: true });
8
+ local1.register('example.com', () => (req, res) => res.end('OK'));
9
+ local1.start().then(() => {
10
+ const url = local1.getUrl('example.com');
11
+ console.log(`✓ example.com → ${url}`);
12
+ console.assert(url.startsWith('http://localhost:'), 'Should be localhost HTTP');
13
+ });
14
+
15
+ // Test 2: Local mode with custom port range
16
+ console.log('\nTEST 2: Local mode (custom port range)');
17
+ const local2 = new Roster({ local: true, minLocalPort: 6000, maxLocalPort: 6100 });
18
+ local2.register('test.com', () => (req, res) => res.end('OK'));
19
+ local2.start().then(() => {
20
+ const url = local2.getUrl('test.com');
21
+ console.log(`✓ test.com → ${url}`);
22
+ const port = parseInt(url.split(':')[2]);
23
+ console.assert(port >= 6000 && port <= 6100, 'Port should be in custom range');
24
+ });
25
+
26
+ // Test 3: Production mode (default HTTPS port)
27
+ console.log('\nTEST 3: Production mode (default HTTPS)');
28
+ const prod1 = new Roster({ local: false, email: 'admin@example.com' });
29
+ prod1.register('example.com', () => (req, res) => res.end('OK'));
30
+ const prodUrl1 = prod1.getUrl('example.com');
31
+ console.log(`✓ example.com → ${prodUrl1}`);
32
+ console.assert(prodUrl1 === 'https://example.com', 'Should be HTTPS without port');
33
+
34
+ // Test 4: Production mode (custom port)
35
+ console.log('\nTEST 4: Production mode (custom port)');
36
+ const prod2 = new Roster({ local: false, port: 8443, email: 'admin@example.com' });
37
+ prod2.register('api.example.com', () => (req, res) => res.end('OK'));
38
+ const prodUrl2 = prod2.getUrl('api.example.com');
39
+ console.log(`✓ api.example.com → ${prodUrl2}`);
40
+ console.assert(prodUrl2 === 'https://api.example.com:8443', 'Should include custom port');
41
+
42
+ // Test 5: www prefix handling
43
+ console.log('\nTEST 5: www prefix handling');
44
+ const local3 = new Roster({ local: true });
45
+ local3.register('example.com', () => (req, res) => res.end('OK'));
46
+ local3.start().then(() => {
47
+ const url1 = local3.getUrl('example.com');
48
+ const url2 = local3.getUrl('www.example.com');
49
+ console.log(`✓ example.com → ${url1}`);
50
+ console.log(`✓ www.example.com → ${url2}`);
51
+ console.assert(url1 === url2, 'www should return same URL');
52
+ });
53
+
54
+ // Test 6: Non-existent domain
55
+ console.log('\nTEST 6: Non-existent domain');
56
+ const local4 = new Roster({ local: true });
57
+ local4.register('example.com', () => (req, res) => res.end('OK'));
58
+ local4.start().then(() => {
59
+ const url = local4.getUrl('nonexistent.com');
60
+ console.log(`✓ nonexistent.com → ${url}`);
61
+ console.assert(url === null, 'Should return null for unregistered domain');
62
+
63
+ console.log('\n✅ All tests passed!\n');
64
+ });
package/index.js CHANGED
@@ -367,41 +367,32 @@ class Roster {
367
367
  }
368
368
 
369
369
  /**
370
- * Get the local URL for a domain when running in local mode
371
- * @param {string} domain - The domain name (e.g., 'example.com')
372
- * @param {Object} options - Optional configuration
373
- * @param {number} options.minLocalPort - Minimum port range (default: 4000)
374
- * @param {number} options.maxLocalPort - Maximum port range (default: 9999)
375
- * @returns {string} The local URL (e.g., 'http://localhost:4321')
376
- */
377
- static getLocalUrl(domain, options = {}) {
378
- const minPort = options.minLocalPort || 4000;
379
- const maxPort = options.maxLocalPort || 9999;
380
-
381
- // Remove www prefix if present
382
- const cleanDomain = domain.startsWith('www.') ? domain.slice(4) : domain;
383
-
384
- // Calculate deterministic port
385
- const port = domainToPort(cleanDomain, minPort, maxPort);
386
-
387
- return `http://localhost:${port}`;
388
- }
389
-
390
- /**
391
- * Get the local URL for a domain that was registered on this instance
370
+ * Get the URL for a domain based on the current environment
392
371
  * @param {string} domain - The domain name
393
- * @returns {string|null} The local URL if found, null otherwise
372
+ * @returns {string|null} The URL if domain is registered, null otherwise
394
373
  */
395
- getLocalUrl(domain) {
374
+ getUrl(domain) {
396
375
  // Remove www prefix if present
397
376
  const cleanDomain = domain.startsWith('www.') ? domain.slice(4) : domain;
398
377
 
399
- // Check if domain has a port assigned
400
- if (this.domainPorts && this.domainPorts[cleanDomain]) {
401
- return `http://localhost:${this.domainPorts[cleanDomain]}`;
378
+ // Check if domain is registered
379
+ const isRegistered = this.sites[cleanDomain] || this.sites[`www.${cleanDomain}`];
380
+ if (!isRegistered) {
381
+ return null;
402
382
  }
403
383
 
404
- return null;
384
+ // Return URL based on environment
385
+ if (this.local) {
386
+ // Local mode: return localhost URL with assigned port
387
+ if (this.domainPorts && this.domainPorts[cleanDomain]) {
388
+ return `http://localhost:${this.domainPorts[cleanDomain]}`;
389
+ }
390
+ return null;
391
+ } else {
392
+ // Production mode: return HTTPS URL
393
+ const port = this.defaultPort === 443 ? '' : `:${this.defaultPort}`;
394
+ return `https://${cleanDomain}${port}`;
395
+ }
405
396
  }
406
397
 
407
398
  createVirtualServer(domain) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roster-server",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "description": "👾 RosterServer - A domain host router to host multiple HTTPS.",
5
5
  "main": "index.js",
6
6
  "scripts": {