wrangler 0.0.0-e22f9d7 → 0.0.0-e2a26a0

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.
Files changed (54) hide show
  1. package/bin/wrangler.js +2 -2
  2. package/package.json +15 -10
  3. package/pages/functions/buildWorker.ts +1 -1
  4. package/pages/functions/filepath-routing.test.ts +21 -13
  5. package/pages/functions/filepath-routing.ts +38 -28
  6. package/pages/functions/routes.ts +8 -6
  7. package/pages/functions/template-worker.ts +16 -24
  8. package/src/__tests__/dev.test.tsx +7 -3
  9. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  10. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  11. package/src/__tests__/helpers/mock-account-id.ts +30 -0
  12. package/src/__tests__/helpers/mock-bin.ts +33 -0
  13. package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +49 -13
  14. package/src/__tests__/helpers/mock-console.ts +56 -0
  15. package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
  16. package/src/__tests__/helpers/mock-kv.ts +40 -0
  17. package/src/__tests__/helpers/mock-user.ts +27 -0
  18. package/src/__tests__/helpers/run-in-tmp.ts +29 -0
  19. package/src/__tests__/helpers/run-wrangler.ts +14 -0
  20. package/src/__tests__/index.test.ts +312 -56
  21. package/src/__tests__/jest.setup.ts +17 -2
  22. package/src/__tests__/kv.test.ts +344 -316
  23. package/src/__tests__/logout.test.ts +50 -0
  24. package/src/__tests__/package-manager.test.ts +206 -0
  25. package/src/__tests__/publish.test.ts +1222 -0
  26. package/src/__tests__/secret.test.ts +210 -0
  27. package/src/__tests__/whoami.test.tsx +86 -0
  28. package/src/api/form_data.ts +10 -7
  29. package/src/api/preview.ts +2 -2
  30. package/src/api/worker.ts +3 -3
  31. package/src/cfetch/index.ts +14 -14
  32. package/src/cfetch/internal.ts +40 -8
  33. package/src/config.ts +162 -8
  34. package/src/dev.tsx +103 -53
  35. package/src/dialogs.tsx +2 -2
  36. package/src/index.tsx +438 -311
  37. package/src/inspect.ts +80 -23
  38. package/src/kv.tsx +9 -1
  39. package/src/module-collection.ts +5 -6
  40. package/src/package-manager.ts +120 -0
  41. package/src/pages.tsx +41 -26
  42. package/src/paths.ts +26 -0
  43. package/src/proxy.ts +78 -10
  44. package/src/publish.ts +98 -52
  45. package/src/sites.tsx +175 -53
  46. package/src/user.tsx +51 -59
  47. package/src/whoami.tsx +69 -0
  48. package/templates/new-worker.js +15 -0
  49. package/templates/new-worker.ts +15 -0
  50. package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
  51. package/wrangler-dist/cli.js +111479 -110187
  52. package/wrangler-dist/cli.js.map +3 -3
  53. package/src/__tests__/run-in-tmp.ts +0 -19
  54. package/src/__tests__/run-wrangler.ts +0 -32
package/src/config.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import assert from "node:assert";
2
+
1
3
  /**
2
4
  * This is the static type definition for the configuration object.
3
5
  * It reflects the configuration that you can write in wrangler.toml,
@@ -79,7 +81,6 @@ export type Config = {
79
81
  *
80
82
  * @optional
81
83
  * @inherited
82
- * @todo This could be an enum!
83
84
  */
84
85
  compatibility_flags?: string[];
85
86
 
