Skip to content

Commit

Permalink
feat(wrangler): add inherit bindings support
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Nov 28, 2024
1 parent 73be975 commit 98006ca
Show file tree
Hide file tree
Showing 15 changed files with 234 additions and 186 deletions.
40 changes: 5 additions & 35 deletions packages/wrangler/src/api/pages/create-worker-bundle-contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { readFileSync } from "node:fs";
import path from "node:path";
import { Response } from "undici";
import { createWorkerUploadForm } from "../../deployment-bundle/create-worker-upload-form";
import { getBindings } from "../../deployment-bundle/provision";
import { loadSourceMaps } from "../../deployment-bundle/source-maps";
import type { Config } from "../../config";
import type { BundleResult } from "../../deployment-bundle/bundle";
import type { CfPlacement, CfWorkerInit } from "../../deployment-bundle/worker";
import type { CfPlacement } from "../../deployment-bundle/worker";
import type { Blob } from "node:buffer";
import type { FormData } from "undici";

Expand Down Expand Up @@ -44,46 +45,17 @@ function createWorkerBundleFormData(
type: workerBundle.bundleType || "esm",
};

const bindings: CfWorkerInit["bindings"] = {
kv_namespaces: config?.kv_namespaces,
vars: config?.vars,
browser: config?.browser,
ai: config?.ai,
version_metadata: config?.version_metadata,
durable_objects: config?.durable_objects,
workflows: config?.workflows,
queues: config?.queues.producers?.map((producer) => {
return { binding: producer.binding, queue_name: producer.queue };
}),
r2_buckets: config?.r2_buckets,
d1_databases: config?.d1_databases,
vectorize: config?.vectorize,
hyperdrive: config?.hyperdrive,
services: config?.services,
analytics_engine_datasets: config?.analytics_engine_datasets,
mtls_certificates: config?.mtls_certificates,
send_email: undefined,
wasm_modules: undefined,
text_blobs: undefined,
data_blobs: undefined,
dispatch_namespaces: undefined,
pipelines: undefined,
logfwdr: undefined,
unsafe: undefined,
assets: undefined,
};

// The upload API only accepts an empty string or no specified placement for the "off" mode.
const placement: CfPlacement | undefined =
config?.placement?.mode === "smart"
? { mode: "smart", hint: config.placement.hint }
: undefined;

