wrangler 0.0.0-e1c615f → 0.0.0-e6733a3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/pages.tsx CHANGED
@@ -4,7 +4,7 @@ import assert from "assert";
4
4
  import type { BuilderCallback } from "yargs";
5
5
  import { join } from "path";
6
6
  import { tmpdir } from "os";
7
- import { existsSync, lstatSync, readFileSync } from "fs";
7
+ import { existsSync, lstatSync, readFileSync, writeFileSync } from "fs";
8
8
  import { execSync, spawn } from "child_process";
9
9
  import { URL } from "url";
10
10
  import { getType } from "mime";
@@ -642,16 +642,20 @@ const RUNNING_BUILDERS: BuildResult[] = [];
642
642
 
643
643
  async function buildFunctions({
644
644
  scriptPath,
645
+ outputConfigPath,
645
646
  functionsDirectory,
646
647
  minify = false,
647
648
  sourcemap = false,
649
+ fallbackService = "ASSETS",
648
650
  watch = false,
649
651
  onEnd,
650
652
  }: {
651
653
  scriptPath: string;
654
+ outputConfigPath?: string;
652
655
  functionsDirectory: string;
653
656
  minify?: boolean;
654
657
  sourcemap?: boolean;
658
+ fallbackService?: string;
655
659
  watch?: boolean;
656
660
  onEnd?: () => void;
657
661
  }) {
@@ -666,6 +670,13 @@ async function buildFunctions({
666
670
  baseURL: "/",
667
671
  });
668
672
 
673
+ if (outputConfigPath) {
674
+ writeFileSync(
675
+ outputConfigPath,
676
+ JSON.stringify({ ...config, baseURL: "/" }, null, 2)
677
+ );
678
+ }
679
+
669
680
  await writeRoutesModule({
670
681
  config,
671
682
  srcDir: functionsDirectory,
@@ -678,6 +689,7 @@ async function buildFunctions({
678
689
  outfile: scriptPath,
679
690
  minify,
680
691
  sourcemap,
692
+ fallbackService,
681
693
  watch,
682
694
  onEnd,
683
695
  })
@@ -738,6 +750,11 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
738
750
  description: "Durable Object to bind (NAME=CLASS)",
739
751
  alias: "o",
740
752
  },
753
+ "live-reload": {
754
+ type: "boolean",
755
+ default: false,
756
+ description: "Auto reload HTML pages when change is detected",
757
+ },
741
758
  // TODO: Miniflare user options
742
759
  });
743
760
  },
@@ -750,6 +767,7 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
750
767
  binding: bindings = [],
751
768
  kv: kvs = [],
752
769
  do: durableObjects = [],
770
+ "live-reload": liveReload,
753
771
  "--": remaining = [],
754
772
  }) => {
755
773
  if (!local) {
@@ -774,7 +792,10 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
774
792
 
775
793
  let miniflareArgs: MiniflareOptions = {};
776
794
 
777
- let scriptReady = true;
795
+ let scriptReadyResolve;
796
+ const scriptReadyPromise = new Promise(
797
+ (resolve) => (scriptReadyResolve = resolve)
798
+ );
778
799
 
779
800
  if (usingFunctions) {
780
801
  const scriptPath = join(tmpdir(), "./functionsWorker.js");
@@ -786,22 +807,19 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
786
807
  functionsDirectory,
787
808
  sourcemap: true,
788
809
  watch: true,
789
- onEnd: () => {
790
- scriptReady = true;
791
- },
810
+ onEnd: () => scriptReadyResolve(),
792
811
  });
793
812
 
794
813
  watch([functionsDirectory], {
795
814
  persistent: true,
815
+ ignoreInitial: true,
796
816
  }).on("all", async () => {
797
817
  await buildFunctions({
798
818
  scriptPath,
799
819
  functionsDirectory,
800
820
  sourcemap: true,
801
821
  watch: true,
802
- onEnd: () => {
803
- scriptReady = true;
804
- },
822
+ onEnd: () => scriptReadyResolve(),
805
823
  });
806
824
  });
807
825
 
@@ -838,6 +856,12 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
838
856
  const { Miniflare, Log, LogLevel } = await import("miniflare");
839
857
  const { Response, fetch } = await import("@miniflare/core");
840
858
 
859
+ // Wait for esbuild to finish building before starting Miniflare.
860
+ // This must be before the call to `new Miniflare`, as that will
861
+ // asynchronously start loading the script. `await startServer()`
862
+ // internally just waits for that promise to resolve.
863
+ await scriptReadyPromise;
864
+
841
865
  // Should only be called if no proxyPort, using `assert.fail()` here
842
866
  // means the type of `assetsFetch` is still `typeof fetch`
843
867
  const assetsFetch = proxyPort
@@ -903,13 +927,11 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
903
927
  kvPersist: true,
904
928
  durableObjectsPersist: true,
905
929
  cachePersist: true,
930
+ liveReload,
906
931
 
907
932
  ...miniflareArgs,
908
933
  });