@@ -268,10 +269,9 @@ export type Config = {
268
269
  * The location of your Worker script.
269
270
  *
270
271
  * @deprecated DO NOT use this (it's a holdover from wrangler 1.x). Either use the top level `entry` field, or pass the path to your entry file as a command line argument.
271
- * @todo we should use a top level "entry" property instead
272
272
  * @breaking
273
273
  */
274
- "entry-point": string;
274
+ "entry-point"?: string;
275
275
 
276
276
  /**
277
277
  * An exclusive list of .gitignore-style patterns that match file
@@ -280,7 +280,6 @@ export type Config = {
280
280
  *
281
281
  * @optional
282
282
  * @default `[]`
283
- * @todo this needs to be implemented!
284
283
  */
285
284
  include?: string[];
286
285
 
@@ -291,7 +290,6 @@ export type Config = {
291
290
  *
292
291
  * @optional
293
292
  * @default `[]`
294
- * @todo this needs to be implemented!
295
293
  */
296
294
  exclude?: string[];
297
295
  };
@@ -304,7 +302,6 @@ export type Config = {
304
302
  * @inherited
305
303
  * @default `{ crons: [] }`
306
304
  * @optional
307
- * @todo can we use typescript for cron patterns?
308
305
  */
309
306
  triggers?: { crons: string[] };
310
307
 
@@ -389,7 +386,7 @@ export type Config = {
389
386
  *
390
387
  * @deprecated We infer the format automatically now.
391
388
  */
392
- format: "service-worker";
389
+ format?: "service-worker";
393
390
 
394
391
  /**
395
392
  * The path to the Worker script. This should be replaced
@@ -412,7 +409,7 @@ export type Config = {
412
409
  *
413
410
  * @deprecated We infer the format automatically now.
414
411
  */
415
- format: "modules";
412
+ format?: "modules";
416
413
 
417
414
  /**
418
415
  * The directory you wish to upload your modules from,
@@ -485,3 +482,160 @@ export async function validateConfig(
485
482
 
486
483
  return results;
487
484
  }
485
+
486
+ /**
487
+ * Process the environments (`env`) specified in the `config`.
488
+ *
489
+ * The environments configuration is complicated since each environment is a customized version of the main config.
490
+ * Some of the configuration can be inherited from the main config, while other configuration must replace what is in the main config.
491
+ *
492
+ * This function ensures that each environment is set up correctly with inherited configuration, as necessary.
493
+ * It will log a warning if an environment is missing required configuration.
494
+ */
495
+ export function normaliseAndValidateEnvironmentsConfig(config: Config) {
496
+ if (config.env == undefined) {
497
+ // There are no environments specified so there is nothing to do here.
498
+ return;
499
+ }
500
+
501
+ const environments = config.env;
502
+
503
+ for (const envKey of Object.keys(environments)) {
504
+ const environment = environments[envKey];
505
+
506
+ // Given how TOML works, there should never be an environment containing nothing.
507
+ // I.e. if there is a section in a TOML file, then the parser will create an object for it.
508
+ // But it may be possible in the future if we change how the configuration is stored.
509
+ assert(
510
+ environment,
511
+ `Environment ${envKey} is specified in the config but not defined.`
512
+ );
513
+
514
+ // Fall back on "inherited fields" from the config, if not specified in the environment.
515
+ const inheritedFields = [
516
+ "name",
517
+ "account_id",
518
+ "workers_dev",
519
+ "compatibility_date",
520
+ "compatibility_flags",
521
+ "zone_id",
522
+ "routes",
523
+ "route",
524
+ "jsx_factory",
525
+ "jsx_fragment",
526
+ "site",
527
+ "triggers",
528
+ "usage_model",
529
+ ];
530
+ for (const inheritedField of inheritedFields) {
531
+ if (config[inheritedField] !== undefined) {
532
+ if (environment[inheritedField] === undefined) {
533
+ environment[inheritedField] = config[inheritedField]; // TODO: - shallow or deep copy?
534
+ }
535
+ }
536
+ }
537
+
538
+ // Warn if there is a "required" field in the top level config that has not been specified specified in the environment.
539
+ // These required fields are `vars`, `durable_objects`, `kv_namespaces` and `experimental_services`.
540
+ // Each of them has different characteristics that need to be checked.
541
+
542
+ // `vars` is just an object
543
+ if (config.vars !== undefined) {
544
+ if (environment.vars === undefined) {
545
+ console.warn(
546
+ `In your configuration, "vars" exists at the top level, but not on "env.${envKey}".\n` +
547
+ `This is not what you probably want, since "vars" is not inherited by environments.\n` +
548
+ `Please add "vars" to "env.${envKey}".`
549
+ );
550
+ } else {
551
+ for (const varField of Object.keys(config.vars)) {
552
+ if (!(varField in environment.vars)) {
553
+ console.warn(
554
+ `In your configuration, "vars.${varField}" exists at the top level, but not on "env.${envKey}".\n` +
555
+ `This is not what you probably want, since "vars" is not inherited by environments.\n` +
556
+ `Please add "vars.${varField}" to "env.${envKey}".`
557
+ );
558
+ }
559
+ }
560
+ }
561
+ }
562
+
563
+ // `durable_objects` is an object containing a `bindings` array
564
+ if (config.durable_objects !== undefined) {
565
+ if (environment.durable_objects === undefined) {
566
+ console.warn(
567
+ `In your configuration, "durable_objects.bindings" exists at the top level, but not on "env.${envKey}".\n` +
568
+ `This is not what you probably want, since "durable_objects" is not inherited by environments.\n` +
569
+ `Please add "durable_objects.bindings" to "env.${envKey}".`
570
+ );
571
+ } else {
572
+ const envBindingNames = new Set(
573
+ environment.durable_objects.bindings.map((b) => b.name)
574
+ );
575
+ for (const bindingName of config.durable_objects.bindings.map(
576
+ (b) => b.name
577
+ )) {
578
+ if (!envBindingNames.has(bindingName)) {
579
+ console.warn(
580
+ `In your configuration, there is a durable_objects binding with name "${bindingName}" at the top level, but not on "env.${envKey}".\n` +
581
+ `This is not what you probably want, since "durable_objects" is not inherited by environments.\n` +
582
+ `Please add a binding for "${bindingName}" to "env.${envKey}.durable_objects.bindings".`
583
+ );
584
+ }
585
+ }
586
+ }
587
+ }
588
+
589
+ // `kv_namespaces` contains an array of namespace bindings
590
+ if (config.kv_namespaces !== undefined) {
591
+ if (environment.kv_namespaces === undefined) {
592
+ console.warn(
593
+ `In your configuration, "kv_namespaces" exists at the top level, but not on "env.${envKey}".\n` +
594
+ `This is not what you probably want, since "kv_namespaces" is not inherited by environments.\n` +
595
+ `Please add "kv_namespaces" to "env.${envKey}".`
596
+ );
597
+ } else {
598
+ const envBindings = new Set(
599
+ environment.kv_namespaces.map((kvNamespace) => kvNamespace.binding)
600
+ );
601
+ for (const bindingName of config.kv_namespaces.map(
602
+ (kvNamespace) => kvNamespace.binding
603
+ )) {
604
+ if (!envBindings.has(bindingName)) {
605
+ console.warn(
606
+ `In your configuration, there is a kv_namespaces with binding "${bindingName}" at the top level, but not on "env.${envKey}".\n` +
607
+ `This is not what you probably want, since "kv_namespaces" is not inherited by environments.\n` +
608
+ `Please add a binding for "${bindingName}" to "env.${envKey}.kv_namespaces".`
609
+ );
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ // `experimental_services` contains an array of namespace bindings
616
+ if (config.experimental_services !== undefined) {
617
+ if (environment.experimental_services === undefined) {
618
+ console.warn(
619
+ `In your configuration, "experimental_services" exists at the top level, but not on "env.${envKey}".\n` +
620
+ `This is not what you probably want, since "experimental_services" is not inherited by environments.\n` +
621
+ `Please add "experimental_services" to "env.${envKey}".`
622
+ );
623
+ } else {
624
+ const envBindingNames = new Set(
625
+ environment.experimental_services.map((service) => service.name)
626
+ );
627
+ for (const bindingName of config.experimental_services.map(
628
+ (service) => service.name
629
+ )) {
630
+ if (!envBindingNames.has(bindingName)) {
631
+ console.warn(
632
+ `In your configuration, there is a experimental_services with binding name "${bindingName}" at the top level, but not on "env.${envKey}".\n` +
633
+ `This is not what you probably want, since "experimental_services" is not inherited by environments.\n` +
634
+ `Please add a service for "${bindingName}" to "env.${envKey}.experimental_services".`
635
+ );
636
+ }
637
+ }
638
+ }
639
+ }
640
+ }
641
+ }
package/src/dev.tsx CHANGED
@@ -1,32 +1,32 @@
1
- import esbuild from "esbuild";
2
1
  import assert from "node:assert";
3
2
  import { spawn } from "node:child_process";
4
- import { readFile } from "node:fs/promises";
5
3
  import { existsSync } from "node:fs";
4
+ import { readFile } from "node:fs/promises";
6
5
  import path from "node:path";
7
- import { Box, Text, useApp, useInput } from "ink";
8
6
  import { watch } from "chokidar";
9
7
  import clipboardy from "clipboardy";
10
8
  import commandExists from "command-exists";
11
- import { execa } from "execa";
12
- import fetch from "node-fetch";
9
+ import * as esbuild from "esbuild";
10
+ import { execaCommand } from "execa";
11
+ import { Box, Text, useApp, useInput } from "ink";
13
12
  import open from "open";
14
13
  import React, { useState, useEffect, useRef } from "react";
15
14
  import { withErrorBoundary, useErrorHandler } from "react-error-boundary";
16
15
  import onExit from "signal-exit";
17
16
  import tmp from "tmp-promise";
18
- import type { DirectoryResult } from "tmp-promise";
17
+ import { fetch } from "undici";
19
18
 
20
- import type { CfPreviewToken } from "./api/preview";
21
- import type { CfModule } from "./api/worker";
22
19
  import { createWorker } from "./api/worker";
23
- import type { CfWorkerInit } from "./api/worker";
24
20
 
25
21
  import useInspector from "./inspect";
26
22
  import makeModuleCollector from "./module-collection";
27
- import { usePreviewServer } from "./proxy";
23
+ import { usePreviewServer, waitForPortToBeAvailable } from "./proxy";
28
24
  import { syncAssets } from "./sites";
29
25
  import { getAPIToken } from "./user";
26
+ import type { CfPreviewToken } from "./api/preview";
27
+ import type { CfModule, CfWorkerInit } from "./api/worker";
28
+ import type { AssetPaths } from "./sites";
29
+ import type { DirectoryResult } from "tmp-promise";
30
30
 
31
31
  type CfScriptFormat = undefined | "modules" | "service-worker";
32
32
 
@@ -39,9 +39,10 @@ export type DevProps = {
39
39
  initialMode: "local" | "remote";
40
40
  jsxFactory: undefined | string;
41
41
  jsxFragment: undefined | string;
42
+ enableLocalPersistence: boolean;
42
43
  bindings: CfWorkerInit["bindings"];
43
44
  public: undefined | string;
44
- site: undefined | string;
45
+ assetPaths: undefined | AssetPaths;
45
46
  compatibilityDate: undefined | string;
46
47
  compatibilityFlags: undefined | string[];
47
48
  usageModel: undefined | "bundled" | "unbound";
@@ -50,6 +51,7 @@ export type DevProps = {
50
51
  cwd?: undefined | string;
51
52
  watch_dir?: undefined | string;
52
53
  };
54
+ env: string | undefined;
53
55
  };
54
56
 
55
57
  function Dev(props: DevProps): JSX.Element {
@@ -98,9 +100,10 @@ function Dev(props: DevProps): JSX.Element {
98
100
  bundle={bundle}
99
101
  format={props.format}
100
102
  bindings={props.bindings}
101
- site={props.site}
103
+ assetPaths={props.assetPaths}
102
104
  public={props.public}
103
105
  port={port}
106
+ enableLocalPersistence={props.enableLocalPersistence}
104
107
  />
105
108
  ) : (
106
109
  <Remote
@@ -110,12 +113,13 @@ function Dev(props: DevProps): JSX.Element {
110
113
  accountId={props.accountId}
111
114
  apiToken={apiToken}
112
115
  bindings={props.bindings}
113
- site={props.site}
116
+ assetPaths={props.assetPaths}
114
117
  public={props.public}
115
118
  port={port}
116
119
  compatibilityDate={props.compatibilityDate}
117
120
  compatibilityFlags={props.compatibilityFlags}
118
121
  usageModel={props.usageModel}
122
+ env={props.env}
119
123
  />
120
124
  )}
121
125
  <Box borderStyle="round" paddingLeft={1} paddingRight={1}>
@@ -136,7 +140,7 @@ function Remote(props: {
136
140
  bundle: EsbuildBundle | undefined;
137
141
  format: CfScriptFormat;
138
142
  public: undefined | string;
139
- site: undefined | string;
143
+ assetPaths: undefined | AssetPaths;
140
144
  port: number;
141
145
  accountId: undefined | string;
142
146
  apiToken: undefined | string;
@@ -144,6 +148,7 @@ function Remote(props: {
144
148
  compatibilityDate: string | undefined;
145
149
  compatibilityFlags: undefined | string[];
146
150
  usageModel: undefined | "bundled" | "unbound";
151
+ env: string | undefined;
147
152
  }) {
148
153
  assert(props.accountId, "accountId is required");
149
154
  assert(props.apiToken, "apiToken is required");
@@ -155,11 +160,12 @@ function Remote(props: {
155
160
  accountId: props.accountId,
156
161
  apiToken: props.apiToken,
157
162
  bindings: props.bindings,
158
- sitesFolder: props.site,
163
+ assetPaths: props.assetPaths,
159
164
  port: props.port,
160
165
  compatibilityDate: props.compatibilityDate,
161
166
  compatibilityFlags: props.compatibilityFlags,
162
167
  usageModel: props.usageModel,
168
+ env: props.env,
163
169
  });
164
170
 
165
171
  usePreviewServer({
@@ -180,16 +186,20 @@ function Local(props: {
180
186
  bundle: EsbuildBundle | undefined;
181
187
  format: CfScriptFormat;
182
188
  bindings: CfWorkerInit["bindings"];
189
+ assetPaths: undefined | AssetPaths;
183
190
  public: undefined | string;
184
- site: undefined | string;
185
191
  port: number;
192
+ enableLocalPersistence: boolean;
186
193
  }) {
187
194
  const { inspectorUrl } = useLocalWorker({
188
195
  name: props.name,
189
196
  bundle: props.bundle,
190
197
  format: props.format,
191
198
  bindings: props.bindings,
199
+ assetPaths: props.assetPaths,
200
+ public: props.public,
192
201
  port: props.port,
202
+ enableLocalPersistence: props.enableLocalPersistence,
193
203
  });
194
204
  useInspector({ inspectorUrl, port: 9229, logToTerminal: false });
195
205
  return null;
@@ -200,10 +210,13 @@ function useLocalWorker(props: {
200
210
  bundle: EsbuildBundle | undefined;
201
211
  format: CfScriptFormat;
202
212
  bindings: CfWorkerInit["bindings"];
213
+ assetPaths: undefined | AssetPaths;
214
+ public: undefined | string;
203
215
  port: number;
216
+ enableLocalPersistence: boolean;
204
217
  }) {
205
218
  // TODO: pass vars via command line
206
- const { bundle, format, bindings, port } = props;
219
+ const { bundle, format, bindings, port, assetPaths } = props;
207
220
  const local = useRef<ReturnType<typeof spawn>>();
208
221
  const removeSignalExitListener = useRef<() => void>();
209
222
  const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
@@ -221,6 +234,13 @@ function useLocalWorker(props: {
221
234
  return;
222
235
  }
223
236
 
237
+ await waitForPortToBeAvailable(port, { retryPeriod: 200, timeout: 2000 });
238
+ if (props.public) {
239
+ throw new Error(
240
+ '⎔ A "public" folder is not yet supported in local mode.'
241
+ );
242
+ }
243
+
224
244
  console.log("⎔ Starting a local server...");
225
245
  // TODO: just use execa for this
226
246
  local.current = spawn("node", [
@@ -237,9 +257,23 @@ function useLocalWorker(props: {
237
257
  path.join(__dirname, "../miniflare-config-stubs/package.empty.json"),
238
258
  "--port",
239
259
  port.toString(),
240
- "--kv-persist",
241
- "--cache-persist",
242
- "--do-persist",
260
+ ...(assetPaths
261
+ ? [
262
+ "--site",
263
+ assetPaths.baseDirectory,
264
+ ...assetPaths.includePatterns.map((pattern) => [
265
+ "--site-include",
266
+ pattern,
267
+ ]),
268
+ ...assetPaths.excludePatterns.map((pattern) => [
269
+ "--site-exclude",
270
+ pattern,
271
+ ]),
272
+ ].flatMap((x) => x)
273
+ : []),
274
+ ...(props.enableLocalPersistence
275
+ ? ["--kv-persist", "--cache-persist", "--do-persist"]
276
+ : []),
243
277
  ...Object.entries(bindings.vars || {}).flatMap(([key, value]) => {
244
278
  return ["--binding", `${key}=${value}`];
245
279
  }),
@@ -318,6 +352,9 @@ function useLocalWorker(props: {
318
352
  bindings.durable_objects?.bindings,
319
353
  bindings.kv_namespaces,
320
354
  bindings.vars,
355
+ props.enableLocalPersistence,
356
+ assetPaths,
357
+ props.public,
321
358
  ]);
322
359
  return { inspectorUrl };
323
360
  }
@@ -345,7 +382,7 @@ function useTmpDir(): string | undefined {
345
382
  return () => {
346
383
  dir.cleanup().catch(() => {
347
384
  // extremely unlikely,
348
- // but it's 2021 after all
385
+ // but it's 2022 after all
349
386
  console.error("failed to cleanup tmp dir");
350
387
  });
351
388
  };
@@ -370,20 +407,21 @@ function useCustomBuild(
370
407
  if (!command) return;
371
408
  let cmd, interval;
372
409
  console.log("running:", command);
373
- const commandPieces = command.split(" ");
374
- cmd = execa(commandPieces[0], commandPieces.slice(1), {
410
+ cmd = execaCommand(command, {
375
411
  ...(cwd && { cwd }),
412
+ shell: true,
376
413
  stderr: "inherit",
377
414
  stdout: "inherit",
378
415
  });
379
416
  if (watch_dir) {
380
417
  watch(watch_dir, { persistent: true, ignoreInitial: true }).on(
381
418
  "all",
382
- (_event, _path) => {
383
- console.log(`The file ${path} changed, restarting build...`);
419
+ (_event, filePath) => {
420
+ console.log(`The file ${filePath} changed, restarting build...`);
384
421
  cmd.kill();
385
- cmd = execa(commandPieces[0], commandPieces.slice(1), {
422
+ cmd = execaCommand(command, {
386
423
  ...(cwd && { cwd }),
424
+ shell: true,
387
425
  stderr: "inherit",
388
426
  stdout: "inherit",
389
427
  });
@@ -454,6 +492,9 @@ function useEsbuild(props: {
454
492
  sourcemap: true,
455
493
  loader: {
456
494
  ".js": "jsx",
495
+ ".html": "text",
496
+ ".pem": "text",
497
+ ".txt": "text",
457
498
  },
458
499
  ...(jsxFactory && { jsxFactory }),
459
500
  ...(jsxFragment && { jsxFragment }),
@@ -522,11 +563,12 @@ function useWorker(props: {
522
563
  accountId: string;
523
564
  apiToken: string;
524
565
  bindings: CfWorkerInit["bindings"];
525
- sitesFolder: undefined | string;
566
+ assetPaths: undefined | AssetPaths;
526
567
  port: number;
527
568
  compatibilityDate: string | undefined;
528
569
  compatibilityFlags: string[] | undefined;
529
570
  usageModel: undefined | "bundled" | "unbound";
571
+ env: string | undefined;
530
572
  }): CfPreviewToken | undefined {
531
573
  const {
532
574
  name,
@@ -536,7 +578,7 @@ function useWorker(props: {
536
578
  accountId,
537
579
  apiToken,
538
580
  bindings,
539
- sitesFolder,
581
+ assetPaths,
540
582
  compatibilityDate,
541
583
  compatibilityFlags,
542
584
  usageModel,
@@ -568,32 +610,34 @@ function useWorker(props: {
568
610
  if (!startedRef.current) {
569
611
  startedRef.current = true;
570
612
  } else {
571
- console.log("⎔ Detected changes, restarting server...");
613
+ console.log("⎔ Detected changes, restarted server.");
614
+ }
615
+
616
+ const assets = await syncAssets(
617
+ accountId,
618
+ name || path.basename(bundle.path),
619
+ assetPaths,
620
+ true,
621
+ props.env
622
+ ); // TODO: cancellable?
623
+
624
+ const workerType = format || bundle.type === "esm" ? "esm" : "commonjs";
625
+ let content = await readFile(bundle.path, "utf-8");
626
+ if (workerType !== "esm" && assets.manifest) {
627
+ content = `const __STATIC_CONTENT_MANIFEST = ${JSON.stringify(
628
+ assets.manifest
629
+ )};\n${content}`;
572
630
  }
573
631
 
574
- const assets = sitesFolder
575
- ? await syncAssets(
576
- accountId,
577
- path.basename(bundle.path),
578
- sitesFolder,
579
- true,
580
- undefined // TODO: env
581
- )
582
- : {
583
- manifest: undefined,
584
- namespace: undefined,
585
- }; // TODO: cancellable?
586
-
587
- const content = await readFile(bundle.path, "utf-8");
588
632
  const init: CfWorkerInit = {
589
633
  name,
590
634
  main: {
591
635
  name: path.basename(bundle.path),
592
- type: format || bundle.type === "esm" ? "esm" : "commonjs",
636
+ type: workerType,
593
637
  content,
594
638
  },
595
639
  modules: modules.concat(
596
- assets.manifest
640
+ assets.manifest && workerType === "esm"
597
641
  ? {
598
642
  name: "__STATIC_CONTENT_MANIFEST",
599
643
  content: JSON.stringify(assets.manifest),
@@ -633,12 +677,13 @@ function useWorker(props: {
633
677
  accountId,
634
678
  apiToken,
635
679
  port,
636
- sitesFolder,
680
+ assetPaths,
637
681
  compatibilityDate,
638
682
  compatibilityFlags,
639
683
  usageModel,
640
684
  bindings,
641
685
  modules,
686
+ props.env,
642
687
  ]);
643
688
  return token;
644
689
  }
@@ -736,29 +781,34 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
736
781
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
737
782
  key
738
783
  ) => {
739
- switch (input) {
740
- case "b": // open browser
784
+ switch (input.toLowerCase()) {
785
+ // open browser
786
+ case "b":
741
787
  await open(`http://localhost:${port}/`);
742
788
  break;
743
- case "d": // toggle inspector
789
+ // toggle inspector
790
+ case "d":
744
791
  await open(
745
792
  `https://built-devtools.pages.dev/js_app?experiments=true&v8only=true&ws=localhost:9229/ws`
746
793
  );
747
794
  break;
748
- case "s": // toggle tunnel
795
+ // toggle tunnel
796
+ case "s":
749
797
  setToggles((previousToggles) => ({
750
798
  ...previousToggles,
751
799
  tunnel: !previousToggles.tunnel,
752
800
  }));
753
801
  break;
754
- case "l": // toggle local
802
+ // toggle local
803
+ case "l":
755
804
  setToggles((previousToggles) => ({
756
805
  ...previousToggles,
757
806
  local: !previousToggles.local,
758
807
  }));
759
808
  break;
760
- case "q": // shut down
761
- case "x": // shut down
809
+ // shut down
810
+ case "q":
811
+ case "x":
762
812
  process.exit(0);
763
813
  break;
764
814
  default:
package/src/dialogs.tsx CHANGED
@@ -1,7 +1,7 @@
1
- import * as React from "react";
2
- import { useState } from "react";
3
1
  import { Box, Text, useInput, render } from "ink";
4
2
  import TextInput from "ink-text-input";
3
+ import * as React from "react";
4
+ import { useState } from "react";
5
5
  type ConfirmProps = {
6
6
  text: string;
7
7
  onConfirm: (answer: boolean) => void;