const worker: CfWorkerInit = {
return createWorkerUploadForm({
name: mainModule.name,
main: mainModule,
modules: workerBundle.modules,
bindings,
bindings: getBindings(config, { pages: true }),
migrations: undefined,
compatibility_date: config?.compatibility_date,
compatibility_flags: config?.compatibility_flags,
Expand All @@ -99,7 +71,5 @@ function createWorkerBundleFormData(
limits: config?.limits,
assets: undefined,
observability: undefined,
};

return createWorkerUploadForm(worker);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ export class RemoteRuntimeController extends RuntimeController {
configPath: config.config,
});

const bindings = (
await convertBindingsToCfWorkerInitBindings(config.bindings)
).bindings;

const { bindings } = await convertBindingsToCfWorkerInitBindings(
config.bindings,
true
);
const token = await this.#previewToken({
bundle,
modules: bundle.modules,
Expand Down
33 changes: 32 additions & 1 deletion packages/wrangler/src/api/startDevWorker/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from "node:assert";
import { readFile } from "node:fs/promises";
import { UserError } from "../../errors";
import type { CfWorkerInit } from "../../deployment-bundle/worker";
import type {
AsyncHook,
Expand Down Expand Up @@ -252,7 +253,22 @@ export function convertCfWorkerInitBindingstoBindings(
}

export async function convertBindingsToCfWorkerInitBindings(
inputBindings: StartDevWorkerOptions["bindings"]
inputBindings: StartDevWorkerOptions["bindings"],
remote: true
): Promise<{
bindings: CfWorkerInit<string>["bindings"];
fetchers: Record<string, ServiceFetch>;
}>;
export async function convertBindingsToCfWorkerInitBindings(
inputBindings: StartDevWorkerOptions["bindings"],
remote?: false | undefined
): Promise<{
bindings: CfWorkerInit<string | undefined>["bindings"];
fetchers: Record<string, ServiceFetch>;
}>;
export async function convertBindingsToCfWorkerInitBindings(
inputBindings: StartDevWorkerOptions["bindings"],
remote?: boolean
): Promise<{
bindings: CfWorkerInit["bindings"];
fetchers: Record<string, ServiceFetch>;
Expand Down Expand Up @@ -294,6 +310,11 @@ export async function convertBindingsToCfWorkerInitBindings(
bindings.vars ??= {};
bindings.vars[name] = binding.value;
} else if (binding.type === "kv_namespace") {
if (remote && binding.id === undefined) {
throw new UserError(
`${name} bindings must have an "id" field when running remotely`
);
}
bindings.kv_namespaces ??= [];
bindings.kv_namespaces.push({ ...binding, binding: name });
} else if (binding.type === "send_email") {
Expand Down Expand Up @@ -329,9 +350,19 @@ export async function convertBindingsToCfWorkerInitBindings(
bindings.queues ??= [];
bindings.queues.push({ ...binding, binding: name });
} else if (binding.type === "r2_bucket") {
if (remote && binding.bucket_name === undefined) {
throw new UserError(
`${name} bindings must have an "bucket_name" field when running remotely`
);
}
bindings.r2_buckets ??= [];
bindings.r2_buckets.push({ ...binding, binding: name });
} else if (binding.type === "d1") {
if (remote && binding.database_id === undefined) {
throw new UserError(
`${name} bindings must have an "database_id" field when running remotely`
);
}
bindings.d1_databases ??= [];
bindings.d1_databases.push({ ...binding, binding: name });
} else if (binding.type === "vectorize") {
Expand Down
4 changes: 2 additions & 2 deletions packages/wrangler/src/config/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ export interface EnvironmentNonInheritable {
/** The binding name used to refer to the KV Namespace */
binding: string;
/** The ID of the KV namespace */
id?: string;
id: string | undefined;
/** The ID of the KV namespace used during `wrangler dev` */
preview_id?: string;
}[];
Expand Down Expand Up @@ -565,7 +565,7 @@ export interface EnvironmentNonInheritable {
/** The binding name used to refer to the R2 bucket in the Worker. */
binding: string;
/** The name of this R2 bucket at the edge. */
bucket_name?: string;
bucket_name: string | undefined;
/** The preview name of this R2 bucket at the edge. */
preview_bucket_name?: string;
/** The jurisdiction that the bucket exists in. Default if not present. */
Expand Down
24 changes: 16 additions & 8 deletions packages/wrangler/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,11 @@ export function findWranglerConfig(
);
}

function addLocalSuffix(id: string | undefined, local: boolean = false) {
if (!id) {
function addLocalSuffix(
id: string | symbol | undefined,
local: boolean = false
) {
if (!id || typeof id === "symbol") {
return local ? "(local)" : "(remote)";
}

Expand Down Expand Up @@ -249,7 +252,7 @@ export const friendlyBindingNames: Record<
* Print all the bindings a worker using a given config would have access to
*/
export function printBindings(
bindings: CfWorkerInit["bindings"],
bindings: CfWorkerInit<string | symbol | undefined>["bindings"],
context: {
registry?: WorkerRegistry;
local?: boolean;
Expand Down Expand Up @@ -405,10 +408,12 @@ export function printBindings(
name: friendlyBindingNames.d1_databases,
entries: d1_databases.map(
({ binding, database_name, database_id, preview_database_id }) => {
const remoteDatabaseId =
typeof database_id === "string" ? database_id : null;
let databaseValue =
database_id && database_name
? `${database_name} (${database_id})`
: database_id ?? database_name;
remoteDatabaseId && database_name
? `${database_name} (${remoteDatabaseId})`
: remoteDatabaseId ?? database_name;

//database_id is local when running `wrangler dev --local`
if (preview_database_id && database_id !== "local") {
Expand Down Expand Up @@ -451,12 +456,15 @@ export function printBindings(
output.push({
name: friendlyBindingNames.r2_buckets,
entries: r2_buckets.map(({ binding, bucket_name, jurisdiction }) => {
let name = typeof bucket_name === "string" ? bucket_name : "";

if (jurisdiction !== undefined) {
bucket_name += ` (${jurisdiction})`;
name += ` (${jurisdiction})`;
}

return {
key: binding,
value: addLocalSuffix(bucket_name, context.local),
value: addLocalSuffix(name, context.local),
};
}),
});
Expand Down
40 changes: 7 additions & 33 deletions packages/wrangler/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
getWrangler1xLegacyModuleReferences,
} from "../deployment-bundle/module-collection";
import { validateNodeCompatMode } from "../deployment-bundle/node-compat";
import { getBindings } from "../deployment-bundle/provision";
import { loadSourceMaps } from "../deployment-bundle/source-maps";
import { confirm } from "../dialogs";
import { getMigrationsToUpload } from "../durable";
Expand Down Expand Up @@ -63,6 +64,7 @@ import type {
ZoneNameRoute,
} from "../config/environment";
import type { Entry } from "../deployment-bundle/entry";
import type { INHERIT_SYMBOL } from "../deployment-bundle/provision";
import type {
CfModule,
CfPlacement,
Expand Down Expand Up @@ -665,50 +667,22 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
props.oldAssetTtl
);

const bindings: CfWorkerInit["bindings"] = {
kv_namespaces: (config.kv_namespaces || []).concat(
const bindings = getBindings({
...config,
kv_namespaces: config.kv_namespaces.concat(
legacyAssets.namespace
? { binding: "__STATIC_CONTENT", id: legacyAssets.namespace }
: []
),
send_email: config.send_email,
vars: { ...config.vars, ...props.vars },
wasm_modules: config.wasm_modules,
browser: config.browser,
ai: config.ai,
version_metadata: config.version_metadata,
text_blobs: {
...config.text_blobs,
...(legacyAssets.manifest &&
format === "service-worker" && {
__STATIC_CONTENT_MANIFEST: "__STATIC_CONTENT_MANIFEST",
}),
},
data_blobs: config.data_blobs,
durable_objects: config.durable_objects,
workflows: config.workflows,
queues: config.queues.producers?.map((producer) => {
return { binding: producer.binding, queue_name: producer.queue };
}),
r2_buckets: config.r2_buckets,
d1_databases: config.d1_databases,
vectorize: config.vectorize,
hyperdrive: config.hyperdrive,
services: config.services,
analytics_engine_datasets: config.analytics_engine_datasets,
dispatch_namespaces: config.dispatch_namespaces,
mtls_certificates: config.mtls_certificates,
pipelines: config.pipelines,
logfwdr: config.logfwdr,
assets: config.assets?.binding
? { binding: config.assets.binding }
: undefined,
unsafe: {
bindings: config.unsafe.bindings,
metadata: config.unsafe.metadata,
capnp: config.unsafe.capnp,
},
};
});

if (legacyAssets.manifest) {
modules.push({
Expand All @@ -732,7 +706,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
content: content,
type: bundleType,
};
const worker: CfWorkerInit = {
const worker: CfWorkerInit<string | typeof INHERIT_SYMBOL> = {
name: scriptName,
main,
bindings,
Expand Down
Loading

0 comments on commit 98006ca

Please sign in to comment.