collapse consecutive port mappings into ranges in container list (#821)
This commit is contained in:
2 files changed
+64
-25
No files matched your search
@@ -0,0 +1,61 @@
|
||||
export interface PortMapping {
|
||||
publicPort: number;
|
||||
privatePort: number;
|
||||
display: string;
|
||||
isRange?: boolean;
|
||||
}
|
||||
|
||||
interface PortInfo {
|
||||
PublicPort: number;
|
||||
PrivatePort: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format Docker port mappings, collapsing consecutive ranges.
|
||||
* e.g. 8080:8080, 8081:8081, 8082:8082 → 8080-8082:8080-8082
|
||||
*/
|
||||
export function formatPorts(ports: PortInfo[] | undefined | null): PortMapping[] {
|
||||
if (!ports || ports.length === 0) return [];
|
||||
const seen = new Set<string>();
|
||||
const individual = ports
|
||||
.filter(p => p.PublicPort)
|
||||
.map(p => ({
|
||||
publicPort: p.PublicPort,
|
||||
privatePort: p.PrivatePort,
|
||||
display: `${p.PublicPort}:${p.PrivatePort}`
|
||||
}))
|
||||
.filter(p => {
|
||||
const key = p.display;
|
||||
if (seen.has(key)) return false;
|
||||
seen.add(key);
|
||||
return true;
|
||||
})
|
||||
.sort((a, b) => a.publicPort - b.publicPort);
|
||||
|
||||
// Collapse consecutive port ranges
|
||||
if (individual.length <= 1) return individual;
|
||||
|
||||
const result: PortMapping[] = [];
|
||||
let rangeStart = individual[0];
|
||||
let rangeEnd = individual[0];
|
||||
|
||||
for (let i = 1; i < individual.length; i++) {
|
||||
const curr = individual[i];
|
||||
const offset = curr.publicPort - rangeStart.publicPort;
|
||||
const expectedPrivate = rangeStart.privatePort + offset;
|
||||
if (curr.publicPort === rangeEnd.publicPort + 1 && curr.privatePort === expectedPrivate) {
|
||||
rangeEnd = curr;
|
||||
} else {
|
||||
result.push(rangeStart.publicPort === rangeEnd.publicPort
|
||||
? rangeStart
|
||||
: { publicPort: rangeStart.publicPort, privatePort: rangeStart.privatePort, display: `${rangeStart.publicPort}-${rangeEnd.publicPort}:${rangeStart.privatePort}-${rangeEnd.privatePort}`, isRange: true });
|
||||
rangeStart = curr;
|
||||
rangeEnd = curr;
|
||||
}
|
||||
}
|
||||
result.push(rangeStart.publicPort === rangeEnd.publicPort
|
||||
? rangeStart
|
||||
: { publicPort: rangeStart.publicPort, privatePort: rangeStart.privatePort, display: `${rangeStart.publicPort}-${rangeEnd.publicPort}:${rangeStart.privatePort}-${rangeEnd.privatePort}`, isRange: true });
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user