UNPKG

compd

Version:

Run a command under a docker-compose setup

130 lines (129 loc) 3.65 kB
"use strict"; /** * The specification for compose files declares the follow syntaxes. * * Short syntax of ports as: * - "3000" * - "3000-3005" * - "8000:8000" * - "9090-9091:8080-8081" * - "49100:22" * - "127.0.0.1:8001:8001" * - "127.0.0.1:5000-5010:5000-5010" * - "6060:6060/udp" * * Long syntax: * - target: 80 * published: 8080 * protocol: tcp * mode: host */ Object.defineProperty(exports, "__esModule", { value: true }); exports.parsePorts = exports.parsePort = exports.InvalidPortSpecificationError = exports.PortRangeMismatchError = void 0; class PortRangeMismatchError extends Error { } exports.PortRangeMismatchError = PortRangeMismatchError; class InvalidPortSpecificationError extends Error { } exports.InvalidPortSpecificationError = InvalidPortSpecificationError; /** * Parses: * - "3000" * - "3000-3005" * - "127.0.0.1:3000" * - "127.0.0.1:3000-3005" */ function parseHostOrContainerPorts(value) { if (value.includes(':')) { const [hostIP, port] = value.split(':'); return parseHostOrContainerPorts(port) .map(({ port }) => ({ hostIP, port })); } else { if (value.includes('-')) { const [lower, upper] = value.split('-'); return makePortRange(parseInt(lower, 10), parseInt(upper, 10)) .map(port => ({ port })); } else { return [{ port: parseInt(value, 10) },]; } } } /** * Turns [3000, 3002] into [3000, 3001, 3002] */ function makePortRange(lower, uppper) { const ret = []; for (let i = lower; i <= uppper; ++i) ret.push(i); return ret; } /** * Parses: * - "3000" * - "3000/udp" * - "3000-3005" * - "3000-3005/tcp" */ function parseContainerPorts(value) { const m = value.match(/^([^/]+)(\/([^/]+))?$/); if (!m) throw new InvalidPortSpecificationError(`Invalid port definition: ${value}`); const [, port, , protocol = 'tcp'] = [...m]; const proto = protocol; return parseHostOrContainerPorts(port) .map(({ hostIP, port }) => ({ hostIP, container: port, proto, })); } // Splits a string on the *last* colon function splitHostContainer(value) { const m = value.match(/^(.+):([^:]+)$/); if (!m) throw new InvalidPortSpecificationError(`Invalid port definition: ${value}`); return [m[1], m[2]]; } function parsePortShort(value) { value = `${value}`; if (value.includes(':')) { const [host, container] = splitHostContainer(value); const portsHost = parseHostOrContainerPorts(host); const portsContainer = parseContainerPorts(container); if (portsHost.length !== portsContainer.length) throw new PortRangeMismatchError(`Port range of different size: ${value}`); return portsContainer .map(({ container, proto }, index) => ({ hostIP: portsHost[index].hostIP, host: portsHost[index].port, container, proto, })); } else { return parseContainerPorts(value); } } function parsePortLong(value) { return [ { host: value.published, container: value.target, proto: value.protocol || 'tcp', mode: value.mode || 'host', }, ]; } function parsePort(value) { return (typeof value === 'string' || typeof value === 'number') ? parsePortShort(value) : parsePortLong(value); } exports.parsePort = parsePort; function parsePorts(values) { return [] .concat(...values.map(value => parsePort(value))); } exports.parsePorts = parsePorts;