iop
Version:
Ship Docker Anywhere
168 lines • 8.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IopSecretsSchema = exports.IopConfigSchema = exports.ServiceEntrySchema = exports.ServiceEntryWithoutNameSchema = exports.ProxyConfigSchema = exports.HealthCheckSchema = void 0;
const zod_1 = require("zod");
// Zod schema for HealthCheck
exports.HealthCheckSchema = zod_1.z.object({
path: zod_1.z.string().optional().default("/up"), // Health check endpoint path
});
// Zod schema for Proxy Configuration (for HTTP services)
exports.ProxyConfigSchema = zod_1.z.object({
hosts: zod_1.z.array(zod_1.z.string()).optional(),
app_port: zod_1.z
.number()
.describe("Port the application container is exposed on, e.g. 3000. The proxy will forward traffic to this port.")
.optional(),
ssl: zod_1.z
.boolean()
.describe("Enable automatic HTTPS via Let's Encrypt. Requires 'hosts' to be set and DNS to point to the server.")
.optional()
.default(true),
ssl_redirect: zod_1.z
.boolean()
.describe("Redirect HTTP to HTTPS if SSL is enabled. Defaults to true.")
.optional(),
forward_headers: zod_1.z
.boolean()
.describe("Forward X-Forwarded-For/Proto headers. Default depends on SSL status (true if SSL disabled, false if SSL enabled, unless overridden).")
.optional(),
response_timeout: zod_1.z
.string()
.describe("Request timeout, e.g., '30s', '1m'. Default is '30s'.")
.optional(),
});
// Zod schema for unified Service Entry without name (used in record format)
exports.ServiceEntryWithoutNameSchema = zod_1.z.object({
image: zod_1.z.string().optional(), // e.g., "postgres:15" or "my-app/web" - optional when build is specified
server: zod_1.z.string().describe("Hostname or IP address of the target server"),
replicas: zod_1.z
.number()
.min(1)
.default(1)
.describe("Number of replicas to deploy for this service. Defaults to 1."),
build: zod_1.z
.object({
context: zod_1.z.string(),
dockerfile: zod_1.z.string().default("Dockerfile"),
args: zod_1.z.array(zod_1.z.string()).optional().describe("Build arguments passed to Docker build command. List of environment variable names to pass as build args. These variables must be defined in the environment section."),
target: zod_1.z.string().optional(), // For multi-stage builds
platform: zod_1.z.string().optional(), // e.g., linux/amd64
})
.optional()
.describe("Build configuration. When specified, the service is built locally and transferred via docker save/load instead of using registries."),
ports: zod_1.z.array(zod_1.z.string()).optional(), // e.g., ["3000", "5432:5432"]
volumes: zod_1.z.array(zod_1.z.string()).optional(), // e.g., ["mydata:/data/db"]
environment: zod_1.z
.object({
plain: zod_1.z.array(zod_1.z.string()).optional(), // Array format for environment variables like ["KEY=VALUE"]
secret: zod_1.z.array(zod_1.z.string()).optional(),
})
.optional(),
registry: zod_1.z // Optional registry for pre-built images
.object({
url: zod_1.z.string().optional(),
username: zod_1.z.string(),
password_secret: zod_1.z.string(), // Secret key for the password
})
.optional()
.describe("Registry configuration for pre-built images. Not used for services with 'build' configuration."),
command: zod_1.z.string().optional().describe("Override the default command for the container"),
health_check: exports.HealthCheckSchema.optional(),
proxy: exports.ProxyConfigSchema.optional(),
}).refine((data) => {
// Ensure either image or build is provided, but not both
const hasImage = !!data.image;
const hasBuild = !!data.build;
return hasImage !== hasBuild; // XOR: exactly one must be true
}, {
message: "Service must have either 'image' or 'build', but not both",
path: ["image"],
});
// Zod schema for ServiceEntry (includes name - for array format if needed)
exports.ServiceEntrySchema = zod_1.z.object({
name: zod_1.z.string(),
image: zod_1.z.string().optional(), // e.g., "postgres:15" or "my-app/web" - optional when build is specified
server: zod_1.z.string().describe("Hostname or IP address of the target server"),
replicas: zod_1.z
.number()
.min(1)
.default(1)
.describe("Number of replicas to deploy for this service. Defaults to 1."),
build: zod_1.z
.object({
context: zod_1.z.string(),
dockerfile: zod_1.z.string().default("Dockerfile"),
args: zod_1.z.array(zod_1.z.string()).optional().describe("Build arguments passed to Docker build command. List of environment variable names to pass as build args. These variables must be defined in the environment section."),
target: zod_1.z.string().optional(), // For multi-stage builds
platform: zod_1.z.string().optional(), // e.g., linux/amd64
})
.optional()
.describe("Build configuration. When specified, the service is built locally and transferred via docker save/load instead of using registries."),
ports: zod_1.z.array(zod_1.z.string()).optional(), // e.g., ["3000", "5432:5432"]
volumes: zod_1.z.array(zod_1.z.string()).optional(), // e.g., ["mydata:/data/db"]
environment: zod_1.z
.object({
plain: zod_1.z.array(zod_1.z.string()).optional(), // Array format for environment variables like ["KEY=VALUE"]
secret: zod_1.z.array(zod_1.z.string()).optional(),
})
.optional(),
registry: zod_1.z // Optional registry for pre-built images
.object({
url: zod_1.z.string().optional(),
username: zod_1.z.string(),
password_secret: zod_1.z.string(), // Secret key for the password
})
.optional()
.describe("Registry configuration for pre-built images. Not used for services with 'build' configuration."),
command: zod_1.z.string().optional().describe("Override the default command for the container"),
health_check: exports.HealthCheckSchema.optional(),
proxy: exports.ProxyConfigSchema.optional(),
}).refine((data) => {
// Ensure either image or build is provided, but not both
const hasImage = !!data.image;
const hasBuild = !!data.build;
return hasImage !== hasBuild; // XOR: exactly one must be true
}, {
message: "Service must have either 'image' or 'build', but not both",
path: ["image"],
});
// Zod schema for IopConfig - unified services model
exports.IopConfigSchema = zod_1.z.object({
name: zod_1.z.string().min(1, "Project name is required"), // Used for network naming etc.
services: zod_1.z
.union([
zod_1.z.record(exports.ServiceEntryWithoutNameSchema), // Object format where keys are service names
zod_1.z.array(exports.ServiceEntrySchema), // Array format with explicit name field
])
.optional(),
docker: zod_1.z
.object({
registry: zod_1.z
.string()
.optional()
.describe("Global Docker registry (optional - only needed for services using private registries)"), // Global Docker registry
username: zod_1.z.string().optional().describe("Global registry username"), // Global username
// Global password_secret should be defined in IopSecrets and referenced
// e.g. global_docker_password_secret: "DOCKER_REGISTRY_PASSWORD"
})
.optional()
.describe("Global Docker registry configuration. Optional - only needed for services using private registries. Apps with build configuration use docker save/load transfer."),
ssh: zod_1.z
.object({
username: zod_1.z.string().optional(), // Default SSH username
port: zod_1.z.number().optional(), // Default SSH port
key_file: zod_1.z.string().optional(), // Path to SSH private key file
})
.optional(),
proxy: zod_1.z
.object({
image: zod_1.z
.string()
.describe("Custom Docker image for the iop proxy")
.optional(),
})
.optional(),
});
// Zod schema for IopSecrets (simple key-value)
exports.IopSecretsSchema = zod_1.z.record(zod_1.z.string());
//# sourceMappingURL=types.js.map