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 +34 -36
- package/demo/custom-port-range.js +4 -12
- package/demo/environment-aware-url.js +55 -0
- package/demo/local-url-example.js +7 -11
- package/demo/socketio.js +2 -6
- package/demo/test-geturl.js +64 -0
- package/index.js +19 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -205,27 +205,11 @@ const roster = new Roster({
|
|
|
205
205
|
});
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
-
### Getting
|
|
208
|
+
### Getting URLs
|
|
209
209
|
|
|
210
|
-
RosterServer provides
|
|
210
|
+
RosterServer provides a method to get the URL for a domain that adapts automatically to your environment:
|
|
211
211
|
|
|
212
|
-
**
|
|
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
|
|
237
|
-
const url = roster.
|
|
238
|
-
console.log(url);
|
|
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
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
|
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('
|
|
36
|
-
console.log('example.com →', roster.
|
|
37
|
-
console.log('api.example.com →', roster.
|
|
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
|
|
4
|
-
console.log('\n
|
|
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('
|
|
28
|
-
console.log('example.com →', roster.
|
|
29
|
-
console.log('api.example.com →', roster.
|
|
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.
|
|
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.
|
|
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
|
|
31
|
-
const url = roster.
|
|
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
|
|
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
|
|
372
|
+
* @returns {string|null} The URL if domain is registered, null otherwise
|
|
394
373
|
*/
|
|
395
|
-
|
|
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
|
|
400
|
-
|
|
401
|
-
|
|
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
|
-
|
|
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) {
|