tilt-ts-core
Version:
A TypeScript implementation of a Tilt-like development tool for Kubernetes live development workflows
369 lines (355 loc) • 11.1 kB
TypeScript
type LiveSync = {
type: "sync";
src: string;
dest: string;
include?: string[];
exclude?: string[];
};
type LiveRun = {
type: "run";
cmd: string[];
dir?: string;
env?: Record<string, string>;
whenFilesChanged?: string[];
};
type LiveStep = LiveSync | LiveRun;
type ResourceSelector = {
kind: "Deployment" | "StatefulSet" | "DaemonSet";
name: string;
namespace?: string;
container?: string;
labelSelector?: string;
};
type DockerBuildOpts = {
dockerfile?: string;
args?: Record<string, string>;
target?: string;
tags?: string[];
live_update?: LiveStep[];
registry?: {
/** URL used for pushing images from the host (e.g., "localhost:36269") */
hostUrl?: string;
/** URL used by the cluster to pull images (e.g., "k3d-registry:5000") */
clusterUrl?: string;
};
};
type DaggerBuildOpts = {
context: string;
dockerfile?: string;
args?: Record<string, string>;
target?: string;
live_update?: LiveStep[];
registry?: {
/** URL used for pushing images from the host (e.g., "localhost:36269") */
hostUrl?: string;
/** URL used by the cluster to pull images (e.g., "k3d-registry:5000") */
clusterUrl?: string;
};
pipeline?: (client: any) => any;
};
type BuiltImage = {
logicalName: string;
/** Image reference used for pushing from host (e.g., "localhost:36269/dev/my-app:dev-123") */
imageRef: string;
/** Image reference used by cluster (e.g., "k3d-registry:5000/dev/my-app:dev-123") */
clusterImageName: string;
digest?: string;
live_update?: LiveStep[];
};
type ApplyInput = {
type: "yamlText";
text: string;
} | {
type: "yamlFile";
path: string;
} | {
type: "yamlFiles";
paths: string[];
};
type K8sApplyOpts = {
rewriteImages?: Record<string, string>;
};
type LiveUpdateBinding = {
selector: ResourceSelector;
steps: LiveStep[];
};
type RunOpts = {
cwd?: string;
env?: Record<string, string>;
stdin?: "inherit" | "null";
};
declare function docker_build(logicalName: string, contextDir: string, opts?: DockerBuildOpts): Promise<BuiltImage>;
/**
* Experimental and subject to change.
*/
declare function dagger_build(logicalName: string, contextDir: string, opts: DaggerBuildOpts): Promise<BuiltImage>;
type K8sResource = {
apiVersion?: string;
kind?: string;
metadata?: {
name?: string;
namespace?: string;
labels?: Record<string, string>;
annotations?: Record<string, string>;
};
spec?: any;
data?: any;
[key: string]: any;
};
declare class YamlWrapper {
private resources;
constructor(input: string | K8sResource[]);
/**
* Transform each resource with a function
*/
map(transform: (resource: K8sResource, index: number) => K8sResource): YamlWrapper;
/**
* Filter resources by predicate
*/
filter(predicate: (resource: K8sResource) => boolean): YamlWrapper;
/**
* Update container images using a transform function
*/
updateImages(transformFn: (image: string) => string): YamlWrapper;
/**
* Get all resources as array
*/
toArray(): K8sResource[];
/**
* Convert to YAML string
*/
toYaml(): string;
/**
* Get count of resources
*/
count(): number;
}
declare const byKind: (kind: string) => (resource: K8sResource) => boolean;
declare const byName: (name: string) => (resource: K8sResource) => boolean;
declare const byNamespace: (namespace: string) => (resource: K8sResource) => boolean;
declare class K8sApplier extends YamlWrapper {
private _correlations;
constructor(input: string | K8sResource[]);
log(): this;
map(transform: (resource: K8sResource, index: number) => K8sResource): K8sApplier;
filter(predicate: (resource: K8sResource) => boolean): K8sApplier;
updateImages(transformFn: (image: string) => string): K8sApplier;
/**
* Apply the YAML resources to the Kubernetes cluster
*/
apply(options?: {
dryRun?: boolean;
validateContext?: boolean;
}): Promise<void>;
}
/**
* Create a new K8sApplier from YAML input
*
* @param input - YAML string
* @returns K8sApplier for chaining operations
*
* @example
* ```typescript
* await k8s(yamlString)
* .filter(byKind("Deployment"))
* .updateImages(image => `registry.com/${image}`)
* .apply();
* ```
*/
declare function k8s(input: string): K8sApplier;
/**
* Smart YAML loader that automatically detects input type
*
* @param input - File path, YAML content string, or array of mixed inputs
* @returns K8sApplier for chaining operations
*
* @example
* ```typescript
* // Load from file
* await k8s_yaml("./deploy.yaml")
* .updateImages(image => `registry.com/${image}`)
* .apply();
*
* // Load from YAML string
* await k8s_yaml(yamlContent)
* .filter(byKind("Deployment"))
* .apply();
*
* // Load from multiple mixed sources
* await k8s_yaml(["./app.yaml", yamlString, "./service.yaml"])
* .updateImages(image => `registry.com/${image}`)
* .apply();
* ```
*/
declare function k8s_yaml(input: string | string[]): K8sApplier;
/**
* Load YAML from a single file
*
* @param path - Path to YAML file
* @returns K8sApplier for chaining operations
*
* @example
* ```typescript
* await k8s_file("./deploy/app.yaml")
* .updateImages(image => `registry.com/${image}`)
* .apply();
* ```
*/
declare function k8s_file(path: string): K8sApplier;
/**
* Load YAML from multiple files
*
* @param paths - Array of paths to YAML files
* @returns K8sApplier for chaining operations
*
* @example
* ```typescript
* await k8s_files("./app.yaml", "./service.yaml", "./ingress.yaml")
* .filter(byKind("Deployment"))
* .apply();
* ```
*/
declare function k8s_files(...paths: string[]): K8sApplier;
declare function live_update(bind: LiveUpdateBinding): Promise<void>;
/**
* Get the current Kubernetes context
*/
declare function k8s_context(): Promise<string>;
/**
* Allow additional Kubernetes contexts for Tilt operations
* Similar to Tilt's allow_k8s_contexts function
*
* @param contexts - A string or array of context names to allow
*/
declare function allow_k8s_contexts(contexts: string | string[]): void;
/**
* Validate that the current context is safe for development
* Throws an error if the context is not allowed
*/
declare function validate_k8s_context(): Promise<void>;
/**
* Set the Kubernetes context after validating it's safe
* This function combines setting and allowing the context in one step
*
* @param context - The context name to switch to
* @param validate - Whether to validate the context is safe (default: true)
*/
declare function set_k8s_context(context: string, validate?: boolean): Promise<void>;
/**
* Reset allowed contexts to defaults
* Useful for testing or resetting state
*/
declare function reset_allowed_contexts(): void;
/**
* Set the current Kubernetes namespace
*
* @param namespace - The namespace to set as current
*/
declare function set_k8s_namespace(namespace: string): Promise<void>;
/**
* Get currently allowed contexts and patterns
* Useful for debugging and introspection
*/
declare function get_allowed_contexts(): {
contexts: string[];
patterns: string[];
};
declare function sync(src: string, dest: string, include?: string[], exclude?: string[]): LiveSync;
declare function run(cmd: string[], whenFilesChanged: string[], options?: {
dir?: string;
env?: Record<string, string>;
} | undefined): LiveRun;
declare function exec(cmd: string[], opts?: RunOpts): Promise<void>;
declare function execCapture(cmd: string[], opts?: Omit<RunOpts, "stdin">): Promise<string>;
declare class Logger {
private logger;
debug(message: string, attributes?: Record<string, any>): void;
info(message: string, attributes?: Record<string, any>): void;
warn(message: string, attributes?: Record<string, any>): void;
error(message: string, attributes?: Record<string, any>): void;
}
declare const logger: Logger;
/**
* Registry entry for a built image
*/
type ImageRegistryEntry = {
logicalName: string;
imageRef: string;
live_update?: LiveStep[];
digest?: string;
};
/**
* Global registry to track built images and their live update configurations
*/
declare class ImageRegistry {
private images;
/**
* Register a built image with its logical name and live update config
*/
register(logicalName: string, builtImage: BuiltImage): void;
/**
* Get a registered image by logical name
*/
get(logicalName: string): ImageRegistryEntry | undefined;
/**
* Get all registered images
*/
getAll(): ImageRegistryEntry[];
/**
* Check if a logical name is registered
*/
has(logicalName: string): boolean;
/**
* Clear all registered images (useful for testing)
*/
clear(): void;
/**
* Get all images that have live update configurations
*/
getLiveUpdateImages(): ImageRegistryEntry[];
}
declare const imageRegistry: ImageRegistry;
/**
* Registry configuration for mapping between host and cluster URLs
*/
type RegistryConfig = {
/** URL used for pushing images from the host (e.g., "localhost:36269") */
hostUrl: string;
/** URL used by the cluster to pull images (e.g., "k3d-registry:5000") */
clusterUrl?: string;
};
/**
* Sets the default registry configuration for docker_build operations
*
* @param config - Registry configuration with host and cluster URLs
* @returns The registry configuration for chaining
*
* @example
* ```typescript
* // Set up registry for k3d environment
* default_registry({
* hostUrl: "localhost:36269",
* clusterUrl: "k3d-registry:5000"
* });
*
* // Now docker_build will use this registry by default
* const built = await docker_build("my-app", "./context", {
* dockerfile: "./Dockerfile"
* });
*
* // Use the cluster image name directly
* await k8s_yaml("./deploy.yaml")
* .updateImages(() => built.clusterImageName)
* .apply();
* ```
*/
declare function default_registry(config: RegistryConfig): RegistryConfig;
/**
* Gets the current default registry configuration
*/
declare function get_default_registry(): RegistryConfig | null;
/**
* Resets the default registry configuration (useful for testing)
*/
declare function reset_default_registry(): void;
export { type ApplyInput, type BuiltImage, type DaggerBuildOpts, type DockerBuildOpts, type K8sApplyOpts, type LiveRun, type LiveStep, type LiveSync, type LiveUpdateBinding, type ResourceSelector, type RunOpts, YamlWrapper, allow_k8s_contexts, byKind, byName, byNamespace, dagger_build, default_registry, docker_build, exec, execCapture, get_allowed_contexts, get_default_registry, imageRegistry, k8s, k8s_context, k8s_file, k8s_files, k8s_yaml, live_update, logger, reset_allowed_contexts, reset_default_registry, run, set_k8s_context, set_k8s_namespace, sync, validate_k8s_context };