@gkucmierz/dport 1.0.0
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/.github/workflows/npm-publish.yml +36 -0
- package/README.md +23 -0
- package/bin/dport.js +79 -0
- package/index.js +15 -0
- package/package.json +29 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: npm-publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'self-hosted' }}
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: '20.x'
|
|
17
|
+
registry-url: 'https://registry.npmjs.org'
|
|
18
|
+
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: npm ci
|
|
21
|
+
|
|
22
|
+
- name: Publish to NPM Registry
|
|
23
|
+
run: npm publish --access public
|
|
24
|
+
env:
|
|
25
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
|
26
|
+
|
|
27
|
+
- name: Setup Gitea Registry
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: '20.x'
|
|
31
|
+
registry-url: 'https://gitea.7u.pl/api/packages/gkucmierz/npm/'
|
|
32
|
+
|
|
33
|
+
- name: Publish to Gitea Registry
|
|
34
|
+
run: npm publish
|
|
35
|
+
env:
|
|
36
|
+
NODE_AUTH_TOKEN: ${{ secrets.LOCAL_PACKAGE_REGISTRY }}
|
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @gkucmierz/dport
|
|
2
|
+
|
|
3
|
+
Deterministic local port generator based on your project name.
|
|
4
|
+
Replaces chaotic local development port assignments (`localhost:3000`, `8080`) with stable, predictable ports calculated mathematically. Maximize local PWA and Service Worker isolation effortlessly.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @gkucmierz/dport
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
Calculate deterministic port from `package.json` in the current directory:
|
|
13
|
+
```bash
|
|
14
|
+
dport calc
|
|
15
|
+
```
|
|
16
|
+
Pass a custom name directly:
|
|
17
|
+
```bash
|
|
18
|
+
dport calc talk-app-backend
|
|
19
|
+
```
|
|
20
|
+
Automatically fix all familiar dev ports in your `scripts` tag inside `package.json`:
|
|
21
|
+
```bash
|
|
22
|
+
dport fix
|
|
23
|
+
```
|
package/bin/dport.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { getDeterministicPort } from '../index.js';
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const command = args.find(a => !a.startsWith('-')) || 'calc';
|
|
9
|
+
const hasFixFlag = args.includes('--fix');
|
|
10
|
+
|
|
11
|
+
if (command === 'help') {
|
|
12
|
+
console.log(`
|
|
13
|
+
Usage: dport <command> [options]
|
|
14
|
+
|
|
15
|
+
Commands:
|
|
16
|
+
calc [name] Calculate deterministic port. (Default if no command provided)
|
|
17
|
+
fix [name] Alias for 'calc --fix'.
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--fix Find common development ports in package.json scripts
|
|
21
|
+
and auto-replace them with the deterministic port.
|
|
22
|
+
`);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (command === 'calc' || command === 'show' || command === 'fix') {
|
|
27
|
+
let name = args.find(a => !a.startsWith('-') && a !== command);
|
|
28
|
+
let pkgPath, pkg;
|
|
29
|
+
|
|
30
|
+
if (!name || hasFixFlag || command === 'fix') {
|
|
31
|
+
try {
|
|
32
|
+
pkgPath = path.resolve(process.cwd(), 'package.json');
|
|
33
|
+
const pkgContext = fs.readFileSync(pkgPath, 'utf8');
|
|
34
|
+
pkg = JSON.parse(pkgContext);
|
|
35
|
+
if (!name) name = pkg.name;
|
|
36
|
+
} catch(e) {
|
|
37
|
+
console.error('Error: Could not read package.json in current directory.');
|
|
38
|
+
if (hasFixFlag || command === 'fix') process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!name) {
|
|
43
|
+
console.error('Error: No project name could be determined.');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const port = getDeterministicPort(name);
|
|
48
|
+
console.log(`\n📦 Project: ${name}`);
|
|
49
|
+
console.log(`🎯 Deterministic Port: ${port}\n`);
|
|
50
|
+
|
|
51
|
+
if ((hasFixFlag || command === 'fix') && pkg && pkg.scripts) {
|
|
52
|
+
let modified = false;
|
|
53
|
+
const commonPorts = ['3000', '8080', '5173', '8000', '4000', '3001', '8081', '4200'];
|
|
54
|
+
|
|
55
|
+
for (const [key, script] of Object.entries(pkg.scripts)) {
|
|
56
|
+
let newScript = script;
|
|
57
|
+
commonPorts.forEach(cp => {
|
|
58
|
+
newScript = newScript.replace(new RegExp(`\\b${cp}\\b`, 'g'), port.toString());
|
|
59
|
+
});
|
|
60
|
+
if (newScript !== script) {
|
|
61
|
+
pkg.scripts[key] = newScript;
|
|
62
|
+
modified = true;
|
|
63
|
+
console.log(`✅ Updated script '${key}': ${newScript}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (modified) {
|
|
68
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
69
|
+
console.log(`\n💾 Successfully saved package.json with new port ${port}!`);
|
|
70
|
+
} else {
|
|
71
|
+
console.log(`ℹ️ No common ports (${commonPorts.join(', ')}) found to replace in package.json scripts.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.error(`Unknown command: \${command}`);
|
|
79
|
+
process.exit(1);
|
package/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
export function getDeterministicPort(name, options = {}) {
|
|
4
|
+
const maxPorts = 65535;
|
|
5
|
+
const systemPorts = 1024;
|
|
6
|
+
const availablePorts = maxPorts - systemPorts;
|
|
7
|
+
|
|
8
|
+
const hash = crypto.createHash('sha256').update(name).digest('hex');
|
|
9
|
+
const hashInt = BigInt('0x' + hash);
|
|
10
|
+
const port = Number((hashInt % BigInt(availablePorts)) + BigInt(systemPorts));
|
|
11
|
+
|
|
12
|
+
const offset = options.offset || 0;
|
|
13
|
+
|
|
14
|
+
return port + offset;
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gkucmierz/dport",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Deterministic local port generator based on project name",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"dport": "./bin/dport.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"port",
|
|
15
|
+
"deterministic",
|
|
16
|
+
"dev",
|
|
17
|
+
"cli"
|
|
18
|
+
],
|
|
19
|
+
"author": "gkucmierz",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://gitea.7u.pl/gkucmierz/dports.git"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|