Skip to content

Commit 046b17d

Browse files
feat: dev+envs (#532)
This implements service environments + `wrangler dev`. Fairly simple, it just needed the right url when creating the edge preview token. I tested this by publishing a service under one env, adding secrets under it in the dashboard, and then trying to dev under another env, and verifying that the secrets didn't leak.
1 parent 9d7e946 commit 046b17d

File tree

6 files changed

+69
-24
lines changed

6 files changed

+69
-24
lines changed

.changeset/healthy-bugs-reply.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
feat: dev+envs
6+
7+
This implements service environments + `wrangler dev`. Fairly simple, it just needed the right url when creating the edge preview token.
8+
9+
I tested this by publishing a service under one env, adding secrets under it in the dashboard, and then trying to dev under another env, and verifying that the secrets didn't leak.

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ function renderDev({
8282
usageModel,
8383
buildCommand = {},
8484
enableLocalPersistence = false,
85-
env = undefined,
85+
env,
86+
zone,
8687
}: Partial<DevProps>) {
8788
return render(
8889
<Dev
@@ -106,6 +107,7 @@ function renderDev({
106107
usageModel={usageModel}
107108
bindings={bindings}
108109
enableLocalPersistence={enableLocalPersistence}
110+
zone={zone}
109111
/>
110112
);
111113
}

packages/wrangler/src/api/preview.ts

+32-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { URL } from "node:url";
22
import { fetch } from "undici";
33
import { fetchResult } from "../cfetch";
44
import { toFormData } from "./form_data";
5-
import type { CfAccount, CfWorkerInit } from "./worker";
5+
import type { CfAccount, CfWorkerContext, CfWorkerInit } from "./worker";
66

77
/**
88
* A preview mode.
@@ -55,10 +55,13 @@ export interface CfPreviewToken {
5555
/**
5656
* Generates a preview session token.
5757
*/
58-
async function sessionToken(account: CfAccount): Promise<CfPreviewToken> {
59-
const { accountId, zoneId } = account;
60-
const initUrl = zoneId
61-
? `/zones/${zoneId}/workers/edge-preview`
58+
async function sessionToken(
59+
account: CfAccount,
60+
ctx: CfWorkerContext
61+
): Promise<CfPreviewToken> {
62+
const { accountId } = account;
63+
const initUrl = ctx.zone
64+
? `/zones/${ctx.zone}/workers/edge-preview`
6265
: `/accounts/${accountId}/workers/subdomain/edge-preview`;
6366

6467
const { exchange_url } = await fetchResult<{ exchange_url: string }>(initUrl);
@@ -92,15 +95,22 @@ function randomId(): string {
9295
*/
9396
export async function previewToken(
9497
account: CfAccount,
95-
worker: CfWorkerInit
98+
worker: CfWorkerInit,
99+
ctx: CfWorkerContext
96100
): Promise<CfPreviewToken> {
97-
const { value, host, inspectorUrl, prewarmUrl } = await sessionToken(account);
101+
const { value, host, inspectorUrl, prewarmUrl } = await sessionToken(
102+
account,
103+
ctx
104+
);
98105

99-
const { accountId, zoneId } = account;
100-
const scriptId = zoneId ? randomId() : worker.name || host.split(".")[0];
101-
const url = `/accounts/${accountId}/workers/scripts/${scriptId}/edge-preview`;
106+
const { accountId } = account;
107+
const scriptId = ctx.zone ? randomId() : worker.name || host.split(".")[0];
108+
const url =
109+
ctx.env && !ctx.legacyEnv
110+
? `/accounts/${accountId}/workers/services/${scriptId}/environments/${ctx.env}/edge-preview`
111+
: `/accounts/${accountId}/workers/scripts/${scriptId}/edge-preview`;
102112

103-
const mode: CfPreviewMode = zoneId
113+
const mode: CfPreviewMode = ctx.zone
104114
? { routes: ["*/*"] }
105115
: { workers_dev: true };
106116

@@ -119,8 +129,17 @@ export async function previewToken(
119129
value: preview_token,
120130
// TODO: verify this works with zoned workers
121131
host:
122-
worker.name && !zoneId
123-
? `${worker.name}.${host.split(".").slice(1).join(".")}`
132+
worker.name && !ctx.zone
133+
? // hrmm this might need change as well
134+
`${
135+
worker.name
136+
// TODO: this should also probably have the env prefix
137+
// but it doesn't appear to work yet, instead giving us the
138+
// "There is nothing here yet" screen
139+
// ctx.env && !ctx.legacyEnv
140+
// ? `${ctx.env}.${worker.name}`
141+
// : worker.name
142+
}.${host.split(".").slice(1).join(".")}`
124143
: host,
125144
inspectorUrl,
126145
prewarmUrl,

packages/wrangler/src/api/worker.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ export interface CfAccount {
1616
* An account ID.
1717
*/
1818
accountId: string;
19-
/**
20-
* A zone ID, only required if not using `workers.dev`.
21-
*/
22-
zoneId?: string;
2319
}
2420

2521
/**
@@ -164,6 +160,12 @@ export interface CfWorkerInit {
164160
usage_model: undefined | "bundled" | "unbound";
165161
}
166162

163+
export interface CfWorkerContext {
164+
env: string | undefined;
165+
legacyEnv: boolean | undefined;
166+
zone: string | undefined;
167+
}
168+
167169
/**
168170
* A stub to create a Cloudflare Worker preview.
169171
*
@@ -172,9 +174,10 @@ export interface CfWorkerInit {
172174
*/
173175
export async function createWorker(
174176
init: CfWorkerInit,
175-
account: CfAccount
177+
account: CfAccount,
178+
ctx: CfWorkerContext
176179
): Promise<CfPreviewToken> {
177-
const token = await previewToken(account, init);
180+
const token = await previewToken(account, init, ctx);
178181
const response = await fetch(token.prewarmUrl.href, { method: "POST" });
179182
if (!response.ok) {
180183
// console.error("worker failed to prewarm: ", response.statusText);

packages/wrangler/src/dev.tsx

+14-4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export type DevProps = {
5656
};
5757
env: string | undefined;
5858
legacyEnv: boolean;
59+
zone: string | undefined;
5960
};
6061

6162
function Dev(props: DevProps): JSX.Element {
@@ -142,6 +143,7 @@ function Dev(props: DevProps): JSX.Element {
142143
usageModel={props.usageModel}
143144
env={props.env}
144145
legacyEnv={props.legacyEnv}
146+
zone={props.zone}
145147
/>
146148
)}
147149
<Box borderStyle="round" paddingLeft={1} paddingRight={1}>
@@ -192,6 +194,7 @@ function Remote(props: {
192194
usageModel: undefined | "bundled" | "unbound";
193195
env: string | undefined;
194196
legacyEnv: boolean | undefined;
197+
zone: string | undefined;
195198
}) {
196199
assert(props.accountId, "accountId is required");
197200
assert(props.apiToken, "apiToken is required");
@@ -210,6 +213,7 @@ function Remote(props: {
210213
usageModel: props.usageModel,
211214
env: props.env,
212215
legacyEnv: props.legacyEnv,
216+
zone: props.zone,
213217
});
214218

215219
usePreviewServer({
@@ -685,6 +689,7 @@ function useWorker(props: {
685689
usageModel: undefined | "bundled" | "unbound";
686690
env: string | undefined;
687691
legacyEnv: boolean | undefined;
692+
zone: string | undefined;
688693
}): CfPreviewToken | undefined {
689694
const {
690695
name,
@@ -769,10 +774,14 @@ function useWorker(props: {
769774
usage_model: usageModel,
770775
};
771776
setToken(
772-
await createWorker(init, {
773-
accountId,
774-
apiToken,
775-
})
777+
await createWorker(
778+
init,
779+
{
780+
accountId,
781+
apiToken,
782+
},
783+
{ env: props.env, legacyEnv: props.legacyEnv, zone: props.zone }
784+
)
776785
);
777786
}
778787
start().catch((err) => {
@@ -795,6 +804,7 @@ function useWorker(props: {
795804
modules,
796805
props.env,
797806
props.legacyEnv,
807+
props.zone,
798808
]);
799809
return token;
800810
}

packages/wrangler/src/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ export async function main(argv: string[]): Promise<void> {
707707
name={getScriptName(args, config)}
708708
entry={entry}
709709
env={args.env}
710+
zone={undefined}
710711
rules={getRules(config)}
711712
legacyEnv={isLegacyEnv(args, config)}
712713
buildCommand={config.build || {}}
@@ -1151,6 +1152,7 @@ export async function main(argv: string[]): Promise<void> {
11511152
entry={entry}
11521153
rules={getRules(config)}
11531154
env={args.env}
1155+
zone={undefined}
11541156
legacyEnv={isLegacyEnv(args, config)}
11551157
buildCommand={config.build || {}}
11561158
format={config.build?.upload?.format}

0 commit comments

Comments
 (0)