iop
Version:
Ship Docker Anywhere
101 lines • 4.34 kB
JavaScript
;
// General utilities will go here
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProjectNetworkName = getProjectNetworkName;
exports.sanitizeFolderName = sanitizeFolderName;
exports.processVolumes = processVolumes;
exports.ensureProjectDirectories = ensureProjectDirectories;
__exportStar(require("./release"), exports);
// Add other utils exports here as they are created
function getProjectNetworkName(projectName) {
if (!projectName || projectName.trim() === "") {
throw new Error("Project name cannot be empty when generating network name.");
}
// Sanitize project name to be DNS-friendly for network naming
const sanitizedProjectName = projectName
.toLowerCase()
.replace(/[^a-z0-9-]/g, "-");
return `${sanitizedProjectName}-network`;
}
__exportStar(require("./port-checker"), exports);
__exportStar(require("./config-validator"), exports);
/**
* Sanitizes a string to be safe for use as a folder name
*/
function sanitizeFolderName(name) {
return name
.replace(/[^a-zA-Z0-9\-_]/g, "-") // Replace invalid chars with hyphens
.replace(/^-+|-+$/g, "") // Remove leading/trailing hyphens
.replace(/-+/g, "-") // Collapse multiple hyphens
.toLowerCase();
}
/**
* Processes volume mappings to ensure project isolation and proper path resolution
* @param volumes Array of volume mappings (e.g., ["mydata:/data", "./local:/app"])
* @param projectName Project name for prefixing
* @returns Processed volume mappings with project prefixes and resolved paths
*/
function processVolumes(volumes, projectName) {
if (!volumes || volumes.length === 0) {
return [];
}
const sanitizedProjectName = sanitizeFolderName(projectName);
return volumes.map((volume) => {
const [source, destination, ...rest] = volume.split(":");
if (!destination) {
throw new Error(`Invalid volume mapping: "${volume}". Expected format: "source:destination" or "source:destination:options"`);
}
let processedSource;
if (source.startsWith("./") ||
source.startsWith("../") ||
!source.startsWith("/")) {
// Relative path or local directory - convert to project-specific bind mount
const relativePath = source.startsWith("./") ? source.slice(2) : source;
processedSource = `~/.iop/projects/${sanitizedProjectName}/${relativePath}`;
}
else if (source.startsWith("/")) {
// Absolute path - use as-is (but warn user)
processedSource = source;
}
else {
// Named volume - prefix with project name
const sanitizedVolumeName = sanitizeFolderName(source);
processedSource = `${sanitizedProjectName}-${sanitizedVolumeName}`;
}
// Reconstruct the volume mapping
const processedVolume = rest.length > 0
? `${processedSource}:${destination}:${rest.join(":")}`
: `${processedSource}:${destination}`;
return processedVolume;
});
}
/**
* Creates necessary project directories on the remote server
* @param sshClient SSH client connection
* @param projectName Project name
*/
async function ensureProjectDirectories(sshClient, projectName) {
const sanitizedProjectName = sanitizeFolderName(projectName);
const projectDir = `~/.iop/projects/${sanitizedProjectName}`;
try {
await sshClient.exec(`mkdir -p "${projectDir}"`);
}
catch (error) {
throw new Error(`Failed to create project directory ${projectDir}: ${error}`);
}
}
//# sourceMappingURL=index.js.map