wrangler 0.0.0-e928f94 → 0.0.0-e9a1820

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
@@ -1,6 +1,6 @@
1
1
  import esbuild from "esbuild";
2
- import httpProxy from "http-proxy";
3
2
  import { readFile } from "fs/promises";
3
+ import { existsSync } from "fs";
4
4
  import type { DirectoryResult } from "tmp-promise";
5
5
  import tmp from "tmp-promise";
6
6
  import type { CfPreviewToken } from "./api/preview";
@@ -9,7 +9,7 @@ import React, { useState, useEffect, useRef } from "react";
9
9
  import path from "path";
10
10
  import open from "open";
11
11
  import { DtInspector } from "./api/inspect";
12
- import type { CfModule, CfVariable } from "./api/worker";
12
+ import type { CfModule } from "./api/worker";
13
13
  import { createWorker } from "./api/worker";
14
14
  import type { CfWorkerInit } from "./api/worker";
15
15
  import { spawn } from "child_process";
@@ -17,12 +17,15 @@ import onExit from "signal-exit";
17
17
  import { syncAssets } from "./sites";
18
18
  import clipboardy from "clipboardy";
19
19
  import http from "node:http";
20
- import serveStatic from "serve-static";
21
20
  import commandExists from "command-exists";
22
21
  import assert from "assert";
23
22
  import { getAPIToken } from "./user";
24
23
  import fetch from "node-fetch";
25
24
  import makeModuleCollector from "./module-collection";
25
+ import { withErrorBoundary, useErrorHandler } from "react-error-boundary";
26
+ import { createHttpProxy } from "./proxy";
27
+ import { execa } from "execa";
28
+ import { watch } from "chokidar";
26
29
 
27
30
  type CfScriptFormat = void | "modules" | "service-worker";
28
31
 
@@ -35,15 +38,20 @@ type Props = {
35
38
  initialMode: "local" | "remote";
36
39
  jsxFactory: void | string;
37
40
  jsxFragment: void | string;
38
- variables: { [name: string]: CfVariable };
41
+ bindings: CfWorkerInit["bindings"];
39
42
  public: void | string;
40
43
  site: void | string;
41
44
  compatibilityDate: void | string;
42
45
  compatibilityFlags: void | string[];
43
46
  usageModel: void | "bundled" | "unbound";
47
+ buildCommand: {
48
+ command?: undefined | string;
49
+ cwd?: undefined | string;
50
+ watch_dir?: undefined | string;
51
+ };
44
52
  };
45
53
 
