wrangler
Version:
Command-line interface for all things Cloudflare Workers
1,318 lines (1,276 loc) • 58.4 kB
TypeScript
import { Rule, CfModule, Environment, Config, CfScriptFormat, CfModuleType, CfKvNamespace, CfSendEmailBindings, CfBrowserBinding, CfAIBinding, CfImagesBinding, CfDurableObject, CfWorkflow, CfQueue, CfR2Bucket, CfD1Database, CfVectorize, CfHyperdrive, CfService, CfAnalyticsEngineDataset, CfDispatchNamespace, CfMTlsCertificate, CfPipeline, CfSecretsStoreSecrets, CfLogfwdrBinding, CfHelloWorld, CfRateLimit, CfWorkerLoader, CfVpcService, CfMediaBinding, DurableObjectMigration, ContainerApp, ZoneIdRoute, ZoneNameRoute, CustomDomainRoute, CfTailConsumer, ContainerEngine, CfUnsafe, ConfigBindingOptions, NormalizeAndValidateConfigArgs, ResolveConfigPathOptions, ParseError, RawConfig, PackageJSON, UserError, FatalError } from '@cloudflare/workers-utils';
export { ConfigBindingOptions as Experimental_ConfigBindingOptions, Config as Unstable_Config, RawConfig as Unstable_RawConfig, RawEnvironment as Unstable_RawEnvironment, experimental_patchConfig, experimental_readRawConfig } from '@cloudflare/workers-utils';
import { Json, Request, Response as Response$1, NodeJSCompatMode, DispatchFetch, Miniflare, WorkerRegistry, MiniflareOptions, Mutex, WorkerOptions, ModuleRule, RemoteProxyConnectionString } from 'miniflare';
import * as undici from 'undici';
import { RequestInfo, RequestInit, Response, FormData } from 'undici';
import { RouterConfig, AssetConfig } from '@cloudflare/workers-shared';
import { Metafile } from 'esbuild';
import Protocol from 'devtools-protocol/types/protocol-mapping';
import { EventEmitter } from 'node:events';
import { ContainerNormalizedConfig } from '@cloudflare/containers-shared';
import { IncomingRequestCfProperties } from '@cloudflare/workers-types/experimental';
import { URLSearchParams } from 'node:url';
import { Argv, PositionalOptions, Options, ArgumentsCamelCase, InferredOptionTypes, InferredOptionType } from 'yargs';
import Cloudflare from 'cloudflare';
interface EnablePagesAssetsServiceBindingOptions {
proxyPort?: number;
directory?: string;
}
interface Unstable_DevOptions {
config?: string;
env?: string;
envFiles?: string[];
ip?: string;
port?: number;
bundle?: boolean;
inspectorPort?: number;
localProtocol?: "http" | "https";
httpsKeyPath?: string;
httpsCertPath?: string;
assets?: string;
site?: string;
siteInclude?: string[];
siteExclude?: string[];
compatibilityDate?: string;
compatibilityFlags?: string[];
persist?: boolean;
persistTo?: string;
vars?: Record<string, string | Json>;
kv?: {
binding: string;
id?: string;
preview_id?: string;
remote?: boolean;
}[];
durableObjects?: {
name: string;
class_name: string;
script_name?: string | undefined;
environment?: string | undefined;
}[];
services?: {
binding: string;
service: string;
environment?: string | undefined;
entrypoint?: string | undefined;
remote?: boolean;
}[];
r2?: {
binding: string;
bucket_name?: string;
preview_bucket_name?: string;
remote?: boolean;
}[];
ai?: {
binding: string;
};
version_metadata?: {
binding: string;
};
moduleRoot?: string;
rules?: Rule[];
logLevel?: "none" | "info" | "error" | "log" | "warn" | "debug";
inspect?: boolean;
local?: boolean;
accountId?: string;
experimental?: {
processEntrypoint?: boolean;
additionalModules?: CfModule[];
d1Databases?: Environment["d1_databases"];
disableExperimentalWarning?: boolean;
disableDevRegistry?: boolean;
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
forceLocal?: boolean;
liveReload?: boolean;
showInteractiveDevSession?: boolean;
testMode?: boolean;
testScheduled?: boolean;
watch?: boolean;
devEnv?: boolean;
fileBasedRegistry?: boolean;
enableIpc?: boolean;
enableContainers?: boolean;
dockerPath?: string;
containerEngine?: string;
};
}
interface Unstable_DevWorker {
port: number;
address: string;
stop: () => Promise<void>;
fetch: (input?: RequestInfo, init?: RequestInit) => Promise<Response>;
waitUntilExit: () => Promise<void>;
}
/**
* unstable_dev starts a wrangler dev server, and returns a promise that resolves with utility functions to interact with it.
*/
declare function unstable_dev(script: string, options?: Unstable_DevOptions, apiOptions?: unknown): Promise<Unstable_DevWorker>;
interface PagesDeployOptions {
/**
* Path to static assets to deploy to Pages
*/
directory: string;
/**
* The Cloudflare Account ID that owns the project that's
* being published
*/
accountId: string;
/**
* The name of the project to be published
*/
projectName: string;
/**
* Branch name to use. Defaults to production branch
*/
branch?: string;
/**
* Whether or not to skip local file upload result caching
*/
skipCaching?: boolean;
/**
* Commit message associated to deployment
*/
commitMessage?: string;
/**
* Commit hash associated to deployment
*/
commitHash?: string;
/**
* Whether or not the deployment should be considered to be
* in a dirty commit state
*/
commitDirty?: boolean;
/**
* Path to the project's functions directory. Default uses
* the current working directory + /functions since this is
* typically called in a CLI
*/
functionsDirectory?: string;
/**
* Whether to run bundling on `_worker.js` before deploying.
* Default: true
*/
bundle?: boolean;
/**
* Whether to upload any server-side sourcemaps with this deployment
*/
sourceMaps: boolean;
/**
* Command line args passed to the `pages deploy` cmd
*/
args?: Record<string, unknown>;
}
/**
* Publish a directory to an account/project.
* NOTE: You will need the `CLOUDFLARE_API_KEY` environment
* variable set
*/
declare function deploy({ directory, accountId, projectName, branch, skipCaching, commitMessage, commitHash, commitDirty, functionsDirectory: customFunctionsDirectory, bundle, sourceMaps, args, }: PagesDeployOptions): Promise<{
deploymentResponse: {
id: string;
url: string;
environment: "production" | "preview";
build_config: {
build_command: string;
destination_dir: string;
root_dir: string;
web_analytics_tag?: string | undefined;
web_analytics_token?: string | undefined;
fast_builds?: boolean | undefined;
};
created_on: string;
production_branch: string;
project_id: string;
project_name: string;
deployment_trigger: {
type: string;
metadata: {
branch: string;
commit_hash: string;
commit_message: string;
};
};
latest_stage: {
status: "canceled" | "active" | "idle" | "success" | "failure" | "skipped";
name: "build" | "queued" | "deploy" | "initialize" | "clone_repo";
started_on: string | null;
ended_on: string | null;
};
stages: {
status: "canceled" | "active" | "idle" | "success" | "failure" | "skipped";
name: "build" | "queued" | "deploy" | "initialize" | "clone_repo";
started_on: string | null;
ended_on: string | null;
}[];
aliases: string[];
modified_on: string;
short_id: string;
build_image_major_version: number;
kv_namespaces?: any;
source?: {
type: "github" | "gitlab";
config: {
owner: string;
repo_name: string;
production_branch?: string | undefined;
pr_comments_enabled?: boolean | undefined;
deployments_enabled?: boolean | undefined;
production_deployments_enabled?: boolean | undefined;
preview_deployment_setting?: "custom" | "none" | "all" | undefined;
preview_branch_includes?: string[] | undefined;
preview_branch_excludes?: string[] | undefined;
};
} | undefined;
env_vars?: any;
durable_object_namespaces?: any;
is_skipped?: boolean | undefined;
files?: {
[x: string]: string | undefined;
} | undefined;
};
formData: FormData;
}>;
declare const unstable_pages: {
deploy: typeof deploy;
};
/**
* The compliance region to use for the API requests.
*/
type ComplianceConfig = Partial<Pick<Config, "compliance_region">>;
type _Params<ParamsArray extends [unknown?]> = ParamsArray extends [infer P] ? P : undefined;
type _EventMethods = keyof Protocol.Events;
type DevToolsEvent<Method extends _EventMethods> = Method extends unknown ? {
method: Method;
params: _Params<Protocol.Events[Method]>;
} : never;
type AssetsOptions = {
directory: string;
binding?: string;
routerConfig: RouterConfig;
assetConfig: AssetConfig;
_redirects?: string;
_headers?: string;
run_worker_first?: boolean | string[];
};
type ApiCredentials = {
apiToken: string;
} | {
authKey: string;
authEmail: string;
};
/**
* An entry point for the Worker.
*
* It consists not just of a `file`, but also of a `directory` that is used to resolve relative paths.
*/
type Entry = {
/** A worker's entrypoint */
file: string;
/** A worker's directory. Usually where the Wrangler configuration file is located */
projectRoot: string;
/** The path to the config file, if it exists. */
configPath: string | undefined;
/** Is this a module worker or a service worker? */
format: CfScriptFormat;
/** The directory that contains all of a `--no-bundle` worker's modules. Usually `${directory}/src`. Defaults to path.dirname(file) */
moduleRoot: string;
/**
* A worker's name
*/
name?: string | undefined;
/** Export from a Worker's entrypoint */
exports: string[];
};
/**
* Information about Wrangler's bundling process that needs passed through
* for DevTools sourcemap transformation
*/
interface SourceMapMetadata {
tmpDir: string;
entryDirectory: string;
}
type EsbuildBundle = {
id: number;
path: string;
entrypointSource: string;
entry: Entry;
type: CfModuleType;
modules: CfModule[];
dependencies: Metafile["outputs"][string]["inputs"];
sourceMapPath: string | undefined;
sourceMapMetadata: SourceMapMetadata | undefined;
};
/**
* A Cloudflare account.
*/
interface CfAccount {
/**
* An API token.
*
* @link https://api.cloudflare.com/#user-api-tokens-properties
*/
apiToken: ApiCredentials;
/**
* An account ID.
*/
accountId: string;
}
declare class ConfigController extends Controller {
#private;
latestInput?: StartDevWorkerInput;
latestConfig?: StartDevWorkerOptions;
set(input: StartDevWorkerInput, throwErrors?: boolean): Promise<StartDevWorkerOptions | undefined>;
patch(input: Partial<StartDevWorkerInput>): Promise<StartDevWorkerOptions | undefined>;
onDevRegistryUpdate(event: DevRegistryUpdateEvent): void;
teardown(): Promise<void>;
emitConfigUpdateEvent(config: StartDevWorkerOptions): void;
}
type MiniflareWorker = Awaited<ReturnType<Miniflare["getWorker"]>>;
interface Worker {
ready: Promise<void>;
url: Promise<URL>;
inspectorUrl: Promise<URL | undefined>;
config: StartDevWorkerOptions;
setConfig: ConfigController["set"];
patchConfig: ConfigController["patch"];
fetch: DispatchFetch;
scheduled: MiniflareWorker["scheduled"];
queue: MiniflareWorker["queue"];
dispose(): Promise<void>;
raw: DevEnv;
}
interface StartDevWorkerInput {
/** The name of the worker. */
name?: string;
/**
* The javascript or typescript entry-point of the worker.
* This is the `main` property of a Wrangler configuration file.
*/
entrypoint?: string;
/** The configuration path of the worker. */
config?: string;
/** The compatibility date for the workerd runtime. */
compatibilityDate?: string;
/** The compatibility flags for the workerd runtime. */
compatibilityFlags?: string[];
/** Specify the compliance region mode of the Worker. */
complianceRegion?: Config["compliance_region"];
/** Configuration for Python modules. */
pythonModules?: {
/** A list of glob patterns to exclude files from the python_modules directory when bundling. */
exclude?: string[];
};
env?: string;
/**
* An array of paths to the .env files to load for this worker, relative to the project directory.
*
* If not specified, defaults to the standard `.env` files as given by `getDefaultEnvFiles()`.
* The project directory is where the Wrangler configuration file is located or the current working directory otherwise.
*/
envFiles?: string[];
/** The bindings available to the worker. The specified bindind type will be exposed to the worker on the `env` object under the same key. */
bindings?: Record<string, Binding>;
migrations?: DurableObjectMigration[];
containers?: ContainerApp[];
/** The triggers which will cause the worker's exported default handlers to be called. */
triggers?: Trigger[];
tailConsumers?: CfTailConsumer[];
streamingTailConsumers?: CfTailConsumer[];
/**
* Whether Wrangler should send usage metrics to Cloudflare for this project.
*
* When defined this will override any user settings.
* Otherwise, Wrangler will use the user's preference.
*/
sendMetrics?: boolean;
/** Options applying to the worker's build step. Applies to deploy and dev. */
build?: {
/** Whether the worker and its dependencies are bundled. Defaults to true. */
bundle?: boolean;
additionalModules?: CfModule[];
findAdditionalModules?: boolean;
processEntrypoint?: boolean;
/** Specifies types of modules matched by globs. */
moduleRules?: Rule[];
/** Replace global identifiers with constant expressions, e.g. { debug: 'true', version: '"1.0.0"' }. Only takes effect if bundle: true. */
define?: Record<string, string>;
/** Alias modules */
alias?: Record<string, string>;
/** Whether the bundled worker is minified. Only takes effect if bundle: true. */
minify?: boolean;
/** Whether to keep function names after JavaScript transpilations. */
keepNames?: boolean;
/** Options controlling a custom build step. */
custom?: {
/** Custom shell command to run before bundling. Runs even if bundle. */
command?: string;
/** The cwd to run the command in. */
workingDirectory?: string;
/** Filepath(s) to watch for changes. Upon changes, the command will be rerun. */
watch?: string | string[];
};
jsxFactory?: string;
jsxFragment?: string;
tsconfig?: string;
nodejsCompatMode?: Hook<NodeJSCompatMode, [Config]>;
moduleRoot?: string;
};
/** Options applying to the worker's development preview environment. */
dev?: {
/** Options applying to the worker's inspector server. False disables the inspector server. */
inspector?: {
hostname?: string;
port?: number;
secure?: boolean;
} | false;
/** Whether the worker runs on the edge or locally. This has several options:
* - true | "minimal": Run your Worker's code & bindings in a remote preview session, optionally using minimal mode as an internal detail
* - false: Run your Worker's code & bindings in a local simulator
* - undefined (default): Run your Worker's code locally, and any configured remote bindings remotely
*/
remote?: boolean | "minimal";
/** Cloudflare Account credentials. Can be provided upfront or as a function which will be called only when required. */
auth?: AsyncHook<CfAccount, [Pick<Config, "account_id">]>;
/** Whether local storage (KV, Durable Objects, R2, D1, etc) is persisted. You can also specify the directory to persist data to. */
persist?: string;
/** Controls which logs are logged 🤙. */
logLevel?: LogLevel;
/** Whether the worker server restarts upon source/config file changes. */
watch?: boolean;
/** Whether a script tag is inserted on text/html responses which will reload the page upon file changes. Defaults to false. */
liveReload?: boolean;
/** The local address to reach your worker. Applies to remote: true (remote mode) and remote: false (local mode). */
server?: {
hostname?: string;
port?: number;
secure?: boolean;
httpsKeyPath?: string;
httpsCertPath?: string;
};
/** Controls what request.url looks like inside the worker. */
origin?: {
hostname?: string;
secure?: boolean;
};
/** A hook for outbound fetch calls from within the worker. */
outboundService?: ServiceFetch;
/** An undici MockAgent to declaratively mock fetch calls to particular resources. */
mockFetch?: undici.MockAgent;
testScheduled?: boolean;
/** Treat this as the primary worker in a multiworker setup (i.e. the first Worker in Miniflare's options) */
multiworkerPrimary?: boolean;
containerBuildId?: string;
/** Whether to build and connect to containers during local dev. Requires Docker daemon to be running. Defaults to true. */
enableContainers?: boolean;
/** Path to the dev registry directory */
registry?: string;
/** Path to the docker executable. Defaults to 'docker' */
dockerPath?: string;
/** Options for the container engine */
containerEngine?: ContainerEngine;
};
legacy?: {
site?: Hook<Config["site"], [Config]>;
useServiceEnvironments?: boolean;
};
unsafe?: Omit<CfUnsafe, "bindings">;
assets?: string;
experimental?: {
tailLogs: boolean;
};
}
type StartDevWorkerOptions = Omit<StartDevWorkerInput, "assets" | "containers"> & {
/** A worker's directory. Usually where the Wrangler configuration file is located */
projectRoot: string;
build: StartDevWorkerInput["build"] & {
nodejsCompatMode: NodeJSCompatMode;
format: CfScriptFormat;
moduleRoot: string;
moduleRules: Rule[];
define: Record<string, string>;
additionalModules: CfModule[];
exports: string[];
processEntrypoint: boolean;
};
legacy: StartDevWorkerInput["legacy"] & {
site?: Config["site"];
};
dev: StartDevWorkerInput["dev"] & {
persist: string;
auth?: AsyncHook<CfAccount>;
};
entrypoint: string;
assets?: AssetsOptions;
containers?: ContainerNormalizedConfig[];
name: string;
complianceRegion: Config["compliance_region"];
};
type HookValues = string | number | boolean | object | undefined | null;
type Hook<T extends HookValues, Args extends unknown[] = []> = T | ((...args: Args) => T);
type AsyncHook<T extends HookValues, Args extends unknown[] = []> = Hook<T, Args> | Hook<Promise<T>, Args>;
type Bundle = EsbuildBundle;
type LogLevel = "debug" | "info" | "log" | "warn" | "error" | "none";
type File<Contents = string, Path = string> = {
path: Path;
} | {
contents: Contents;
path?: Path;
};
type BinaryFile = File<Uint8Array>;
type QueueConsumer = NonNullable<Config["queues"]["consumers"]>[number];
type Trigger = {
type: "workers.dev";
} | {
type: "route";
pattern: string;
} | ({
type: "route";
} & ZoneIdRoute) | ({
type: "route";
} & ZoneNameRoute) | ({
type: "route";
} & CustomDomainRoute) | {
type: "cron";
cron: string;
} | ({
type: "queue-consumer";
} & QueueConsumer);
type BindingOmit<T> = Omit<T, "binding">;
type NameOmit<T> = Omit<T, "name">;
type Binding = {
type: "plain_text";
value: string;
} | {
type: "json";
value: Json;
} | ({
type: "kv_namespace";
} & BindingOmit<CfKvNamespace>) | ({
type: "send_email";
} & NameOmit<CfSendEmailBindings>) | {
type: "wasm_module";
source: BinaryFile;
} | {
type: "text_blob";
source: File;
} | ({
type: "browser";
} & BindingOmit<CfBrowserBinding>) | ({
type: "ai";
} & BindingOmit<CfAIBinding>) | ({
type: "images";
} & BindingOmit<CfImagesBinding>) | {
type: "version_metadata";
} | {
type: "data_blob";
source: BinaryFile;
} | ({
type: "durable_object_namespace";
} & NameOmit<CfDurableObject>) | ({
type: "workflow";
} & BindingOmit<CfWorkflow>) | ({
type: "queue";
} & BindingOmit<CfQueue>) | ({
type: "r2_bucket";
} & BindingOmit<CfR2Bucket>) | ({
type: "d1";
} & BindingOmit<CfD1Database>) | ({
type: "vectorize";
} & BindingOmit<CfVectorize>) | ({
type: "hyperdrive";
} & BindingOmit<CfHyperdrive>) | ({
type: "service";
} & BindingOmit<CfService>) | {
type: "fetcher";
fetcher: ServiceFetch;
} | ({
type: "analytics_engine";
} & BindingOmit<CfAnalyticsEngineDataset>) | ({
type: "dispatch_namespace";
} & BindingOmit<CfDispatchNamespace>) | ({
type: "mtls_certificate";
} & BindingOmit<CfMTlsCertificate>) | ({
type: "pipeline";
} & BindingOmit<CfPipeline>) | ({
type: "secrets_store_secret";
} & BindingOmit<CfSecretsStoreSecrets>) | ({
type: "logfwdr";
} & NameOmit<CfLogfwdrBinding>) | ({
type: "unsafe_hello_world";
} & BindingOmit<CfHelloWorld>) | ({
type: "ratelimit";
} & NameOmit<CfRateLimit>) | ({
type: "worker_loader";
} & BindingOmit<CfWorkerLoader>) | ({
type: "vpc_service";
} & BindingOmit<CfVpcService>) | ({
type: "media";
} & BindingOmit<CfMediaBinding>) | {
type: `unsafe_${string}`;
} | {
type: "assets";
};
type ServiceFetch = (request: Request) => Promise<Response$1> | Response$1;
type ErrorEvent = BaseErrorEvent<"ConfigController" | "BundlerController" | "LocalRuntimeController" | "RemoteRuntimeController" | "ProxyWorker" | "InspectorProxyWorker" | "MultiworkerRuntimeController"> | BaseErrorEvent<"ProxyController", {
config?: StartDevWorkerOptions;
bundle?: Bundle;
}> | BaseErrorEvent<"BundlerController", {
config?: StartDevWorkerOptions;
filePath?: string;
}>;
type BaseErrorEvent<Source = string, Data = undefined> = {
type: "error";
reason: string;
cause: Error | SerializedError;
source: Source;
data: Data;
};
type ConfigUpdateEvent = {
type: "configUpdate";
config: StartDevWorkerOptions;
};
type BundleStartEvent = {
type: "bundleStart";
config: StartDevWorkerOptions;
};
type BundleCompleteEvent = {
type: "bundleComplete";
config: StartDevWorkerOptions;
bundle: Bundle;
};
type ReloadStartEvent = {
type: "reloadStart";
config: StartDevWorkerOptions;
bundle: Bundle;
};
type ReloadCompleteEvent = {
type: "reloadComplete";
config: StartDevWorkerOptions;
bundle: Bundle;
proxyData: ProxyData;
};
type DevRegistryUpdateEvent = {
type: "devRegistryUpdate";
registry: WorkerRegistry;
};
type PreviewTokenExpiredEvent = {
type: "previewTokenExpired";
proxyData: ProxyData;
};
type ReadyEvent = {
type: "ready";
proxyWorker: Miniflare;
url: URL;
inspectorUrl: URL | undefined;
};
type ProxyWorkerIncomingRequestBody = {
type: "play";
proxyData: ProxyData;
} | {
type: "pause";
};
type ProxyWorkerOutgoingRequestBody = {
type: "error";
error: SerializedError;
} | {
type: "previewTokenExpired";
proxyData: ProxyData;
} | {
type: "debug-log";
args: Parameters<typeof console.debug>;
};
type InspectorProxyWorkerIncomingWebSocketMessage = {
type: ReloadStartEvent["type"];
} | {
type: ReloadCompleteEvent["type"];
proxyData: ProxyData;
};
type InspectorProxyWorkerOutgoingWebsocketMessage = DevToolsEvent<"Runtime.consoleAPICalled"> | DevToolsEvent<"Runtime.exceptionThrown">;
type InspectorProxyWorkerOutgoingRequestBody = {
type: "error";
error: SerializedError;
} | {
type: "runtime-websocket-error";
error: SerializedError;
} | {
type: "debug-log";
args: Parameters<typeof console.debug>;
} | {
type: "load-network-resource";
url: string;
};
type SerializedError = {
message: string;
name?: string;
stack?: string | undefined;
cause?: unknown;
};
type UrlOriginParts = Pick<URL, "protocol" | "hostname" | "port">;
type UrlOriginAndPathnameParts = Pick<URL, "protocol" | "hostname" | "port" | "pathname">;
type ProxyData = {
userWorkerUrl: UrlOriginParts;
userWorkerInspectorUrl?: UrlOriginAndPathnameParts;
userWorkerInnerUrlOverrides?: Partial<UrlOriginParts>;
headers: Record<string, string>;
liveReload?: boolean;
proxyLogsToController?: boolean;
};
type ControllerEvent = ErrorEvent | ConfigUpdateEvent | BundleStartEvent | BundleCompleteEvent | ReloadStartEvent | ReloadCompleteEvent | DevRegistryUpdateEvent | PreviewTokenExpiredEvent;
interface ControllerBus {
dispatch(event: ControllerEvent): void;
}
declare abstract class Controller {
#private;
protected bus: ControllerBus;
constructor(bus: ControllerBus);
teardown(): Promise<void>;
protected emitErrorEvent(event: ErrorEvent): void;
}
declare abstract class RuntimeController extends Controller {
abstract onBundleStart(_: BundleStartEvent): void;
abstract onBundleComplete(_: BundleCompleteEvent): void;
abstract onPreviewTokenExpired(_: PreviewTokenExpiredEvent): void;
protected emitReloadStartEvent(data: ReloadStartEvent): void;
protected emitReloadCompleteEvent(data: ReloadCompleteEvent): void;
protected emitDevRegistryUpdateEvent(data: DevRegistryUpdateEvent): void;
}
declare class BundlerController extends Controller {
#private;
onConfigUpdate(event: ConfigUpdateEvent): void;
teardown(): Promise<void>;
emitBundleStartEvent(config: StartDevWorkerOptions): void;
emitBundleCompleteEvent(config: StartDevWorkerOptions, bundle: EsbuildBundle): void;
}
type MaybePromise<T> = T | Promise<T>;
type DeferredPromise<T> = {
promise: Promise<T>;
resolve: (_: MaybePromise<T>) => void;
reject: (_: Error) => void;
};
declare function convertConfigBindingsToStartWorkerBindings(configBindings: ConfigBindingOptions): StartDevWorkerOptions["bindings"];
declare class ProxyController extends Controller {
ready: DeferredPromise<ReadyEvent>;
localServerReady: DeferredPromise<void>;
proxyWorker?: Miniflare;
proxyWorkerOptions?: MiniflareOptions;
private inspectorProxyWorkerWebSocket?;
protected latestConfig?: StartDevWorkerOptions;
protected latestBundle?: EsbuildBundle;
secret: `${string}-${string}-${string}-${string}-${string}`;
protected createProxyWorker(): void;
private reconnectInspectorProxyWorker;
runtimeMessageMutex: Mutex;
sendMessageToProxyWorker(message: ProxyWorkerIncomingRequestBody, retries?: number): Promise<void>;
sendMessageToInspectorProxyWorker(message: InspectorProxyWorkerIncomingWebSocketMessage, retries?: number): Promise<void>;
get inspectorEnabled(): boolean;
onConfigUpdate(data: ConfigUpdateEvent): void;
onBundleStart(data: BundleStartEvent): void;
onReloadStart(data: ReloadStartEvent): void;
onReloadComplete(data: ReloadCompleteEvent): void;
onProxyWorkerMessage(message: ProxyWorkerOutgoingRequestBody): void;
onInspectorProxyWorkerMessage(message: InspectorProxyWorkerOutgoingWebsocketMessage): void;
onInspectorProxyWorkerRequest(message: InspectorProxyWorkerOutgoingRequestBody): Promise<Response$1>;
_torndown: boolean;
teardown(): Promise<void>;
emitReadyEvent(proxyWorker: Miniflare, url: URL, inspectorUrl: URL | undefined): void;
emitPreviewTokenExpiredEvent(proxyData: ProxyData): void;
emitErrorEvent(data: ErrorEvent): void;
emitErrorEvent(reason: string, cause?: Error | SerializedError): void;
}
type ControllerFactory<C extends Controller> = (devEnv: DevEnv) => C;
declare class DevEnv extends EventEmitter implements ControllerBus {
config: ConfigController;
bundler: BundlerController;
runtimes: RuntimeController[];
proxy: ProxyController;
startWorker(options: StartDevWorkerInput): Promise<Worker>;
constructor({ configFactory, bundlerFactory, runtimeFactories, proxyFactory, }?: {
configFactory?: ControllerFactory<ConfigController>;
bundlerFactory?: ControllerFactory<BundlerController>;
runtimeFactories?: ControllerFactory<RuntimeController>[];
proxyFactory?: ControllerFactory<ProxyController>;
});
/**
* Central message bus dispatch method.
* All events from controllers flow through here, making the event routing explicit and traceable.
*
* Event flow:
* - ConfigController emits configUpdate → BundlerController, ProxyController
* - BundlerController emits bundleStart → ProxyController, RuntimeControllers
* - BundlerController emits bundleComplete → RuntimeControllers
* - RuntimeController emits reloadStart → ProxyController
* - RuntimeController emits reloadComplete → ProxyController
* - RuntimeController emits devRegistryUpdate → ConfigController
* - ProxyController emits previewTokenExpired → RuntimeControllers
* - Any controller emits error → DevEnv error handler
*/
dispatch(event: ControllerEvent): void;
private handleErrorEvent;
teardown(): Promise<void>;
}
declare function startWorker(options: StartDevWorkerInput): Promise<Worker>;
type ReadConfigCommandArgs = NormalizeAndValidateConfigArgs & {
config?: string;
script?: string;
};
type ReadConfigOptions = ResolveConfigPathOptions & {
hideWarnings?: boolean;
preserveOriginalMain?: boolean;
};
/**
* Get the Wrangler configuration; read it from the give `configPath` if available.
*/
declare function readConfig(args: ReadConfigCommandArgs, options?: ReadConfigOptions): Config;
declare function getDurableObjectClassNameToUseSQLiteMap(migrations: Config["migrations"] | undefined): Map<string, boolean>;
/**
* Note about this file:
*
* Here we are providing a no-op implementation of the runtime Cache API instead of using
* the miniflare implementation (via `mf.getCaches()`).
*
* We are not using miniflare's implementation because that would require the user to provide
* miniflare-specific Request objects and they would receive back miniflare-specific Response
* objects, this (in particular the Request part) is not really suitable for `getPlatformProxy`
* as people would ideally interact with their bindings in a very production-like manner and
* requiring them to deal with miniflare-specific classes defeats a bit the purpose of the utility.
*
* Similarly the Request and Response types here are set to `undefined` as not to use specific ones
* that would require us to make a choice right now or the user to adapt their code in order to work
* with the api.
*
* We need to find a better/generic manner in which we can reuse the miniflare cache implementation,
* but until then the no-op implementation below will have to do.
*/
/**
* No-op implementation of CacheStorage
*/
declare class CacheStorage {
constructor();
open(cacheName: string): Promise<Cache>;
get default(): Cache;
}
type CacheRequest = any;
type CacheResponse = any;
/**
* No-op implementation of Cache
*/
declare class Cache {
delete(request: CacheRequest, options?: CacheQueryOptions): Promise<boolean>;
match(request: CacheRequest, options?: CacheQueryOptions): Promise<CacheResponse | undefined>;
put(request: CacheRequest, response: CacheResponse): Promise<void>;
}
type CacheQueryOptions = {
ignoreMethod?: boolean;
};
declare class ExecutionContext {
waitUntil(promise: Promise<any>): void;
passThroughOnException(): void;
props: any;
}
/**
* Get the Worker `vars` bindings for a `wrangler dev` instance of a Worker.
*
* The `vars` bindings can be specified in the Wrangler configuration file.
* But "secret" `vars` are usually only provided at the server -
* either by creating them in the Dashboard UI, or using the `wrangler secret` command.
*
* It is useful during development, to provide these types of variable locally.
* When running `wrangler dev` we will look for a file called `.dev.vars`, situated
* next to the User's Wrangler configuration file (or in the current working directory if there is no
* Wrangler configuration). If the `--env <env>` option is set, we'll first look for
* `.dev.vars.<env>`.
*
* If there are no `.dev.vars*` file, (and CLOUDFLARE_LOAD_DEV_VARS_FROM_DOT_ENV is not "false")
* we will look for `.env*` files in the same directory.
* If the `envFiles` option is set, we'll look for the `.env` files at those paths instead of the defaults.
*
* Any values in these files (all formatted like `.env` files) will add to or override `vars`
* bindings provided in the Wrangler configuration file.
*
* @param configPath - The path to the Wrangler configuration file, if defined.
* @param envFiles - An array of paths to .env files to load; if `undefined` the default .env files will be used (see `getDefaultEnvFiles()`).
* The `envFiles` paths are resolved against the directory of the Wrangler configuration file, if there is one, otherwise against the current working directory.
* @param vars - The existing `vars` bindings from the Wrangler configuration.
* @param env - The specific environment name (e.g., "staging") or `undefined` if no specific environment is set.
* @param silent - If true, will not log any messages about the loaded .dev.vars files or .env files.
* @returns The merged `vars` bindings, including those loaded from `.dev.vars` or `.env` files.
*/
declare function getVarsForDev(configPath: string | undefined, envFiles: string[] | undefined, vars: Config["vars"], env: string | undefined, silent?: boolean): Config["vars"];
/**
* Options for the `getPlatformProxy` utility
*/
type GetPlatformProxyOptions = {
/**
* The name of the environment to use
*/
environment?: string;
/**
* The path to the config file to use.
* If no path is specified the default behavior is to search from the
* current directory up the filesystem for a Wrangler configuration file to use.
*
* Note: this field is optional but if a path is specified it must
* point to a valid file on the filesystem
*/
configPath?: string;
/**
* Paths to `.env` files to load environment variables from, relative to the project directory.
*
* The project directory is computed as the directory containing `configPath` or the current working directory if `configPath` is undefined.
*
* If `envFiles` is defined, only the files in the array will be considered for loading local dev variables.
* If `undefined`, the default behavior is:
* - compute the project directory as that containing the Wrangler configuration file,
* or the current working directory if no Wrangler configuration file is specified.
* - look for `.env` and `.env.local` files in the project directory.
* - if the `environment` option is specified, also look for `.env.<environment>` and `.env.<environment>.local`
* files in the project directory
* - resulting in an `envFiles` array like: `[".env", ".env.local", ".env.<environment>", ".env.<environment>.local"]`.
*
* The values from files earlier in the `envFiles` array (e.g. `envFiles[x]`) will be overridden by values from files later in the array (e.g. `envFiles[x+1)`).
*/
envFiles?: string[];
/**
* Indicates if and where to persist the bindings data, if not present or `true` it defaults to the same location
* used by wrangler: `.wrangler/state/v3` (so that the same data can be easily used by the caller and wrangler).
* If `false` is specified no data is persisted on the filesystem.
*/
persist?: boolean | {
path: string;
};
/**
* Whether remote bindings should be enabled or not (defaults to `true`)
*/
remoteBindings?: boolean;
};
/**
* Result of the `getPlatformProxy` utility
*/
type PlatformProxy<Env = Record<string, unknown>, CfProperties extends Record<string, unknown> = IncomingRequestCfProperties> = {
/**
* Environment object containing the various Cloudflare bindings
*/
env: Env;
/**
* Mock of the context object that Workers received in their request handler, all the object's methods are no-op
*/
cf: CfProperties;
/**
* Mock of the context object that Workers received in their request handler, all the object's methods are no-op
*/
ctx: ExecutionContext;
/**
* Caches object emulating the Workers Cache runtime API
*/
caches: CacheStorage;
/**
* Function used to dispose of the child process providing the bindings implementation
*/
dispose: () => Promise<void>;
};
/**
* By reading from a Wrangler configuration file this function generates proxy objects that can be
* used to simulate the interaction with the Cloudflare platform during local development
* in a Node.js environment
*
* @param options The various options that can tweak this function's behavior
* @returns An Object containing the generated proxies alongside other related utilities
*/
declare function getPlatformProxy<Env = Record<string, unknown>, CfProperties extends Record<string, unknown> = IncomingRequestCfProperties>(options?: GetPlatformProxyOptions): Promise<PlatformProxy<Env, CfProperties>>;
type SourcelessWorkerOptions = Omit<WorkerOptions, "script" | "scriptPath" | "modules" | "modulesRoot"> & {
modulesRules?: ModuleRule[];
};
interface Unstable_MiniflareWorkerOptions {
workerOptions: SourcelessWorkerOptions;
define: Record<string, string>;
main?: string;
externalWorkers: WorkerOptions[];
}
declare function unstable_getMiniflareWorkerOptions(configPath: string, env?: string, options?: {
remoteProxyConnectionString?: RemoteProxyConnectionString;
overrides?: {
assets?: Partial<AssetsOptions>;
enableContainers?: boolean;
};
containerBuildId?: string;
}): Unstable_MiniflareWorkerOptions;
declare function unstable_getMiniflareWorkerOptions(config: Config, env?: string, options?: {
remoteProxyConnectionString?: RemoteProxyConnectionString;
overrides?: {
assets?: Partial<AssetsOptions>;
enableContainers?: boolean;
};
containerBuildId?: string;
}): Unstable_MiniflareWorkerOptions;
type StartRemoteProxySessionOptions = {
workerName?: string;
auth?: NonNullable<StartDevWorkerInput["dev"]>["auth"];
/** If running in a non-public compliance region, set this here. */
complianceRegion?: Config["compliance_region"];
};
declare function startRemoteProxySession(bindings: StartDevWorkerInput["bindings"], options?: StartRemoteProxySessionOptions): Promise<RemoteProxySession>;
type RemoteProxySession = Pick<Worker, "ready" | "dispose"> & {
updateBindings: (bindings: StartDevWorkerInput["bindings"]) => Promise<void>;
remoteProxyConnectionString: RemoteProxyConnectionString;
};
type WranglerConfigObject = {
/** The path to the wrangler config file */
path: string;
/** The target environment */
environment?: string;
};
type WorkerConfigObject = {
/** The name of the worker */
name?: string;
/** The Worker's bindings */
bindings: NonNullable<StartDevWorkerInput["bindings"]>;
/** If running in a non-public compliance region, set this here. */
complianceRegion?: Config["compliance_region"];
};
/**
* Utility for potentially starting or updating a remote proxy session.
*
* @param wranglerOrWorkerConfigObject either a file path to a wrangler configuration file or an object containing the name of
* the target worker alongside its bindings.
* @param preExistingRemoteProxySessionData the optional data of a pre-existing remote proxy session if there was one, this
* argument can be omitted or set to null if there is no pre-existing remote proxy session
* @param auth the authentication information for establishing the remote proxy connection
* @returns null if no existing remote proxy session was provided and one should not be created (because the worker is not
* defining any remote bindings), the data associated to the created/updated remote proxy session otherwise.
*/
declare function maybeStartOrUpdateRemoteProxySession(wranglerOrWorkerConfigObject: WranglerConfigObject | WorkerConfigObject, preExistingRemoteProxySessionData?: {
session: RemoteProxySession;
remoteBindings: Record<string, Binding>;
auth?: CfAccount | undefined;
} | null, auth?: CfAccount | undefined): Promise<{
session: RemoteProxySession;
remoteBindings: Record<string, Binding>;
} | null>;
declare const LOGGER_LEVELS: {
readonly none: -1;
readonly error: 0;
readonly warn: 1;
readonly info: 2;
readonly log: 3;
readonly debug: 4;
};
type LoggerLevel = keyof typeof LOGGER_LEVELS;
type TableRow<Keys extends string> = Record<Keys, string>;
declare class Logger {
#private;
constructor();
private overrideLoggerLevel?;
private onceHistory;
get loggerLevel(): "debug" | "error" | "none" | "info" | "log" | "warn";
set loggerLevel(val: "debug" | "error" | "none" | "info" | "log" | "warn");
resetLoggerLevel(): void;
columns: number;
json: (data: unknown) => void;
debug: (...args: unknown[]) => void;
debugWithSanitization: (label: string, ...args: unknown[]) => void;
info: (...args: unknown[]) => void;
log: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error(...args: unknown[]): void;
error(error: ParseError): void;
table<Keys extends string>(data: TableRow<Keys>[], options?: {
wordWrap: boolean;
head?: Keys[];
}): void;
console<M extends Exclude<keyof Console, "Console">>(method: M, ...args: Parameters<Console[M]>): void;
get once(): {
info: (...args: unknown[]) => void;
log: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
};
clearHistory(): void;
doLogOnce(messageLevel: Exclude<LoggerLevel, "none">, args: unknown[]): void;
private doLog;
static registerBeforeLogHook(callback: (() => void) | undefined): void;
static registerAfterLogHook(callback: (() => void) | undefined): void;
private formatMessage;
}
/**
* Split an SQLQuery into an array of statements
*/
declare function splitSqlQuery(sql: string): string[];
type ConfigurationOptions = {
outputDir: string;
projectPath: string;
workerName: string;
dryRun: boolean;
};
declare abstract class Framework {
abstract name: string;
preview?: string;
deploy?: string;
typegen?: string;
/** Some frameworks (i.e. Nuxt) don't need additional configuration */
get configured(): boolean;
abstract configure(options: ConfigurationOptions): Promise<RawConfig> | RawConfig;
configurationDescription?: string;
}
type AutoConfigDetails = {
/** The name of the worker */
workerName: string;
/** The path to the project (defaults to cwd) */
projectPath: string;
/** The content of the project's package.json file (if any) */
packageJson?: PackageJSON;
/** Whether the project is already configured (no autoconfig required) */
configured: boolean;
/** Details about the detected framework (if any) */
framework?: Framework;
/** The build command used to build the project (if any) */
buildCommand?: string;
/** The output directory (if no framework is used, points to the raw asset files) */
outputDir?: string;
};
type AutoConfigOptions = {
/** Whether to run autoconfig without actually applying any filesystem modification (default: false) */
dryRun?: boolean;
/**
* Whether the build command should be run (default: true)
*
* Note: When `dryRun` is `true` the build command is never run.
*/
runBuild?: boolean;
/**
* Whether the confirmation prompts should be skipped (default: false)
*
* Note: When `dryRun` is `true` the the confirmation prompts are always skipped.
*/
skipConfirmations?: boolean;
};
declare function getDetailsForAutoConfig({ projectPath, wranglerConfig, }?: {
projectPath?: string;
wranglerConfig?: Config;
}): Promise<AutoConfigDetails>;
declare function runAutoConfig(autoConfigDetails: AutoConfigDetails, autoConfigOptions?: AutoConfigOptions): Promise<void>;
/**
* Make a fetch request, and extract the `result` from the JSON response.
*/
declare function fetchResult<ResponseType>(complianceConfig: ComplianceConfig, resource: string, init?: RequestInit, queryParams?: URLSearchParams, abortSignal?: AbortSignal, apiToken?: ApiCredentials): Promise<ResponseType>;
type ExperimentalFlags = {
MULTIWORKER: boolean;
RESOURCES_PROVISION: boolean;
DEPLOY_REMOTE_DIFF_CHECK: boolean;
AUTOCREATE_RESOURCES: boolean;
};
/**
* Yargs options included in every wrangler command.
*/
interface CommonYargsOptions {
v: boolean | undefined;
cwd: string | undefined;
config: string | undefined;
env: string | undefined;
"env-file": string[] | undefined;
"experimental-provision": boolean | undefined;
"experimental-auto-create": boolean;
}
type CommonYargsArgv = Argv<CommonYargsOptions>;
type RemoveIndex<T> = {
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
};
// Team names from https://wiki.cfdata.org/display/EW/Developer+Platform+Components+and+Pillar+Ownership
type Teams =
| "Workers: Onboarding & Integrations"
| "Workers: Builds and Automation"
| "Workers: Deploy and Config"
| "Workers: Authoring and Testing"
| "Workers: Frameworks and Runtime APIs"
| "Workers: Runtime Platform"
| "Workers: Workers Observability"
| "Product: KV"
| "Product: R2"
| "Product: R2 Data Catalog"
| "Product: R2 SQL"
| "Product: D1"
| "Product: Queues"
| "Product: AI"
| "Product: Hyperdrive"
| "Product: Pipelines"
| "Product: Vectorize"
| "Product: Workflows"
| "Product: Cloudchamber"
| "Product: SSL"
| "Product: WVPC";
/** Convert literal string types like 'foo-bar' to 'FooBar' */
type PascalCase<S extends string> = string extends S ? string : S extends `${infer T}-${infer U}` ? `${Capitalize<T>}${PascalCase<U>}` : Capitalize<S>;
/** Convert literal string types like 'foo-bar' to 'fooBar' */
type CamelCase<S extends string> = string extends S ? string : S extends `${infer T}-${infer U}` ? `${T}${PascalCase<U>}` : S;
type CamelCaseKey<K extends PropertyKey> = K extends string ? Exclude<CamelCase<K>, ""> : K;
type Alias<O extends Options | PositionalOptions> = O extends {
alias: infer T;
} ? T extends Exclude<string, T> ? {
[key in T]: InferredOptionType<O>;
} : {} : {};
type StringKeyOf<T> = Extract<keyof T, string>;
type DeepFlatten<T> = T extends object ? {
[K in keyof T]: DeepFlatten<T[K]>;
} : T;
type Command = `wrangler${string}`;
type Metadata = {
description: string;
status: "experimental" | "alpha" | "private-beta" | "open-beta" | "stable";
statusMessage?: string;
deprecated?: boolean;
deprecatedMessage?: string;
hidden?: boolean;
owner: Teams;
/** Prints something at the bottom of the help */
epilogue?: string;
examples?: {
command: string;
description: string;
}[];
hideGlobalFlags?: string[];
};
type ArgDefinition = Omit<PositionalOptions, "type"> & Pick<Options, "hidden" | "requiresArg" | "deprecated" | "type">;
type NamedArgDefinitions = {
[key: string]: ArgDefinition;
};
type OnlyCamelCase<T = Record<string, never>> = {
[key in keyof T as CamelCaseKey<key>]: T[key];
};
type HandlerArgs<Args extends NamedArgDefinitions> = DeepFlatten<OnlyCamelCase<RemoveIndex<ArgumentsCamelCase<CommonYargsOptions & InferredOptionTypes<Args> & Alias<Args>>>>>;
type HandlerContext = {
/**
* The wrangler config file read from disk and parsed.
*/
config: Config;
/**
* The logger instance provided to the command implementor as a convenience.
*/
logger: Logger;
/**
* Use fetchResult to make *auth'd* requests to the Cloudflare API.
*/
fetchResult: typeof fetchResult;
/**
* Error classes provided to the command implementor as a convenience
* to aid discoverability and to encourage their usage.
*/
errors: {
UserError: typeof UserError;
FatalError: typeof FatalError;
};
/**
* API SDK
*/
sdk: Cloudflare;
};
type CommandDefinition<NamedArgDefs extends NamedArgDefinitions = NamedArgDefinitions> = {
/**
* Descriptive information about the command which does not affect behaviour.
* This is used for the CLI --help and subcommand --help output.
* This should be used as the source-of-truth for status and ownership.
*/
metadata: Metadata;
/**
* Controls shared behaviour across all commands.
* This will allow wrangler commands to remain consistent and only diverge intentionally.
*/
behaviour?: {