wrangler 0.0.0-fb0eae7 → 0.0.0-fb43821

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/dev.tsx CHANGED
@@ -23,6 +23,7 @@ import assert from "assert";
23
23
  import { getAPIToken } from "./user";
24
24
  import fetch from "node-fetch";
25
25
  import makeModuleCollector from "./module-collection";
26
+ import { withErrorBoundary, useErrorHandler } from "react-error-boundary";
26
27
 
27
28
  type CfScriptFormat = void | "modules" | "service-worker";
28
29
 
@@ -43,7 +44,7 @@ type Props = {
43
44
  usageModel: void | "bundled" | "unbound";
44
45
  };
45
46
 
46
- export function Dev(props: Props): JSX.Element {
47
+ function Dev(props: Props): JSX.Element {
47
48
  if (props.public && props.format === "service-worker") {
48
49
  throw new Error(
49
50
  "You cannot use the service worker format with a `public` directory."
@@ -233,6 +234,7 @@ function useLocalWorker(props: {
233
234
  }
234
235
 
235
236
  console.log("⎔ Starting a local server...");
237
+ // TODO: just use execa for this
236
238
  local.current = spawn("node", [
237
239
  "--experimental-vm-modules",
238
240
  "--inspect",
@@ -293,6 +295,17 @@ function useLocalWorker(props: {
293
295
  }
294
296
  });
295
297
 
298
+ local.current.on("exit", (code) => {
299
+ if (code !== 0) {
300
+ console.error(`miniflare process exited with code ${code}`);
301
+ }
302
+ });
303
+
304
+ local.current.on("error", (error: Error) => {
305
+ console.error(`miniflare process failed to spawn`);
306
+ console.error(error);
307
+ });
308
+
296
309
  removeSignalExitListener.current = onExit((_code, _signal) => {
297
310
  console.log("⎔ Shutting down local server.");
298
311
  local.current?.kill();
@@ -300,7 +313,9 @@ function useLocalWorker(props: {
300
313
  });
301
314
  }
302
315
 
303
- startLocalWorker();
316
+ startLocalWorker().catch((err) => {
317
+ console.error("local worker:", err);
318
+ });
304
319
 
305
320
  return () => {
306
321
  if (local.current) {
@@ -317,6 +332,7 @@ function useLocalWorker(props: {
317
332
 
318
333
  function useTmpDir(): string | void {
319
334
  const [directory, setDirectory] = useState<DirectoryResult>();
335
+ const handleError = useErrorHandler();
320
336
  useEffect(() => {
321
337
  let dir: DirectoryResult;
322
338
  async function create() {
@@ -326,15 +342,22 @@ function useTmpDir(): string | void {
326
342
  return;
327
343
  } catch (err) {
328
344
  console.error("failed to create tmp dir");
329
- console.error(err);
330
345
  throw err;
331
346
  }
332
347
  }
333
- create();
348
+ create().catch((err) => {
349
+ // we want to break here
350
+ // we can't do much without a temp dir anyway
351
+ handleError(err);
352
+ });
334
353
  return () => {
335
- dir.cleanup();
354
+ dir.cleanup().catch(() => {
355
+ // extremely unlikely,
356
+ // but it's 2021 after all
357
+ console.error("failed to cleanup tmp dir");
358
+ });
336
359
  };
337
- }, []);
360
+ }, [handleError]);
338
361
  return directory?.path;
339
362
  }
340
363
 
@@ -374,6 +397,7 @@ function useEsbuild(props: {
374
397
  ...(jsxFactory && { jsxFactory }),
375
398
  ...(jsxFragment && { jsxFragment }),
376
399
  external: ["__STATIC_CONTENT_MANIFEST"],
400
+ conditions: ["worker", "browser"],
377
401
  plugins: [moduleCollector.plugin],
378
402
  // TODO: import.meta.url
379
403
  watch: {
@@ -401,7 +425,12 @@ function useEsbuild(props: {
401
425
  modules: moduleCollector.modules,
402
426
  });
403
427
  }
404
- build();
428
+ build().catch((_err) => {
429
+ // esbuild already logs errors to stderr
430
+ // and we don't want to end the process
431
+ // on build errors anyway
432
+ // so this is a no-op error handler
433
+ });
405
434
  return () => {
406
435
  result?.stop();
407
436
  };
@@ -505,7 +534,11 @@ function useWorker(props: {
505
534
  );
506
535
  console.log(`⬣ Listening at http://localhost:${port}`);
507
536
  }
508
- start();
537
+ start().catch((err) => {
538
+ // we want to log the error, but not end the process
539
+ // since it could recover after the developer fixes whatever's wrong
540
+ console.error("remote worker:", err);
541
+ });
509
542
  }, [
510
543
  name,
511
544
  bundle,
@@ -649,12 +682,14 @@ function useTunnel(toggle: boolean) {
649
682
  });
650
683
 
651
684
  const hostName = await findTunnelHostname();
652
- clipboardy.write(hostName);
685
+ await clipboardy.write(hostName);
653
686
  console.log(`⬣ Sharing at ${hostName}, copied to clipboard.`);
654
687
  }
655
688
  }
656
689
 
657
- startTunnel();
690
+ startTunnel().catch((err) => {
691
+ console.error("tunnel:", err);
692
+ });
658
693
 
659
694
  return () => {
660
695
  if (tunnel.current) {
@@ -676,14 +711,14 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
676
711
  // UGH, we should put port in context instead
677
712
  const [toggles, setToggles] = useState(initial);
678
713
  useInput(
679
- (
714
+ async (
680
715
  input,
681
716
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
682
717
  key
683
718
  ) => {
684
719
  switch (input) {
685
720
  case "b": // open browser
686
- open(
721
+ await open(
687
722
  `http://localhost:${port}/`
688
723
  // {
689
724
  // app: {
@@ -693,7 +728,7 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
693
728
  );
694
729
  break;
695
730
  case "d": // toggle inspector
696
- open(
731
+ await open(
697
732
  `https://built-devtools.pages.dev/js_app?experiments=true&v8only=true&ws=localhost:9229/ws`
698
733
  // {
699
734
  // app: {
@@ -721,3 +756,21 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
721
756
  );
722
757
  return toggles;
723
758
  }
759
+
760
+ function ErrorFallback(props: {
761
+ error: Error;
762
+ resetErrorBoundary: () => void;
763
+ }) {
764
+ useEffect(() => {
765
+ console.error(props.error);
766
+ process.exit(1);
767
+ });
768
+ return (
769
+ <Box>
770
+ <Text>Something went wrong:</Text>
771
+ <Text>{props.error.message}</Text>
772
+ </Box>
773
+ );
774
+ }
775
+
776
+ export default withErrorBoundary(Dev, { FallbackComponent: ErrorFallback });
package/src/dialogs.tsx CHANGED
@@ -4,7 +4,7 @@ import { Box, Text, useInput, render } from "ink";
4
4
  import TextInput from "ink-text-input";
5
5
  type ConfirmProps = {
6
6
  text: string;
7
- onConfirm: (answer: boolean) => void | Promise<void>;
7
+ onConfirm: (answer: boolean) => void;
8
8
  };
9
9
  function Confirm(props: ConfirmProps) {
10
10
  useInput((input: string) => {
@@ -75,11 +75,3 @@ export async function prompt(text: string, type: "text" | "password" = "text") {
75
75
  );
76
76
  });
77
77
  }
78
-
79
- // this one feels a little non "standard"
80
- // export async function select(
81
- // title: string,
82
- // choices: { label: string; value: string }[]
83
- // ): Promise<{ label: string; value: string }>{
84
-
85
- // }
package/src/index.tsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { render } from "ink";
3
- import { Dev } from "./dev";
3
+ import Dev from "./dev";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import makeCLI from "yargs";
6
6
  import { hideBin } from "yargs/helpers";
@@ -134,8 +134,11 @@ export async function main(argv: string[]): Promise<void> {
134
134
  ["*"],
135
135
  false,
136
136
  () => {},
137
- () => {
137
+ (args) => {
138
138
  yargs.showHelp("log");
139
+ if (args._.length > 0) {
140
+ console.error(`\nUnknown command: ${args._}.`);
141
+ }
139
142
  }
140
143
  )
141
144
  .scriptName("wrangler")
@@ -184,26 +187,43 @@ export async function main(argv: string[]): Promise<void> {
184
187
  type: "string",
185
188
  });
186
189
  },
187
- async () => {
190
+ async (args) => {
191
+ if ("type" in args) {
192
+ let message = "The --type option is no longer supported.";
193
+ if (args.type === "webpack") {
194
+ message +=
195
+ "\nIf you wish to use webpack then you will need to create a custom build.";
196
+ // TODO: Add a link to docs
197
+ }
198
+ console.error(message);
199
+ return;
200
+ }
201
+
188
202
  const destination = path.join(process.cwd(), "wrangler.toml");
189
203
  if (fs.existsSync(destination)) {
190
- console.error(`${destination} already exists.`);
191
- } else {
192
- const compatibilityDate = new Date().toISOString().substring(0, 10);
193
- try {
194
- await writeFile(
195
- destination,
196
- `compatibility_date = "${compatibilityDate}"` + "\n"
197
- );
198
- console.log(`✨ Succesfully created wrangler.toml`);
199
- // TODO: suggest next steps?
200
- } catch (err) {
201
- console.error(`Failed to create wrangler.toml`);
202
- console.error(err);
203
- throw err;
204
+ console.error(`${destination} file already exists!`);
205
+ const result = await confirm(
206
+ "Do you want to continue initializing this project?"
207
+ );
208
+ if (!result) {
209
+ return;
204
210
  }
205
211
  }
206
212
 
213
+ const compatibilityDate = new Date().toISOString().substring(0, 10);
214
+ try {
215
+ await writeFile(
216
+ destination,
217
+ `compatibility_date = "${compatibilityDate}"` + "\n"
218
+ );
219
+ console.log(`✨ Successfully created wrangler.toml`);
220
+ // TODO: suggest next steps?
221
+ } catch (err) {
222
+ console.error(`Failed to create wrangler.toml`);
223
+ console.error(err);
224
+ throw err;
225
+ }
226
+
207
227
  // if no package.json, ask, and if yes, create one
208
228
  let pathToPackageJson = await findUp("package.json");
209
229
 
@@ -240,9 +260,17 @@ export async function main(argv: string[]): Promise<void> {
240
260
  JSON.stringify(
241
261
  {
242
262
  compilerOptions: {
243
- target: "ES2020",
244
- module: "CommonJS",
245
- lib: ["ES2020"],
263
+ target: "esnext",
264
+ module: "esnext",
265
+ moduleResolution: "node",
266
+ esModuleInterop: true,
267
+ allowJs: true,
268
+ allowSyntheticDefaultImports: true,
269
+ isolatedModules: true,
270
+ noEmit: true,
271
+ lib: ["esnext"],
272
+ jsx: "react",
273
+ resolveJsonModule: true,
246
274
  types: ["@cloudflare/workers-types"],
247
275
  },
248
276
  },
@@ -686,9 +714,9 @@ export async function main(argv: string[]): Promise<void> {
686
714
  `successfully created tail, expires at ${expiration.toLocaleString()}`
687
715
  );
688
716
 
689
- onExit(() => {
717
+ onExit(async () => {
690
718
  tail.terminate();
691
- deleteTail();
719
+ await deleteTail();
692
720
  });
693
721
 
694
722
  tail.on("message", (data) => {
@@ -1121,7 +1149,7 @@ export async function main(argv: string[]): Promise<void> {
1121
1149
  // TODO: these options shouldn't be required
1122
1150
  script: ` `, // has to be a string with at least one char
1123
1151
  });
1124
- mf.getKVNamespace(title); // this should "create" the namespace
1152
+ await mf.getKVNamespace(title); // this should "create" the namespace
1125
1153
  console.log(`✨ Success! Created KV namespace ${title}`);
1126
1154
  return;
1127
1155
  }
@@ -1367,7 +1395,16 @@ export async function main(argv: string[]): Promise<void> {
1367
1395
  : args.value;
1368
1396
  const config = args.config as Config;
1369
1397
 
1370
- console.log(`writing ${key}=${value} to namespace ${namespaceId}`);
1398
+ if (args.path) {
1399
+ console.log(
1400
+ `writing the contents of ${args.path} to the key "${key}" on namespace ${namespaceId}`
1401
+ );
1402
+ } else {
1403
+ console.log(
1404
+ `writing the value "${value}" to key "${key}" on namespace ${namespaceId}`
1405
+ );
1406
+ }
1407
+
1371
1408
  if (args.local) {
1372
1409
  const { Miniflare } = await import("miniflare");
1373
1410
  const mf = new Miniflare({
@@ -1539,7 +1576,7 @@ export async function main(argv: string[]): Promise<void> {
1539
1576
  // -- snip, end --
1540
1577
 
1541
1578
  // annoyingly, the API for this one doesn't return the
1542
- // data in the 'standard' format. goddamit.
1579
+ // data in the 'standard' format. goddammit.
1543
1580
  // That's why we have the fallthrough response in cfetch.
1544
1581
  // Oh well.
1545
1582
  console.log(
@@ -1579,6 +1616,10 @@ export async function main(argv: string[]): Promise<void> {
1579
1616
  async ({ key, ...args }) => {
1580
1617
  const namespaceId = getNamespaceId(args);
1581
1618
 
1619
+ console.log(
1620
+ `deleting the key "${key}" on namespace ${namespaceId}`
1621
+ );
1622
+
1582
1623
  if (args.local) {
1583
1624
  const { Miniflare } = await import("miniflare");
1584
1625
  const mf = new Miniflare({
@@ -1825,21 +1866,9 @@ export async function main(argv: string[]): Promise<void> {
1825
1866
  yargs.group(["config", "help", "version"], "Flags:");
1826
1867
  yargs.help().alias("h", "help");
1827
1868
  yargs.version(wranglerVersion).alias("v", "version");
1869
+ yargs.exitProcess(false);
1870
+
1828
1871
  await initialiseUserConfig();
1829
1872
 
1830
- await yargs.parse(
1831
- argv
1832
- /* TODO: we'd like to use the parse callback,
1833
- but there's a serious bug with it
1834
- https://github.com/yargs/yargs/issues/1975#issuecomment-874237906
1835
-
1836
- , (err, argv, output) => {
1837
- if (output) {
1838
- console.log(output);
1839
- }
1840
- console.log({ err });
1841
- console.log("what now");
1842
- }
1843
- */
1844
- );
1873
+ await yargs.parse(argv);
1845
1874
  }