Skip to content

Commit 065afe9

Browse files
feat(wrangler): Add remote mode support for Workers + Assets
1 parent 914290b commit 065afe9

File tree

5 files changed

+55
-47
lines changed

5 files changed

+55
-47
lines changed

packages/wrangler/src/__tests__/dev.test.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,18 +1733,6 @@ describe.sequential("wrangler dev", () => {
17331733
`[Error: Cannot use assets in remote mode. Workers with assets are only supported in local mode. Please use \`wrangler dev\`.]`
17341734
);
17351735
});
1736-
1737-
it("should error if config.assets and --remote are used together", async () => {
1738-
writeWranglerConfig({
1739-
assets: { directory: "./public" },
1740-
});
1741-
fs.mkdirSync("public");
1742-
await expect(
1743-
runWrangler("dev --remote")
1744-
).rejects.toThrowErrorMatchingInlineSnapshot(
1745-
`[Error: Cannot use assets in remote mode. Workers with assets are only supported in local mode. Please use \`wrangler dev\`.]`
1746-
);
1747-
});
17481736
});
17491737

17501738
describe("--inspect", () => {

packages/wrangler/src/api/startDevWorker/ConfigController.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,6 @@ async function resolveConfig(
308308
);
309309
}
310310

311-
if (resolved.assets && resolved.dev.remote) {
312-
throw new UserError(
313-
"Cannot use assets in remote mode. Workers with assets are only supported in local mode. Please use `wrangler dev`."
314-
);
315-
}
316-
317311
validateAssetsArgsAndConfig(resolved);
318312

319313
const services = extractBindingsOfType("service", resolved.bindings);

packages/wrangler/src/api/startDevWorker/RemoteRuntimeController.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import type {
3030
} from "./events";
3131
import type { Trigger } from "./types";
3232

33+
type CreateRemoteWorkerInitProps = Parameters<typeof createRemoteWorkerInit>[0];
34+
3335
export class RemoteRuntimeController extends RuntimeController {
3436
#abortController = new AbortController();
3537

@@ -60,40 +62,49 @@ export class RemoteRuntimeController extends RuntimeController {
6062
}
6163

6264
async #previewToken(
63-
props: Parameters<typeof createRemoteWorkerInit>[0] &
65+
props: Omit<CreateRemoteWorkerInitProps, "name"> &
66+
Partial<Pick<CreateRemoteWorkerInitProps, "name">> &
6467
Parameters<typeof getWorkerAccountAndContext>[0]
6568
): Promise<CfPreviewToken | undefined> {
69+
if (!this.#session) {
70+
return;
71+
}
72+
6673
try {
74+
const { workerAccount, workerContext } = await getWorkerAccountAndContext(
75+
{
76+
accountId: props.accountId,
77+
env: props.env,
78+
legacyEnv: props.legacyEnv,
79+
host: props.host,
80+
routes: props.routes,
81+
sendMetrics: props.sendMetrics,
82+
configPath: props.configPath,
83+
}
84+
);
85+
86+
const scriptId =
87+
props.name ||
88+
(workerContext.zone
89+
? this.#session.id
90+
: this.#session.host.split(".")[0]);
91+
6792
const init = await createRemoteWorkerInit({
6893
bundle: props.bundle,
6994
modules: props.modules,
7095
accountId: props.accountId,
71-
name: props.name,
96+
name: scriptId,
7297
legacyEnv: props.legacyEnv,
7398
env: props.env,
7499
isWorkersSite: props.isWorkersSite,
100+
assets: props.assets,
75101
legacyAssetPaths: props.legacyAssetPaths,
76102
format: props.format,
77103
bindings: props.bindings,
78104
compatibilityDate: props.compatibilityDate,
79105
compatibilityFlags: props.compatibilityFlags,
80106
});
81107

82-
const { workerAccount, workerContext } = await getWorkerAccountAndContext(
83-
{
84-
accountId: props.accountId,
85-
env: props.env,
86-
legacyEnv: props.legacyEnv,
87-
host: props.host,
88-
routes: props.routes,
89-
sendMetrics: props.sendMetrics,
90-
configPath: props.configPath,
91-
}
92-
);
93-
if (!this.#session) {
94-
return;
95-
}
96-
97108
const workerPreviewToken = await createWorkerPreview(
98109
init,
99110
workerAccount,
@@ -173,6 +184,7 @@ export class RemoteRuntimeController extends RuntimeController {
173184
legacyEnv: !config.legacy?.enableServiceEnvironments,
174185
env: config.env,
175186
isWorkersSite: config.legacy?.site !== undefined,
187+
assets: config.assets,
176188
legacyAssetPaths: config.legacy?.site?.bucket
177189
? {
178190
baseDirectory: config.legacy?.site?.bucket,

packages/wrangler/src/dev/create-worker-preview.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ import { logger } from "../logger";
77
import { ParseError, parseJSON } from "../parse";
88
import { getAccessToken } from "../user/access";
99
import { isAbortError } from "../utils/isAbortError";
10-
import type {
11-
CfWorkerContext,
12-
CfWorkerInit,
13-
} from "../deployment-bundle/worker";
10+
import type { CfWorkerContext } from "../deployment-bundle/worker";
1411
import type { ApiCredentials } from "../user";
12+
import type { CfWorkerInitWithName } from "./remote";
1513
import type { HeadersInit } from "undici";
1614

1715
/**
@@ -227,18 +225,17 @@ export async function createPreviewSession(
227225
*/
228226
async function createPreviewToken(
229227
account: CfAccount,
230-
worker: CfWorkerInit,
228+
worker: CfWorkerInitWithName,
231229
ctx: CfWorkerContext,
232230
session: CfPreviewSession,
233231
abortSignal: AbortSignal
234232
): Promise<CfPreviewToken> {
235233
const { value, host, inspectorUrl, prewarmUrl } = session;
236234
const { accountId } = account;
237-
const scriptId = worker.name || (ctx.zone ? session.id : host.split(".")[0]);
238235
const url =
239236
ctx.env && !ctx.legacyEnv
240-
? `/accounts/${accountId}/workers/services/${scriptId}/environments/${ctx.env}/edge-preview`
241-
: `/accounts/${accountId}/workers/scripts/${scriptId}/edge-preview`;
237+
? `/accounts/${accountId}/workers/services/${worker.name}/environments/${ctx.env}/edge-preview`
238+
: `/accounts/${accountId}/workers/scripts/${worker.name}/edge-preview`;
242239

243240
const mode: CfPreviewMode = ctx.zone
244241
? {
@@ -303,7 +300,7 @@ async function createPreviewToken(
303300
* const {value, host} = await createWorker(init, acct);
304301
*/
305302
export async function createWorkerPreview(
306-
init: CfWorkerInit,
303+
init: CfWorkerInitWithName,
307304
account: CfAccount,
308305
ctx: CfWorkerContext,
309306
session: CfPreviewSession,

packages/wrangler/src/dev/remote.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import assert from "node:assert";
22
import path from "node:path";
3+
import { syncAssets } from "../assets";
34
import { printBundleSize } from "../deployment-bundle/bundle-reporter";
45
import { getBundleType } from "../deployment-bundle/bundle-type";
56
import { withSourceURLs } from "../deployment-bundle/source-url";
@@ -10,6 +11,7 @@ import { syncLegacyAssets } from "../sites";
1011
import { requireApiToken } from "../user";
1112
import { isAbortError } from "../utils/isAbortError";
1213
import { getZoneIdForPreview } from "../zones";
14+
import type { AssetsOptions } from "../assets";
1315
import type { Route } from "../config/environment";
1416
import type {
1517
CfModule,
@@ -79,14 +81,18 @@ export function handlePreviewSessionCreationError(
7981
}
8082
}
8183

84+
export type CfWorkerInitWithName = Required<Pick<CfWorkerInit, "name">> &
85+
CfWorkerInit;
86+
8287
export async function createRemoteWorkerInit(props: {
8388
bundle: EsbuildBundle;
8489
modules: CfModule[];
8590
accountId: string;
86-
name: string | undefined;
91+
name: string;
8792
legacyEnv: boolean | undefined;
8893
env: string | undefined;
8994
isWorkersSite: boolean;
95+
assets: AssetsOptions | undefined;
9096
legacyAssetPaths: LegacyAssetPaths | undefined;
9197
format: CfScriptFormat;
9298
bindings: CfWorkerInit["bindings"];
@@ -130,7 +136,11 @@ export async function createRemoteWorkerInit(props: {
130136
});
131137
}
132138

133-
const init: CfWorkerInit = {
139+
const assetsJwt = props.assets
140+
? await syncAssets(props.accountId, props.name, props.assets.directory)
141+
: undefined;
142+
143+
const init: CfWorkerInitWithName = {
134144
name: props.name,
135145
main: {
136146
name: path.basename(props.bundle.path),
@@ -161,10 +171,17 @@ export async function createRemoteWorkerInit(props: {
161171
keepSecrets: true,
162172
logpush: false,
163173
sourceMaps: undefined,
174+
assets:
175+
props.assets && assetsJwt
176+
? {
177+
jwt: assetsJwt,
178+
routingConfig: props.assets.routingConfig,
179+
assetConfig: props.assets.assetConfig,
180+
}
181+
: undefined,
164182
placement: undefined, // no placement in dev
165183
tail_consumers: undefined, // no tail consumers in dev - TODO revisit?
166184
limits: undefined, // no limits in preview - not supported yet but can be added
167-
assets: undefined, // no remote mode for assets
168185
observability: undefined, // no observability in dev
169186
};
170187

0 commit comments

Comments
 (0)