46
- export function Dev(props: Props): JSX.Element {
54
+ function Dev(props: Props): JSX.Element {
47
55
  if (props.public && props.format === "service-worker") {
48
56
  throw new Error(
49
57
  "You cannot use the service worker format with a `public` directory."
@@ -53,8 +61,13 @@ export function Dev(props: Props): JSX.Element {
53
61
  const apiToken = getAPIToken();
54
62
  const directory = useTmpDir();
55
63
 
64
+ // if there isn't a build command, we just return the entry immediately
65
+ // ideally there would be a conditional here, but the rules of hooks
66
+ // kinda forbid that, so we thread the entry through useCustomBuild
67
+ const entry = useCustomBuild(props.entry, props.buildCommand);
68
+
56
69
  const bundle = useEsbuild({
57
- entry: props.entry,
70
+ entry,
58
71
  destination: directory,
59
72
  staticRoot: props.public,
60
73
  jsxFactory: props.jsxFactory,
@@ -86,7 +99,7 @@ export function Dev(props: Props): JSX.Element {
86
99
  name={props.name}
87
100
  bundle={bundle}
88
101
  format={props.format}
89
- variables={props.variables}
102
+ bindings={props.bindings}
90
103
  site={props.site}
91
104
  public={props.public}
92
105
  port={props.port}
@@ -98,7 +111,7 @@ export function Dev(props: Props): JSX.Element {
98
111
  format={props.format}
99
112
  accountId={props.accountId}
100
113
  apiToken={apiToken}
101
- variables={props.variables}
114
+ bindings={props.bindings}
102
115
  site={props.site}
103
116
  public={props.public}
104
117
  port={props.port}
@@ -159,7 +172,7 @@ function Remote(props: {
159
172
  port: number;
160
173
  accountId: void | string;
161
174
  apiToken: void | string;
162
- variables: { [name: string]: CfVariable };
175
+ bindings: CfWorkerInit["bindings"];
163
176
  compatibilityDate: string | void;
164
177
  compatibilityFlags: void | string[];
165
178
  usageModel: void | "bundled" | "unbound";
@@ -173,7 +186,7 @@ function Remote(props: {
173
186
  modules: props.bundle ? props.bundle.modules : [],
174
187
  accountId: props.accountId,
175
188
  apiToken: props.apiToken,
176
- variables: props.variables,
189
+ bindings: props.bindings,
177
190
  sitesFolder: props.site,
178
191
  port: props.port,
179
192
  compatibilityDate: props.compatibilityDate,
@@ -190,7 +203,7 @@ function Local(props: {
190
203
  name: void | string;
191
204
  bundle: EsbuildBundle | void;
192
205
  format: CfScriptFormat;
193
- variables: { [name: string]: CfVariable };
206
+ bindings: CfWorkerInit["bindings"];
194
207
  public: void | string;
195
208
  site: void | string;
196
209
  port: number;
@@ -199,7 +212,7 @@ function Local(props: {
199
212
  name: props.name,
200
213
  bundle: props.bundle,
201
214
  format: props.format,
202
- variables: props.variables,
215
+ bindings: props.bindings,
203
216
  port: props.port,
204
217
  });
205
218
  useInspector(inspectorUrl);
@@ -210,11 +223,11 @@ function useLocalWorker(props: {
210
223
  name: void | string;
211
224
  bundle: EsbuildBundle | void;
212
225
  format: CfScriptFormat;
213
- variables: { [name: string]: CfVariable };
226
+ bindings: CfWorkerInit["bindings"];
214
227
  port: number;
215
228
  }) {
216
229
  // TODO: pass vars via command line
217
- const { bundle, format, variables, port } = props;
230
+ const { bundle, format, bindings, port } = props;
218
231
  const local = useRef<ReturnType<typeof spawn>>();
219
232
  const removeSignalExitListener = useRef<() => void>();
220
233
  const [inspectorUrl, setInspectorUrl] = useState<string | void>();
@@ -233,6 +246,7 @@ function useLocalWorker(props: {
233
246
  }
234
247
 
235
248
  console.log("⎔ Starting a local server...");
249
+ // TODO: just use execa for this
236
250
  local.current = spawn("node", [
237
251
  "--experimental-vm-modules",
238
252
  "--inspect",
@@ -250,20 +264,17 @@ function useLocalWorker(props: {
250
264
  "--kv-persist",
251
265
  "--cache-persist",
252
266
  "--do-persist",
253
- ...Object.entries(variables)
254
- .map(([varKey, varVal]) => {
255
- if (typeof varVal === "string") {
256
- return `--binding ${varKey}=${varVal}`;
257
- } else if (
258
- "namespaceId" in varVal &&
259
- typeof varVal.namespaceId === "string"
260
- ) {
261
- return `--kv ${varKey}`;
262
- } else if ("class_name" in varVal) {
263
- return `--do ${varKey}=${varVal.class_name}`;
264
- }
265
- })
266
- .filter(Boolean),
267
+ ...Object.entries(bindings.vars || {}).flatMap(([key, value]) => {
268
+ return ["--binding", `${key}=${value}`];
269
+ }),
270
+ ...(bindings.kv_namespaces || []).flatMap(({ binding }) => {
271
+ return ["--kv", binding];
272
+ }),
273
+ ...(bindings.durable_objects?.bindings || []).flatMap(
274
+ ({ name, class_name }) => {
275
+ return ["--do", `${name}=${class_name}`];
276
+ }
277
+ ),
267
278
  "--modules",
268
279
  format ||
269
280
  (bundle.type === "esm" ? "modules" : "service-worker") === "modules"
@@ -278,21 +289,32 @@ function useLocalWorker(props: {
278
289
  }
279
290
  });
280
291
 
281
- local.current.stdout.on("data", (_data: string) => {
282
- // console.log(`stdout: ${data}`);
292
+ local.current.stdout.on("data", (data: Buffer) => {
293
+ console.log(`${data.toString()}`);
283
294
  });
284
295
 
285
- local.current.stderr.on("data", (data: string) => {
286
- // console.error(`stderr: ${data}`);
296
+ local.current.stderr.on("data", (data: Buffer) => {
297
+ console.error(`${data.toString()}`);
287
298
  const matches =
288
299
  /Debugger listening on (ws:\/\/127\.0\.0\.1:9229\/[A-Za-z0-9-]+)/.exec(
289
- data
300
+ data.toString()
290
301
  );
291
302
  if (matches) {
292
303
  setInspectorUrl(matches[1]);
293
304
  }
294
305
  });
295
306
 
307
+ local.current.on("exit", (code) => {
308
+ if (code !== 0) {
309
+ console.error(`miniflare process exited with code ${code}`);
310
+ }
311
+ });
312
+
313
+ local.current.on("error", (error: Error) => {
314
+ console.error(`miniflare process failed to spawn`);
315
+ console.error(error);
316
+ });
317
+
296
318
  removeSignalExitListener.current = onExit((_code, _signal) => {
297
319
  console.log("⎔ Shutting down local server.");
298
320
  local.current?.kill();
@@ -300,7 +322,9 @@ function useLocalWorker(props: {
300
322
  });
301
323
  }
302
324
 
303
- startLocalWorker();
325
+ startLocalWorker().catch((err) => {
326
+ console.error("local worker:", err);
327
+ });
304
328
 
305
329
  return () => {
306
330
  if (local.current) {
@@ -311,12 +335,20 @@ function useLocalWorker(props: {
311
335
  removeSignalExitListener.current = undefined;
312
336
  }
313
337
  };
314
- }, [bundle, format, port]);
338
+ }, [
339
+ bundle,
340
+ format,
341
+ port,
342
+ bindings.durable_objects?.bindings,
343
+ bindings.kv_namespaces,
344
+ bindings.vars,
345
+ ]);
315
346
  return { inspectorUrl };
316
347
  }
317
348
 
318
349
  function useTmpDir(): string | void {
319
350
  const [directory, setDirectory] = useState<DirectoryResult>();
351
+ const handleError = useErrorHandler();
320
352
  useEffect(() => {
321
353
  let dir: DirectoryResult;
322
354
  async function create() {
@@ -326,18 +358,94 @@ function useTmpDir(): string | void {
326
358
  return;
327
359
  } catch (err) {
328
360
  console.error("failed to create tmp dir");
329
- console.error(err);
330
361
  throw err;
331
362
  }
332
363
  }
333
- create();
364
+ create().catch((err) => {
365
+ // we want to break here
366
+ // we can't do much without a temp dir anyway
367
+ handleError(err);
368
+ });
334
369
  return () => {
335
- dir.cleanup();
370
+ dir.cleanup().catch(() => {
371
+ // extremely unlikely,
372
+ // but it's 2021 after all
373
+ console.error("failed to cleanup tmp dir");
374
+ });
336
375
  };
337
- }, []);
376
+ }, [handleError]);
338
377
  return directory?.path;
339
378
  }
340
379
 
380
+ function useCustomBuild(
381
+ expectedEntry: string,
382
+ props: {
383
+ command?: undefined | string;
384
+ cwd?: undefined | string;
385
+ watch_dir?: undefined | string;
386
+ }
387
+ ): void | string {
388
+ const [entry, setEntry] = useState<string | void>(
389
+ // if there's no build command, just return the expected entry
390
+ props.command ? null : expectedEntry
391
+ );
392
+ const { command, cwd, watch_dir } = props;
393
+ useEffect(() => {
394
+ if (!command) return;
395
+ let cmd, interval;
396
+ console.log("running:", command);
397
+ const commandPieces = command.split(" ");
398
+ cmd = execa(commandPieces[0], commandPieces.slice(1), {
399
+ ...(cwd && { cwd }),
400
+ stderr: "inherit",
401
+ stdout: "inherit",
402
+ });
403
+ if (watch_dir) {
404
+ watch(watch_dir, { persistent: true, ignoreInitial: true }).on(
405
+ "all",
406
+ (_event, _path) => {
407
+ console.log(`The file ${path} changed, restarting build...`);
408
+ cmd.kill();
409
+ cmd = execa(commandPieces[0], commandPieces.slice(1), {
410
+ ...(cwd && { cwd }),
411
+ stderr: "inherit",
412
+ stdout: "inherit",
413
+ });
414
+ }
415
+ );
416
+ }
417
+
418
+ // check every so often whether `expectedEntry` exists
419
+ // if it does, we're done
420
+ const startedAt = Date.now();
421
+ interval = setInterval(() => {
422
+ if (existsSync(expectedEntry)) {
423
+ clearInterval(interval);
424
+ setEntry(expectedEntry);
425
+ } else {
426
+ const elapsed = Date.now() - startedAt;
427
+ // timeout after 30 seconds of waiting
428
+ if (elapsed > 1000 * 60 * 30) {
429
+ console.error("⎔ Build timed out.");
430
+ clearInterval(interval);
431
+ cmd.kill();
432
+ }
433
+ }
434
+ }, 200);
435
+ // TODO: we could probably timeout here after a while
436
+
437
+ return () => {
438
+ if (cmd) {
439
+ cmd.kill();
440
+ cmd = undefined;
441
+ }
442
+ clearInterval(interval);
443
+ interval = undefined;
444
+ };
445
+ }, [command, cwd, expectedEntry, watch_dir]);
446
+ return entry;
447
+ }
448
+
341
449
  type EsbuildBundle = {
342
450
  id: number;
343
451
  path: string;
@@ -348,7 +456,7 @@ type EsbuildBundle = {
348
456
  };
349
457
 
350
458
  function useEsbuild(props: {
351
- entry: string;
459
+ entry: void | string;
352
460
  destination: string | void;
353
461
  staticRoot: void | string;
354
462
  jsxFactory: string | void;
@@ -359,7 +467,7 @@ function useEsbuild(props: {
359
467
  useEffect(() => {
360
468
  let result: esbuild.BuildResult;
361
469
  async function build() {
362
- if (!destination) return;
470
+ if (!destination || !entry) return;
363
471
  const moduleCollector = makeModuleCollector();
364
472
  result = await esbuild.build({
365
473
  entryPoints: [entry],
@@ -383,7 +491,10 @@ function useEsbuild(props: {
383
491
  else {
384
492
  // nothing really changes here, so let's increment the id
385
493
  // to change the return object's identity
386
- setBundle((bundle) => ({ ...bundle, id: bundle.id + 1 }));
494
+ setBundle((previousBundle) => ({
495
+ ...previousBundle,
496
+ id: previousBundle.id + 1,
497
+ }));
387
498
  }
388
499
  },
389
500
  },
@@ -402,7 +513,12 @@ function useEsbuild(props: {
402
513
  modules: moduleCollector.modules,
403
514
  });
404
515
  }
405
- build();
516
+ build().catch((_err) => {
517
+ // esbuild already logs errors to stderr
518
+ // and we don't want to end the process
519
+ // on build errors anyway
520
+ // so this is a no-op error handler
521
+ });
406
522
  return () => {
407
523
  result?.stop();
408
524
  };
@@ -417,7 +533,7 @@ function useWorker(props: {
417
533
  modules: CfModule[];
418
534
  accountId: string;
419
535
  apiToken: string;
420
- variables: { [name: string]: CfVariable };
536
+ bindings: CfWorkerInit["bindings"];
421
537
  sitesFolder: void | string;
422
538
  port: number;
423
539
  compatibilityDate: string | void;
@@ -431,7 +547,7 @@ function useWorker(props: {
431
547
  modules,
432
548
  accountId,
433
549
  apiToken,
434
- variables,
550
+ bindings,
435
551
  sitesFolder,
436
552
  compatibilityDate,
437
553
  compatibilityFlags,
@@ -439,6 +555,12 @@ function useWorker(props: {
439
555
  port,
440
556
  } = props;
441
557
  const [token, setToken] = useState<CfPreviewToken>();
558
+
559
+ // This is the most reliable way to detect whether
560
+ // something's "happened" in our system; We make a ref and
561
+ // mark it once we log our initial message. Refs are vars!
562
+ const startedRef = useRef(false);
563
+
442
564
  useEffect(() => {
443
565
  async function start() {
444
566
  if (!bundle) return;
@@ -453,10 +575,11 @@ function useWorker(props: {
453
575
  return;
454
576
  }
455
577
 
456
- if (token) {
457
- console.log("⎔ Detected changes, restarting server...");
458
- } else {
578
+ if (!startedRef.current) {
459
579
  console.log("⎔ Starting server...");
580
+ startedRef.current = true;
581
+ } else {
582
+ console.log("⎔ Detected changes, restarting server...");
460
583
  }
461
584
 
462
585
  const assets = sitesFolder
@@ -480,19 +603,23 @@ function useWorker(props: {
480
603
  type: format || bundle.type === "esm" ? "esm" : "commonjs",
481
604
  content,
482
605
  },
483
- modules: assets.manifest
484
- ? modules.concat({
485
- name: "__STATIC_CONTENT_MANIFEST",
486
- content: JSON.stringify(assets.manifest),
487
- type: "text",
488
- })
489
- : modules,
490
- variables: assets.namespace
491
- ? {
492
- ...variables,
493
- __STATIC_CONTENT: { namespaceId: assets.namespace },
494
- }
495
- : variables,
606
+ modules: modules.concat(
607
+ assets.manifest
608
+ ? {
609
+ name: "__STATIC_CONTENT_MANIFEST",
610
+ content: JSON.stringify(assets.manifest),
611
+ type: "text",
612
+ }
613
+ : []
614
+ ),
615
+ bindings: {
616
+ ...bindings,
617
+ kv_namespaces: (bindings.kv_namespaces || []).concat(
618
+ assets.namespace
619
+ ? { binding: "__STATIC_CONTENT", id: assets.namespace }
620
+ : []
621
+ ),
622
+ },
496
623
  migrations: undefined, // no migrations in dev
497
624
  compatibility_date: compatibilityDate,
498
625
  compatibility_flags: compatibilityFlags,
@@ -504,9 +631,12 @@ function useWorker(props: {
504
631
  apiToken,
505
632
  })
506
633
  );
507
- console.log(`⬣ Listening at http://localhost:${port}`);
508
634
  }
509
- start();
635
+ start().catch((err) => {
636
+ // we want to log the error, but not end the process
637
+ // since it could recover after the developer fixes whatever's wrong
638
+ console.error("remote worker:", err);
639
+ });
510
640
  }, [
511
641
  name,
512
642
  bundle,
@@ -518,6 +648,8 @@ function useWorker(props: {
518
648
  compatibilityDate,
519
649
  compatibilityFlags,
520
650
  usageModel,
651
+ bindings,
652
+ modules,
521
653
  ]);
522
654
  return token;
523
655
  }
@@ -533,43 +665,53 @@ function useProxy({
533
665
  }) {
534
666
  useEffect(() => {
535
667
  if (!token) return;
536
- const proxy = httpProxy.createProxyServer({
537
- secure: false,
538
- changeOrigin: true,
539
- headers: {
540
- "cf-workers-preview-token": token.value,
668
+ // TODO(soon): since headers are added in callbacks, the server
669
+ // does not need to restart when changes are made.
670
+ const host = token.host;
671
+ const proxy = createHttpProxy({
672
+ host,
673
+ assetPath: typeof publicRoot === "string" ? publicRoot : null,
674
+ onRequest: (headers) => {
675
+ headers["cf-workers-preview-token"] = token.value;
676
+ },
677
+ onResponse: (headers) => {
678
+ for (const [name, value] of Object.entries(headers)) {
679
+ // Rewrite the remote host to the local host.
680
+ if (typeof value === "string" && value.includes(host)) {
681
+ headers[name] = value
682
+ .replaceAll(`https://${host}`, `http://localhost:${port}`)
683
+ .replaceAll(host, `localhost:${port}`);
684
+ }
685
+ }
541
686
  },
542
- target: `https://${token.host}`,
543
- // TODO: log websockets too? validate durables, etc
544
687
  });
545
688
 
546
- const servePublic =
547
- publicRoot &&
548
- serveStatic(publicRoot, {
549
- cacheControl: false,
550
- });
551
- const server = http
552
- .createServer((req, res) => {
553
- if (publicRoot) {
554
- servePublic(req, res, () => {
555
- proxy.web(req, res);
556
- });
557
- } else {
558
- proxy.web(req, res);
559
- }
560
- })
561
- .listen(port); // TODO: custom port
689
+ console.log(`⬣ Listening at http://localhost:${port}`);
562
690
 
563
- proxy.on("proxyRes", function (proxyRes, req, res) {
691
+ const server = proxy.listen(port);
692
+
693
+ // TODO(soon): refactor logging format into its own function
694
+ proxy.on("request", function (req, res) {
564
695
  // log all requests
565
696
  console.log(
566
697
  new Date().toLocaleTimeString(),
567
698
  req.method,
568
699
  req.url,
569
- res.statusCode // TODO add a status message like Ok etc?
700
+ res.statusCode
570
701
  );
571
702
  });
572
- // TODO: log errors?
703
+ proxy.on("upgrade", (req) => {
704
+ console.log(
705
+ new Date().toLocaleTimeString(),
706
+ req.method,
707
+ req.url,
708
+ 101,
709
+ "(WebSocket)"
710
+ );
711
+ });
712
+ proxy.on("error", (err) => {
713
+ console.error(new Date().toLocaleTimeString(), err);
714
+ });
573
715
 
574
716
  return () => {
575
717
  proxy.close();
@@ -650,12 +792,14 @@ function useTunnel(toggle: boolean) {
650
792
  });
651
793
 
652
794
  const hostName = await findTunnelHostname();
653
- clipboardy.write(hostName);
795
+ await clipboardy.write(hostName);
654
796
  console.log(`⬣ Sharing at ${hostName}, copied to clipboard.`);
655
797
  }
656
798
  }
657
799
 
658
- startTunnel();
800
+ startTunnel().catch((err) => {
801
+ console.error("tunnel:", err);
802
+ });
659
803
 
660
804
  return () => {
661
805
  if (tunnel.current) {
@@ -677,38 +821,31 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
677
821
  // UGH, we should put port in context instead
678
822
  const [toggles, setToggles] = useState(initial);
679
823
  useInput(
680
- (
824
+ async (
681
825
  input,
682
826
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
683
827
  key
684
828
  ) => {
685
829
  switch (input) {
686
830
  case "b": // open browser
687
- open(
688
- `http://localhost:${port}/`
689
- // {
690
- // app: {
691
- // name: open.apps.chrome, // TODO: fallback on other browsers
692
- // },
693
- // }
694
- );
831
+ await open(`http://localhost:${port}/`);
695
832
  break;
696
833
  case "d": // toggle inspector
697
- open(
834
+ await open(
698
835
  `https://built-devtools.pages.dev/js_app?experiments=true&v8only=true&ws=localhost:9229/ws`
699
- // {
700
- // app: {
701
- // name: open.apps.chrome,
702
- // // todo - add firefox and edge fallbacks
703
- // },
704
- // }
705
836
  );
706
837
  break;
707
838
  case "s": // toggle tunnel
708
- setToggles((toggles) => ({ ...toggles, tunnel: !toggles.tunnel }));
839
+ setToggles((previousToggles) => ({
840
+ ...previousToggles,
841
+ tunnel: !previousToggles.tunnel,
842
+ }));
709
843
  break;
710
844
  case "l": // toggle local
711
- setToggles((toggles) => ({ ...toggles, local: !toggles.local }));
845
+ setToggles((previousToggles) => ({
846
+ ...previousToggles,
847
+ local: !previousToggles.local,
848
+ }));
712
849
  break;
713
850
  case "q": // shut down
714
851
  case "x": // shut down
@@ -722,3 +859,21 @@ function useHotkeys(initial: useHotkeysInitialState, port: number) {
722
859
  );
723
860
  return toggles;
724
861
  }
862
+
863
+ function ErrorFallback(props: {
864
+ error: Error;
865
+ resetErrorBoundary: () => void;
866
+ }) {
867
+ useEffect(() => {
868
+ console.error(props.error);
869
+ process.exit(1);
870
+ });
871
+ return (
872
+ <Box>
873
+ <Text>Something went wrong:</Text>
874
+ <Text>{props.error.message}</Text>
875
+ </Box>
876
+ );
877
+ }
878
+
879
+ 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) => {
@@ -67,19 +67,11 @@ export async function prompt(text: string, type: "text" | "password" = "text") {
67
67
  <Prompt
68
68
  text={text}
69
69
  type={type}
70
- onSubmit={(text) => {
70
+ onSubmit={(inputText) => {
71
71
  unmount();
72
- resolve(text);
72
+ resolve(inputText);
73
73
  }}
74
74
  />
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
- // }