UNPKG

iop

Version:
101 lines 4.34 kB
"use strict"; // 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