909
934
 
910
- // Wait for esbuild to finish building the script
911
- while (!scriptReady) {}
912
-
913
935
  try {
914
936
  // `startServer` might throw if user code contains errors
915
937
  const server = await miniflare.startServer();
@@ -921,6 +943,15 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
921
943
  } catch {}
922
944
  }
923
945
 
946
+ if (directory !== undefined && liveReload) {
947
+ watch([directory], {
948
+ persistent: true,
949
+ ignoreInitial: true,
950
+ }).on("all", async () => {
951
+ await miniflare.reload();
952
+ });
953
+ }
954
+
924
955
  EXIT_CALLBACKS.push(() => {
925
956
  server.close();
926
957
  miniflare.dispose().catch((err) => miniflare.log.error(err));
@@ -933,34 +964,66 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
933
964
  )
934
965
  .command("functions", "Cloudflare Pages Functions", (yargs) =>
935
966
  yargs.command(
936
- "build",
967
+ "build [directory]",
937
968
  "Compile a folder of Cloudflare Pages Functions into a single Worker",
938
969
  (yargs) =>
939
- yargs.options({
940
- "script-path": {
970
+ yargs
971
+ .positional("directory", {
941
972
  type: "string",
942
- default: "_worker.js",
943
- description: "The location of the output Worker script",
944
- },
945
- minify: {
946
- type: "boolean",
947
- default: false,
948
- description: "Minify the output Worker script",
949
- },
950
- sourcemap: {
951
- type: "boolean",
952
- default: false,
953
- description: "Generate a sourcemap for the output Worker script",
954
- },
955
- }),
956
- async ({ "script-path": scriptPath, minify, sourcemap }) => {
957
- const functionsDirectory = "./functions";
958
-
973
+ default: "functions",
974
+ description: "The directory of Pages Functions",
975
+ })
976
+ .options({
977
+ "script-path": {
978
+ type: "string",
979
+ default: "_worker.js",
980
+ description: "The location of the output Worker script",
981
+ },
982
+ "output-config-path": {
983
+ type: "string",
984
+ description: "The location for the output config file",
985
+ },
986
+ minify: {
987
+ type: "boolean",
988
+ default: false,
989
+ description: "Minify the output Worker script",
990
+ },
991
+ sourcemap: {
992
+ type: "boolean",
993
+ default: false,
994
+ description:
995
+ "Generate a sourcemap for the output Worker script",
996
+ },
997
+ "fallback-service": {
998
+ type: "string",
999
+ default: "ASSETS",
1000
+ description:
1001
+ "The service to fallback to at the end of the `next` chain. Setting to '' will fallback to the global `fetch`.",
1002
+ },
1003
+ watch: {
1004
+ type: "boolean",
1005
+ default: false,
1006
+ description:
1007
+ "Watch for changes to the functions and automatically rebuild the Worker script",
1008
+ },
1009
+ }),
1010
+ async ({
1011
+ directory,
1012
+ "script-path": scriptPath,
1013
+ "output-config-path": outputConfigPath,
1014
+ minify,
1015
+ sourcemap,
1016
+ fallbackService,
1017
+ watch,
1018
+ }) => {
959
1019
  await buildFunctions({
960
1020
  scriptPath,
961
- functionsDirectory,
1021
+ outputConfigPath,
1022
+ functionsDirectory: directory,
962
1023
  minify,
963
1024
  sourcemap,
1025
+ fallbackService,
1026
+ watch,
964
1027
  });
965
1028
  }
966
1029
  )
package/src/proxy.ts CHANGED
@@ -1,97 +1,288 @@
1
1
  import { connect } from "node:http2";
2
+ import type { ServerHttp2Stream } from "node:http2";
2
3
  import { createServer } from "node:http";
3
- import type { Server, IncomingHttpHeaders, RequestListener } from "node:http";
4
+ import type {
5
+ IncomingHttpHeaders,
6
+ RequestListener,
7
+ IncomingMessage,
8
+ ServerResponse,
9
+ Server,
10
+ } from "node:http";
4
11
  import WebSocket from "faye-websocket";
5
12
  import serveStatic from "serve-static";
13
+ import type { CfPreviewToken } from "./api/preview";
14
+ import { useEffect, useRef } from "react";
6
15
 
7
- export interface HttpProxyInit {
8
- host: string;
9
- assetPath?: string | null;
10
- onRequest?: (headers: IncomingHttpHeaders) => void;
11
- onResponse?: (headers: IncomingHttpHeaders) => void;
16
+ /**
17
+ * `usePreviewServer` is a React hook that creates a local development
18
+ * server that can be used to develop a Worker.
19
+ *
20
+ * When we run `wrangler dev`, we start by uploading the compiled worker
21
+ * to the preview service, which responds with a preview token.
22
+ * (see `useWorker`/`createWorker` for details.)
23
+ * We can then use that token to connect to the preview server for a
24
+ * great local development experience. Further, as we change the worker,
25
+ * we can update the preview token transparently without having to restart
26
+ * the development server.
27
+ */
28
+
29
+ /** Rewrite request headers to add the preview token. */
30
+ function addCfPreviewTokenHeader(
31
+ headers: IncomingHttpHeaders,
32
+ previewTokenValue: string
33
+ ) {
34
+ headers["cf-workers-preview-token"] = previewTokenValue;
12
35
  }
13
36
 
14
37
  /**
15
- * Creates a HTTP/1 proxy that sends requests over HTTP/2.
38
+ * Rewrite references in request headers
39
+ * from the preview host to the local host.
16
40
  */
17
- export function createHttpProxy(init: HttpProxyInit): Server {
18
- const { host, assetPath, onRequest = () => {}, onResponse = () => {} } = init;
19
- const remote = connect(`https://${host}`);
20
- const local = createServer();
21
- // HTTP/2 -> HTTP/2
22
- local.on("stream", (stream, headers: IncomingHttpHeaders) => {
23
- onRequest(headers);
24
- headers[":authority"] = host;
25
- const request = stream.pipe(remote.request(headers));
26
- request.on("response", (responseHeaders: IncomingHttpHeaders) => {
27
- onResponse(responseHeaders);
28
- stream.respond(responseHeaders);
29
- request.pipe(stream, { end: true });
30
- });
31
- });
32
- // HTTP/1 -> HTTP/2
33
- const handleRequest: RequestListener = (message, response) => {
34
- const { httpVersionMajor, headers, method, url } = message;
35
- if (httpVersionMajor >= 2) {
36
- return; // Already handled by the "stream" event.
41
+ function rewriteRemoteHostToLocalHostInHeaders(
42
+ headers: IncomingHttpHeaders,
43
+ remoteHost: string,
44
+ localPort: number
45
+ ) {
46
+ for (const [name, value] of Object.entries(headers)) {
47
+ // Rewrite the remote host to the local host.
48
+ if (typeof value === "string" && value.includes(remoteHost)) {
49
+ headers[name] = value
50
+ .replaceAll(`https://${remoteHost}`, `http://localhost:${localPort}`)
51
+ .replaceAll(remoteHost, `localhost:${localPort}`);
37
52
  }
38
- onRequest(headers);
39
- headers[":method"] = method;
40
- headers[":path"] = url;
41
- headers[":authority"] = host;
42
- headers[":scheme"] = "https";
43
- for (const name of Object.keys(headers)) {
44
- if (HTTP1_HEADERS.has(name.toLowerCase())) {
45
- delete headers[name];
46
- }
53
+ }
54
+ }
55
+
56
+ export function usePreviewServer({
57
+ previewToken,
58
+ publicRoot,
59
+ port,
60
+ }: {
61
+ previewToken: CfPreviewToken | undefined;
62
+ publicRoot: undefined | string;
63
+ port: number;
64
+ }) {
65
+ /** Creates an HTTP/1 proxy that sends requests over HTTP/2. */
66
+ const proxyServer = useRef<Server>();
67
+ if (!proxyServer.current) {
68
+ proxyServer.current = createServer()
69
+ .on("request", function (req, res) {
70
+ // log all requests
71
+ console.log(
72
+ new Date().toLocaleTimeString(),
73
+ req.method,
74
+ req.url,
75
+ res.statusCode
76
+ );
77
+ })
78
+ .on("upgrade", (req) => {
79
+ // log all websocket connections
80
+ console.log(
81
+ new Date().toLocaleTimeString(),
82
+ req.method,
83
+ req.url,
84
+ 101,
85
+ "(WebSocket)"
86
+ );
87
+ })
88
+ .on("error", (err) => {
89
+ // log all connection errors
90
+ console.error(new Date().toLocaleTimeString(), err);
91
+ });
92
+ }
93
+
94
+ /**
95
+ * When we're not connected / getting a fresh token on changes,
96
+ * we'd like to buffer streams/requests until we're connected.
97
+ * Once connected, we can flush the buffered streams/requests.
98
+ * streamBufferRef is used to buffer http/2 streams, while
99
+ * requestResponseBufferRef is used to buffer http/1 requests.
100
+ */
101
+ const streamBufferRef = useRef<
102
+ { stream: ServerHttp2Stream; headers: IncomingHttpHeaders }[]
103
+ >([]);
104
+ const requestResponseBufferRef = useRef<
105
+ { request: IncomingMessage; response: ServerResponse }[]
106
+ >([]);
107
+
108
+ useEffect(() => {
109
+ const proxy = proxyServer.current;
110
+
111
+ // If we don't have a token, that means either we're just starting up,
112
+ // or we're refreshing the token.
113
+ if (!previewToken) {
114
+ const cleanupListeners: (() => void)[] = [];
115
+ const bufferStream = (
116
+ stream: ServerHttp2Stream,
117
+ headers: IncomingHttpHeaders
118
+ ) => {
119
+ // store the stream in a buffer so we can replay it later
120
+ streamBufferRef.current.push({ stream, headers });
121
+ };
122
+ proxy.on("stream", bufferStream);
123
+ cleanupListeners.push(() => proxy.off("stream", bufferStream));
124
+
125
+ const bufferRequestResponse = (
126
+ request: IncomingMessage,
127
+ response: ServerResponse
128
+ ) => {
129
+ // store the request and response in a buffer so we can replay it later
130
+ requestResponseBufferRef.current.push({ request, response });
131
+ };
132
+
133
+ proxy.on("request", bufferRequestResponse);
134
+ cleanupListeners.push(() => proxy.off("request", bufferRequestResponse));
135
+ return () => {
136
+ cleanupListeners.forEach((cleanup) => cleanup());
137
+ };
47
138
  }
48
- const request = message.pipe(remote.request(headers));
49
- request.on("response", (responseHeaders) => {
50
- const status = responseHeaders[":status"];
51
- onResponse(responseHeaders);
52
- for (const name of Object.keys(responseHeaders)) {
53
- if (name.startsWith(":")) {
54
- delete responseHeaders[name];
139
+
140
+ // We have a token. Let's proxy requests to the preview end point.
141
+ const cleanupListeners: (() => void)[] = [];
142
+
143
+ const assetPath = typeof publicRoot === "string" ? publicRoot : null;
144
+
145
+ // create a ClientHttp2Session
146
+ const remote = connect(`https://${previewToken.host}`);
147
+ cleanupListeners.push(() => remote.destroy());
148
+
149
+ /** HTTP/2 -> HTTP/2 */
150
+ function handleStream(
151
+ stream: ServerHttp2Stream,
152
+ headers: IncomingHttpHeaders
153
+ ) {
154
+ addCfPreviewTokenHeader(headers, previewToken.value);
155
+ headers[":authority"] = previewToken.host;
156
+ const request = stream.pipe(remote.request(headers));
157
+ request.on("response", (responseHeaders: IncomingHttpHeaders) => {
158
+ rewriteRemoteHostToLocalHostInHeaders(
159
+ responseHeaders,
160
+ previewToken.host,
161
+ port
162
+ );
163
+ stream.respond(responseHeaders);
164
+ request.pipe(stream, { end: true });
165
+ });
166
+ }
167
+ proxy.on("stream", handleStream);
168
+ cleanupListeners.push(() => proxy.off("stream", handleStream));
169
+
170
+ // flush and replay buffered streams
171
+ streamBufferRef.current.forEach((buffer) =>
172
+ handleStream(buffer.stream, buffer.headers)
173
+ );
174
+ streamBufferRef.current = [];
175
+
176
+ /** HTTP/1 -> HTTP/2 */
177
+ const handleRequest: RequestListener = (
178
+ message: IncomingMessage,
179
+ response: ServerResponse
180
+ ) => {
181
+ const { httpVersionMajor, headers, method, url } = message;
182
+ if (httpVersionMajor >= 2) {
183
+ return; // Already handled by the "stream" event.
184
+ }
185
+ addCfPreviewTokenHeader(headers, previewToken.value);
186
+ headers[":method"] = method;
187
+ headers[":path"] = url;
188
+ headers[":authority"] = previewToken.host;
189
+ headers[":scheme"] = "https";
190
+ for (const name of Object.keys(headers)) {
191
+ if (HTTP1_HEADERS.has(name.toLowerCase())) {
192
+ delete headers[name];
55
193
  }
56
194
  }
57
- response.writeHead(status, responseHeaders);
58
- request.pipe(response, { end: true });
59
- });
60
- };
61
- // If an asset path is defined, check the file system
62
- // for a file first and serve if it exists.
63
- if (assetPath) {
64
- const handleAsset = serveStatic(assetPath, {
65
- cacheControl: false,
66
- });
67
- local.on("request", (request, response) => {
68
- handleAsset(request, response, () => {
69
- handleRequest(request, response);
195
+ const request = message.pipe(remote.request(headers));
196
+ request.on("response", (responseHeaders) => {
197
+ const status = responseHeaders[":status"];
198
+ rewriteRemoteHostToLocalHostInHeaders(
199
+ responseHeaders,
200
+ previewToken.host,
201
+ port
202
+ );
203
+ for (const name of Object.keys(responseHeaders)) {
204
+ if (name.startsWith(":")) {
205
+ delete responseHeaders[name];
206
+ }
207
+ }
208
+ response.writeHead(status, responseHeaders);
209
+ request.pipe(response, { end: true });
70
210
  });
71
- });
72
- } else {
73
- local.on("request", handleRequest);
74
- }
75
- // HTTP/1 -> WebSocket (over HTTP/1)
76
- local.on("upgrade", (message, socket, body) => {
77
- const { headers, url } = message;
78
- onRequest(headers);
79
- headers["host"] = host;
80
- const localWebsocket = new WebSocket(message, socket, body);
81
- // TODO(soon): Custom WebSocket protocol is not working?
82
- const remoteWebsocketClient = new WebSocket.Client(
83
- `wss://${host}${url}`,
84
- [],
85
- { headers }
211
+ };
212
+
213
+ // If an asset path is defined, check the file system
214
+ // for a file first and serve if it exists.
215
+ const actualHandleRequest = assetPath
216
+ ? createHandleAssetsRequest(assetPath, handleRequest)
217
+ : handleRequest;
218
+
219
+ proxy.on("request", actualHandleRequest);
220
+ cleanupListeners.push(() => proxy.off("request", actualHandleRequest));
221
+
222
+ // flush and replay buffered requests
223
+ requestResponseBufferRef.current.forEach(({ request, response }) =>
224
+ actualHandleRequest(request, response)
86
225
  );
87
- localWebsocket.pipe(remoteWebsocketClient).pipe(localWebsocket);
88
- });
89
- remote.on("close", () => {
90
- local.close();
226
+ requestResponseBufferRef.current = [];
227
+
228
+ /** HTTP/1 -> WebSocket (over HTTP/1) */
229
+ const handleUpgrade = (
230
+ message: IncomingMessage,
231
+ socket: WebSocket,
232
+ body: Buffer
233
+ ) => {
234
+ const { headers, url } = message;
235
+ addCfPreviewTokenHeader(headers, previewToken.value);
236
+ headers["host"] = previewToken.host;
237
+ const localWebsocket = new WebSocket(message, socket, body);
238
+ // TODO(soon): Custom WebSocket protocol is not working?
239
+ const remoteWebsocketClient = new WebSocket.Client(
240
+ `wss://${previewToken.host}${url}`,
241
+ [],
242
+ { headers }
243
+ );
244
+ localWebsocket.pipe(remoteWebsocketClient).pipe(localWebsocket);
245
+ // We close down websockets whenever we refresh the token.
246
+ cleanupListeners.push(() => {
247
+ localWebsocket.destroy();
248
+ remoteWebsocketClient.destroy();
249
+ });
250
+ };
251
+ proxy.on("upgrade", handleUpgrade);
252
+ cleanupListeners.push(() => proxy.off("upgrade", handleUpgrade));
253
+
254
+ return () => {
255
+ cleanupListeners.forEach((d) => d());
256
+ };
257
+ }, [previewToken, publicRoot, port]);
258
+
259
+ // Start/stop the server whenever the
260
+ // containing component is mounted/unmounted.
261
+ useEffect(() => {
262
+ proxyServer.current.listen(port);
263
+ console.log(`⬣ Listening at http://localhost:${port}`);
264
+
265
+ return () => {
266
+ proxyServer.current.close();
267
+ };
268
+ }, [port]);
269
+ }
270
+
271
+ function createHandleAssetsRequest(
272
+ assetPath: string,
273
+ handleRequest: RequestListener
274
+ ) {
275
+ const handleAsset = serveStatic(assetPath, {
276
+ cacheControl: false,
91
277
  });
92
- return local;
278
+ return (request: IncomingMessage, response: ServerResponse) => {
279
+ handleAsset(request, response, () => {
280
+ handleRequest(request, response);
281
+ });
282
+ };
93
283
  }
94
284
 
285
+ /** A Set of headers we want to remove from HTTP/1 requests. */
95
286
  const HTTP1_HEADERS = new Set([
96
287
  "host",
97
288
  "connection",
package/src/publish.ts CHANGED
@@ -11,7 +11,7 @@ import type { Config } from "./config";
11
11
  import makeModuleCollector from "./module-collection";
12
12
  import { syncAssets } from "./sites";
13
13
 
14
- type CfScriptFormat = void | "modules" | "service-worker";
14
+ type CfScriptFormat = undefined | "modules" | "service-worker";
15
15
 
16
16
  type Props = {
17
17
  config: Config;
@@ -19,13 +19,15 @@ type Props = {
19
19
  script?: string;
20
20
  name?: string;
21
21
  env?: string;
22
+ compatibilityDate?: string;
23
+ compatibilityFlags?: string[];
22
24
  public?: string;
23
25
  site?: string;
24
26
  triggers?: (string | number)[];
25
27
  routes?: (string | number)[];
26
28
  legacyEnv?: boolean;
27
- jsxFactory: void | string;
28
- jsxFragment: void | string;
29
+ jsxFactory: undefined | string;
30
+ jsxFragment: undefined | string;
29
31
  };
30
32
 
31
33
  function sleep(ms: number) {
@@ -48,6 +50,13 @@ export default async function publish(props: Props): Promise<void> {
48
50
  __path__,
49
51
  } = config;
50
52
 
53
+ const envRootObj = props.env ? config.env[props.env] || {} : config;
54
+
55
+ assert(
56
+ envRootObj.compatibility_date || props["compatibility-date"],
57
+ "A compatibility_date is required when publishing. Add one to your wrangler.toml file, or pass it in your terminal as --compatibility_date. See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information."
58
+ );
59
+
51
60
  const triggers = props.triggers || config.triggers?.crons;
52
61
  const routes = props.routes || config.routes;
53
62
 
@@ -125,7 +134,7 @@ export default async function publish(props: Props): Promise<void> {
125
134
  entryPoint ===
126
135
  (props.public
127
136
  ? path.join(path.dirname(file), "static-asset-facade.js")
128
- : file)
137
+ : Object.keys(result.metafile.inputs)[0])
129
138
  );
130
139
 
131
140
  const { format } = props;
@@ -200,7 +209,6 @@ export default async function publish(props: Props): Promise<void> {
200
209
  )
201
210
  : { manifest: undefined, namespace: undefined };
202
211
 
203
- const envRootObj = props.env ? config.env[props.env] || {} : config;
204
212
  const bindings: CfWorkerInit["bindings"] = {
205
213
  kv_namespaces: envRootObj.kv_namespaces?.concat(
206
214
  assets.namespace