wrangler 2.1.6 → 2.1.7

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 (51) hide show
  1. package/miniflare-dist/index.mjs +5 -20
  2. package/package.json +13 -3
  3. package/src/__tests__/api-dev.test.ts +20 -0
  4. package/src/__tests__/configuration.test.ts +125 -22
  5. package/src/__tests__/dev.test.tsx +0 -2
  6. package/src/__tests__/helpers/mock-oauth-flow.ts +4 -2
  7. package/src/__tests__/index.test.ts +2 -0
  8. package/src/__tests__/paths.test.ts +23 -1
  9. package/src/__tests__/publish.test.ts +8 -10
  10. package/src/__tests__/user.test.ts +4 -4
  11. package/src/__tests__/whoami.test.tsx +0 -1
  12. package/src/__tests__/worker-namespace.test.ts +102 -112
  13. package/src/api/dev.ts +12 -12
  14. package/src/bundle.ts +48 -0
  15. package/src/cfetch/internal.ts +37 -21
  16. package/src/config/environment.ts +20 -0
  17. package/src/config/index.ts +32 -0
  18. package/src/config/validation.ts +59 -0
  19. package/src/config-cache.ts +1 -1
  20. package/src/create-worker-upload-form.ts +9 -0
  21. package/src/d1/backups.tsx +212 -0
  22. package/src/d1/create.tsx +54 -0
  23. package/src/d1/delete.tsx +56 -0
  24. package/src/d1/execute.tsx +294 -0
  25. package/src/d1/formatTimeAgo.ts +14 -0
  26. package/src/d1/index.ts +75 -0
  27. package/src/d1/list.tsx +48 -0
  28. package/src/d1/options.ts +12 -0
  29. package/src/d1/types.tsx +14 -0
  30. package/src/d1/utils.ts +39 -0
  31. package/src/dev/dev.tsx +26 -3
  32. package/src/dev/get-local-persistence-path.tsx +31 -0
  33. package/src/dev/local.tsx +8 -8
  34. package/src/dev/start-server.ts +2 -3
  35. package/src/dev/use-esbuild.ts +8 -1
  36. package/src/dev.tsx +28 -28
  37. package/src/dialogs.tsx +4 -0
  38. package/src/environment-variables.ts +17 -2
  39. package/src/index.tsx +18 -16
  40. package/src/logger.ts +11 -4
  41. package/src/miniflare-cli/index.ts +11 -16
  42. package/src/pages/dev.tsx +13 -9
  43. package/src/paths.ts +30 -4
  44. package/src/proxy.ts +21 -1
  45. package/src/publish.ts +6 -0
  46. package/src/user/user.tsx +1 -0
  47. package/src/worker.ts +30 -0
  48. package/templates/d1-beta-facade.js +174 -0
  49. package/wrangler-dist/cli.d.ts +438 -7
  50. package/wrangler-dist/cli.js +10925 -3223
  51. package/src/miniflare-cli/enum-keys.ts +0 -17
package/src/dev/local.tsx CHANGED
@@ -24,6 +24,7 @@ import type {
24
24
  CfKvNamespace,
25
25
  CfR2Bucket,
26
26
  CfVars,
27
+ CfD1Database,
27
28
  } from "../worker";
28
29
  import type { EsbuildBundle } from "./use-esbuild";
29
30
  import type { MiniflareOptions } from "miniflare";
@@ -49,7 +50,6 @@ export interface LocalProps {
49
50
  localUpstream: string | undefined;
50
51
  inspect: boolean;
51
52
  onReady: ((ip: string, port: number) => void) | undefined;
52
- logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
53
53
  logPrefix?: string;
54
54
  enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
55
55
  testScheduled?: boolean;
@@ -86,7 +86,6 @@ function useLocalWorker({
86
86
  localUpstream,
87
87
  inspect,
88
88
  onReady,
89
- logLevel,
90
89
  logPrefix,
91
90
  enablePagesAssetsServiceBinding,
92
91
  }: LocalProps) {
@@ -171,6 +170,7 @@ function useLocalWorker({
171
170
  usageModel,
172
171
  kv_namespaces: bindings?.kv_namespaces,
173
172
  r2_buckets: bindings?.r2_buckets,
173
+ d1_databases: bindings?.d1_databases,
174
174
  internalDurableObjects,
175
175
  externalDurableObjects,
176
176
  localPersistencePath,
@@ -182,7 +182,6 @@ function useLocalWorker({
182
182
  dataBlobBindings,
183
183
  crons,
184
184
  upstream,
185
- logLevel,
186
185
  logPrefix,
187
186
  workerDefinitions,
188
187
  enablePagesAssetsServiceBinding,
@@ -294,6 +293,7 @@ function useLocalWorker({
294
293
  bindings.durable_objects,
295
294
  bindings.kv_namespaces,
296
295
  bindings.r2_buckets,
296
+ bindings.d1_databases,
297
297
  bindings.vars,
298
298
  bindings.services,
299
299
  workerDefinitions,
@@ -311,7 +311,6 @@ function useLocalWorker({
311
311
  localProtocol,
312
312
  localUpstream,
313
313
  inspect,
314
- logLevel,
315
314
  logPrefix,
316
315
  onReady,
317
316
  enablePagesAssetsServiceBinding,
@@ -414,6 +413,7 @@ interface SetupMiniflareOptionsProps {
414
413
  usageModel: "bundled" | "unbound" | undefined;
415
414
  kv_namespaces: CfKvNamespace[] | undefined;
416
415
  r2_buckets: CfR2Bucket[] | undefined;
416
+ d1_databases: CfD1Database[] | undefined;
417
417
  internalDurableObjects: CfDurableObject[];
418
418
  externalDurableObjects: CfDurableObject[];
419
419
  localPersistencePath: string | null;
@@ -425,7 +425,6 @@ interface SetupMiniflareOptionsProps {
425
425
  dataBlobBindings: Record<string, string>;
426
426
  crons: Config["triggers"]["crons"];
427
427
  upstream: string | undefined;
428
- logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
429
428
  logPrefix: string | undefined;
430
429
  workerDefinitions: WorkerRegistry | undefined;
431
430
  enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
@@ -444,6 +443,7 @@ export function setupMiniflareOptions({
444
443
  usageModel,
445
444
  kv_namespaces,
446
445
  r2_buckets,
446
+ d1_databases,
447
447
  internalDurableObjects,
448
448
  externalDurableObjects,
449
449
  localPersistencePath,
@@ -455,12 +455,10 @@ export function setupMiniflareOptions({
455
455
  dataBlobBindings,
456
456
  crons,
457
457
  upstream,
458
- logLevel,
459
458
  logPrefix,
460
459
  workerDefinitions,
461
460
  enablePagesAssetsServiceBinding,
462
461
  }: SetupMiniflareOptionsProps): MiniflareOptions {
463
- // TODO: This was already messy with the custom `disableLogs` and `logOptions`.
464
462
  // It's now getting _really_ messy now with Pages ASSETS binding outside and the external Durable Objects inside.
465
463
  const options = {
466
464
  name: workerName,
@@ -511,12 +509,14 @@ export function setupMiniflareOptions({
511
509
  })
512
510
  .filter(([_, details]) => !!details)
513
511
  ),
512
+ d1Databases: d1_databases?.map((db) => db.binding),
514
513
  ...(localPersistencePath
515
514
  ? {
516
515
  cachePersist: path.join(localPersistencePath, "cache"),
517
516
  durableObjectsPersist: path.join(localPersistencePath, "do"),
518
517
  kvPersist: path.join(localPersistencePath, "kv"),
519
518
  r2Persist: path.join(localPersistencePath, "r2"),
519
+ d1Persist: path.join(localPersistencePath, "d1"),
520
520
  }
521
521
  : {
522
522
  // We mark these as true, so that they'll
@@ -548,7 +548,7 @@ export function setupMiniflareOptions({
548
548
  logUnhandledRejections: true,
549
549
  crons,
550
550
  upstream,
551
- disableLogs: logLevel === "none",
551
+ logLevel: logger.loggerLevel,
552
552
  logOptions: logPrefix ? { prefix: logPrefix } : undefined,
553
553
  enablePagesAssetsServiceBinding,
554
554
  };
@@ -111,7 +111,6 @@ export async function startDevServer(
111
111
  crons: props.crons,
112
112
  localProtocol: props.localProtocol,
113
113
  localUpstream: props.localUpstream,
114
- logLevel: props.logLevel,
115
114
  logPrefix: props.logPrefix,
116
115
  inspect: props.inspect,
117
116
  onReady: props.onReady,
@@ -212,6 +211,7 @@ async function runEsbuild({
212
211
  services,
213
212
  firstPartyWorkerDevFacade,
214
213
  targetConsumer: "dev", // We are starting a dev server
214
+ local: false,
215
215
  testScheduled,
216
216
  });
217
217
 
@@ -246,7 +246,6 @@ export async function startLocalServer({
246
246
  localUpstream,
247
247
  inspect,
248
248
  onReady,
249
- logLevel,
250
249
  logPrefix,
251
250
  enablePagesAssetsServiceBinding,
252
251
  }: LocalProps) {
@@ -321,6 +320,7 @@ export async function startLocalServer({
321
320
  usageModel,
322
321
  kv_namespaces: bindings?.kv_namespaces,
323
322
  r2_buckets: bindings?.r2_buckets,
323
+ d1_databases: bindings?.d1_databases,
324
324
  internalDurableObjects,
325
325
  externalDurableObjects,
326
326
  localPersistencePath,
@@ -332,7 +332,6 @@ export async function startLocalServer({
332
332
  dataBlobBindings,
333
333
  crons,
334
334
  upstream,
335
- logLevel,
336
335
  logPrefix,
337
336
  workerDefinitions,
338
337
  enablePagesAssetsServiceBinding,
@@ -30,12 +30,14 @@ export function useEsbuild({
30
30
  tsconfig,
31
31
  minify,
32
32
  nodeCompat,
33
+ betaD1Shims,
33
34
  define,
34
35
  noBundle,
35
36
  workerDefinitions,
36
37
  services,
37
38
  durableObjects,
38
39
  firstPartyWorkerDevFacade,
40
+ local,
39
41
  targetConsumer,
40
42
  testScheduled,
41
43
  }: {
@@ -51,10 +53,12 @@ export function useEsbuild({
51
53
  tsconfig: string | undefined;
52
54
  minify: boolean | undefined;
53
55
  nodeCompat: boolean | undefined;
56
+ betaD1Shims?: string[];
54
57
  noBundle: boolean;
55
58
  workerDefinitions: WorkerRegistry;
56
59
  durableObjects: Config["durable_objects"];
57
60
  firstPartyWorkerDevFacade: boolean | undefined;
61
+ local: boolean;
58
62
  targetConsumer: "dev" | "publish";
59
63
  testScheduled: boolean;
60
64
  }): EsbuildBundle | undefined {
@@ -110,6 +114,7 @@ export function useEsbuild({
110
114
  tsconfig,
111
115
  minify,
112
116
  nodeCompat,
117
+ betaD1Shims,
113
118
  define,
114
119
  checkFetch: true,
115
120
  assets: assets && {
@@ -120,6 +125,7 @@ export function useEsbuild({
120
125
  workerDefinitions,
121
126
  services,
122
127
  firstPartyWorkerDevFacade,
128
+ local,
123
129
  targetConsumer,
124
130
  testScheduled,
125
131
  });
@@ -140,7 +146,6 @@ export function useEsbuild({
140
146
  watcher.close();
141
147
  };
142
148
  }
143
-
144
149
  setBundle({
145
150
  id: 0,
146
151
  entry,
@@ -179,6 +184,8 @@ export function useEsbuild({
179
184
  durableObjects,
180
185
  workerDefinitions,
181
186
  firstPartyWorkerDevFacade,
187
+ betaD1Shims,
188
+ local,
182
189
  targetConsumer,
183
190
  testScheduled,
184
191
  ]);
package/src/dev.tsx CHANGED
@@ -6,6 +6,7 @@ import React from "react";
6
6
  import { findWranglerToml, printBindings, readConfig } from "./config";
7
7
  import Dev from "./dev/dev";
8
8
  import { getVarsForDev } from "./dev/dev-vars";
9
+ import { getLocalPersistencePath } from "./dev/get-local-persistence-path";
9
10
 
10
11
  import { startDevServer } from "./dev/start-server";
11
12
  import { getEntry } from "./entry";
@@ -13,18 +14,19 @@ import { logger } from "./logger";
13
14
  import * as metrics from "./metrics";
14
15
  import { getAssetPaths, getSiteAssetPaths } from "./sites";
15
16
  import { getAccountFromCache } from "./user";
16
- import { getZoneIdFromHost, getZoneForRoute, getHostFromRoute } from "./zones";
17
+ import { identifyD1BindingsAsBeta } from "./worker";
18
+ import { getHostFromRoute, getZoneForRoute, getZoneIdFromHost } from "./zones";
17
19
  import {
18
- printWranglerBanner,
19
- DEFAULT_LOCAL_PORT,
20
20
  type ConfigPath,
21
- getScriptName,
21
+ DEFAULT_INSPECTOR_PORT,
22
+ DEFAULT_LOCAL_PORT,
22
23
  getDevCompatibilityDate,
23
24
  getRules,
25
+ getScriptName,
24
26
  isLegacyEnv,
25
- DEFAULT_INSPECTOR_PORT,
27
+ printWranglerBanner,
26
28
  } from "./index";
27
- import type { Config } from "./config";
29
+ import type { Config, Environment } from "./config";
28
30
  import type { Route } from "./config/environment";
29
31
  import type { EnablePagesAssetsServiceBindingOptions } from "./miniflare-cli";
30
32
  import type { CfWorkerInit } from "./worker";
@@ -69,7 +71,7 @@ interface DevArgs {
69
71
  "persist-to"?: string;
70
72
  "live-reload"?: boolean;
71
73
  onReady?: (ip: string, port: number) => void;
72
- logLevel?: "none" | "error" | "log" | "warn" | "debug";
74
+ logLevel?: "none" | "info" | "error" | "log" | "warn" | "debug";
73
75
  logPrefix?: string;
74
76
  showInteractiveDevSession?: boolean;
75
77
  "test-scheduled"?: boolean;
@@ -280,7 +282,6 @@ export function devOptions(yargs: Argv): Argv<DevArgs> {
280
282
  default: false,
281
283
  })
282
284
  .option("log-level", {
283
- // "none" will currently default to "error" for Wrangler Logger
284
285
  choices: ["debug", "info", "log", "warn", "error", "none"] as const,
285
286
  describe: "Specify logging level",
286
287
  default: "log",
@@ -320,6 +321,7 @@ export type AdditionalDevProps = {
320
321
  bucket_name: string;
321
322
  preview_bucket_name?: string;
322
323
  }[];
324
+ d1Databases?: Environment["d1_databases"];
323
325
  };
324
326
 
325
327
  type StartDevOptions = ArgumentsCamelCase<DevArgs> &
@@ -335,8 +337,7 @@ export async function startDev(args: StartDevOptions) {
335
337
  let rerender: (node: React.ReactNode) => void | undefined;
336
338
  try {
337
339
  if (args.logLevel) {
338
- // we don't define a "none" logLevel, so "error" will do for now.
339
- logger.loggerLevel = args.logLevel === "none" ? "error" : args.logLevel;
340
+ logger.loggerLevel = args.logLevel;
340
341
  }
341
342
  await printWranglerBanner();
342
343
 
@@ -434,7 +435,6 @@ export async function startDev(args: StartDevOptions) {
434
435
  usageModel={configParam.usage_model}
435
436
  bindings={bindings}
436
437
  crons={configParam.triggers.crons}
437
- logLevel={args.logLevel}
438
438
  logPrefix={args.logPrefix}
439
439
  onReady={args.onReady}
440
440
  inspect={args.inspect ?? true}
@@ -464,8 +464,7 @@ export async function startDev(args: StartDevOptions) {
464
464
 
465
465
  export async function startApiDev(args: StartDevOptions) {
466
466
  if (args.logLevel) {
467
- // we don't define a "none" logLevel, so "error" will do for now.
468
- logger.loggerLevel = args.logLevel === "none" ? "error" : args.logLevel;
467
+ logger.loggerLevel = args.logLevel;
469
468
  }
470
469
  await printWranglerBanner();
471
470
 
@@ -501,9 +500,13 @@ export async function startApiDev(args: StartDevOptions) {
501
500
  configParam
502
501
  );
503
502
 
503
+ //if args.bundle is on, don't disable bundling
504
+ //if there's no args.bundle, and configParam.no_bundle is on, disable bundling
505
+ //otherwise, enable bundling
506
+ const enableBundling = args.bundle ?? !configParam.no_bundle;
504
507
  return await startDevServer({
505
508
  name: getScriptName({ name: args.name, env: args.env }, configParam),
506
- noBundle: !(args.bundle ?? !configParam.no_bundle),
509
+ noBundle: !enableBundling,
507
510
  entry: entry,
508
511
  env: args.env,
509
512
  zone: zoneId,
@@ -522,7 +525,7 @@ export async function startApiDev(args: StartDevOptions) {
522
525
  upstreamProtocol: upstreamProtocol,
523
526
  localProtocol: args.localProtocol || configParam.dev.local_protocol,
524
527
  localUpstream: args["local-upstream"] || host,
525
- localPersistencePath: localPersistencePath,
528
+ localPersistencePath,
526
529
  liveReload: args.liveReload || false,
527
530
  accountId: configParam.account_id || getAccountFromCache()?.id,
528
531
  assetPaths: assetPaths,
@@ -547,7 +550,6 @@ export async function startApiDev(args: StartDevOptions) {
547
550
  usageModel: configParam.usage_model,
548
551
  bindings: bindings,
549
552
  crons: configParam.triggers.crons,
550
- logLevel: args.logLevel,
551
553
  logPrefix: args.logPrefix,
552
554
  onReady: args.onReady,
553
555
  inspect: args.inspect ?? true,
@@ -683,7 +685,6 @@ async function validateDevServerSettings(
683
685
  "The --assets argument is experimental and may change or break at any time"
684
686
  );
685
687
  }
686
-
687
688
  const upstreamProtocol =
688
689
  args["upstream-protocol"] || config.dev.upstream_protocol;
689
690
  if (upstreamProtocol === "http") {
@@ -708,17 +709,11 @@ async function validateDevServerSettings(
708
709
  );
709
710
  }
710
711
 
711
- const localPersistencePath = args.persistTo
712
- ? // If path specified, always treat it as relative to cwd()
713
- path.resolve(process.cwd(), args.persistTo)
714
- : args.persist
715
- ? // If just flagged on, treat it as relative to wrangler.toml,
716
- // if one can be found, otherwise cwd()
717
- path.resolve(
718
- config.configPath ? path.dirname(config.configPath) : process.cwd(),
719
- ".wrangler/state"
720
- )
721
- : null;
712
+ const localPersistencePath = getLocalPersistencePath(
713
+ args.persistTo,
714
+ Boolean(args.persist),
715
+ config.configPath
716
+ );
722
717
 
723
718
  const cliDefines =
724
719
  args.define?.reduce<Record<string, string>>((collectDefines, d) => {
@@ -758,6 +753,7 @@ async function getBindingsAndAssetPaths(
758
753
  vars: { ...args.vars, ...cliVars },
759
754
  durableObjects: args.durableObjects,
760
755
  r2: args.r2,
756
+ d1Databases: args.d1Databases,
761
757
  });
762
758
 
763
759
  const maskedVars = maskVars(bindings, configParam);
@@ -844,6 +840,10 @@ async function getBindings(
844
840
  services: configParam.services,
845
841
  unsafe: configParam.unsafe?.bindings,
846
842
  logfwdr: configParam.logfwdr,
843
+ d1_databases: identifyD1BindingsAsBeta([
844
+ ...configParam.d1_databases,
845
+ ...(args.d1Databases || []),
846
+ ]),
847
847
  };
848
848
 
849
849
  return bindings;
package/src/dialogs.tsx CHANGED
@@ -138,6 +138,10 @@ export function select(
138
138
  });
139
139
  }
140
140
 
141
+ export function logDim(msg: string) {
142
+ console.log(chalk.gray(msg));
143
+ }
144
+
141
145
  export async function fromDashMessagePrompt(
142
146
  deploySource: "dash" | "wrangler" | "api"
143
147
  ): Promise<boolean | void> {
@@ -1,5 +1,20 @@
1
1
  import { logger } from "./logger";
2
2
 
3
+ type VariableNames =
4
+ | "CLOUDFLARE_ACCOUNT_ID"
5
+ | "CLOUDFLARE_API_TOKEN"
6
+ | "CLOUDFLARE_API_KEY"
7
+ | "CLOUDFLARE_EMAIL"
8
+ | "WRANGLER_SEND_METRICS"
9
+ | "CLOUDFLARE_API_BASE_URL"
10
+ | "WRANGLER_LOG";
11
+
12
+ type DeprecatedNames =
13
+ | "CF_ACCOUNT_ID"
14
+ | "CF_API_TOKEN"
15
+ | "CF_API_KEY"
16
+ | "CF_EMAIL"
17
+ | "CF_API_BASE_URL";
3
18
  /**
4
19
  * Create a function used to access an environment variable.
5
20
  *
@@ -11,8 +26,8 @@ export function getEnvironmentVariableFactory({
11
26
  deprecatedName,
12
27
  defaultValue,
13
28
  }: {
14
- variableName: string;
15
- deprecatedName?: string;
29
+ variableName: VariableNames;
30
+ deprecatedName?: DeprecatedNames;
16
31
  defaultValue?: string;
17
32
  }) {
18
33
  let hasWarned = false;
package/src/index.tsx CHANGED
@@ -7,33 +7,34 @@ import TOML from "@iarna/toml";
7
7
  import chalk from "chalk";
8
8
  import onExit from "signal-exit";
9
9
  import supportsColor from "supports-color";
10
- import { setGlobalDispatcher, ProxyAgent } from "undici";
10
+ import { ProxyAgent, setGlobalDispatcher } from "undici";
11
11
  import makeCLI from "yargs";
12
12
  import { version as wranglerVersion } from "../package.json";
13
13
  import { fetchResult } from "./cfetch";
14
14
  import { findWranglerToml, readConfig } from "./config";
15
15
  import { createWorkerUploadForm } from "./create-worker-upload-form";
16
+ import { d1api } from "./d1";
16
17
  import { devHandler, devOptions } from "./dev";
17
18
  import { confirm, prompt } from "./dialogs";
18
19
  import { workerNamespaceCommands } from "./dispatch-namespace";
19
20
  import { getEntry } from "./entry";
20
21
  import { DeprecationError } from "./errors";
21
22
  import { generateHandler, generateOptions } from "./generate";
22
- import { initOptions, initHandler } from "./init";
23
+ import { initHandler, initOptions } from "./init";
23
24
  import {
24
- getKVNamespaceId,
25
- listKVNamespaces,
26
- listKVNamespaceKeys,
27
- putKVKeyValue,
28
- putKVBulkKeyValue,
29
- deleteKVBulkKeyValue,
30
25
  createKVNamespace,
31
- isValidKVNamespaceBinding,
26
+ deleteKVBulkKeyValue,
27
+ deleteKVKeyValue,
28
+ deleteKVNamespace,
32
29
  getKVKeyValue,
30
+ getKVNamespaceId,
33
31
  isKVKeyValue,
32
+ isValidKVNamespaceBinding,
33
+ listKVNamespaceKeys,
34
+ listKVNamespaces,
35
+ putKVBulkKeyValue,
36
+ putKVKeyValue,
34
37
  unexpectedKVKeyValueProps,
35
- deleteKVNamespace,
36
- deleteKVKeyValue,
37
38
  } from "./kv";
38
39
  import { logger } from "./logger";
39
40
  import * as metrics from "./metrics";
@@ -66,11 +67,11 @@ import {
66
67
  } from "./tail";
67
68
  import { updateCheck } from "./update-check";
68
69
  import {
70
+ listScopes,
69
71
  login,
70
72
  logout,
71
- listScopes,
72
- validateScopeKeys,
73
73
  requireAuth,
74
+ validateScopeKeys,
74
75
  } from "./user";
75
76
  import { whoami } from "./whoami";
76
77
 
@@ -80,7 +81,6 @@ import type { KeyValue } from "./kv";
80
81
  import type { TailCLIFilters } from "./tail";
81
82
  import type { Readable } from "node:stream";
82
83
  import type { RawData } from "ws";
83
- import type { CommandModule } from "yargs";
84
84
  import type Yargs from "yargs";
85
85
 
86
86
  export type ConfigPath = string | undefined;
@@ -262,7 +262,7 @@ function createCLIParser(argv: string[]) {
262
262
  .wrap(null);
263
263
 
264
264
  // Default help command that supports the subcommands
265
- const subHelp: CommandModule = {
265
+ const subHelp: Yargs.CommandModule = {
266
266
  command: ["*"],
267
267
  handler: async (args) => {
268
268
  setImmediate(() =>
@@ -578,7 +578,6 @@ function createCLIParser(argv: string[]) {
578
578
  "The --assets argument is experimental and may change or break at any time"
579
579
  );
580
580
  }
581
-
582
581
  if (args.latest) {
583
582
  logger.warn(
584
583
  "Using the latest version of the Workers runtime. To silence this warning, please choose a specific version of the runtime with --compatibility-date, or add a compatibility_date to your wrangler.toml.\n"
@@ -1015,6 +1014,7 @@ function createCLIParser(argv: string[]) {
1015
1014
  vars: {},
1016
1015
  durable_objects: { bindings: [] },
1017
1016
  r2_buckets: [],
1017
+ d1_databases: [],
1018
1018
  services: [],
1019
1019
  wasm_modules: {},
1020
1020
  text_blobs: {},
@@ -2182,6 +2182,8 @@ function createCLIParser(argv: string[]) {
2182
2182
  }
2183
2183
  );
2184
2184
 
2185
+ wrangler.command("d1", "🗄 Interact with a D1 database", d1api);
2186
+
2185
2187
  wrangler.command(
2186
2188
  "pubsub",
2187
2189
  "📮 Interact and manage Pub/Sub Brokers",
package/src/logger.ts CHANGED
@@ -3,10 +3,12 @@ import { formatMessagesSync } from "esbuild";
3
3
  import { getEnvironmentVariableFactory } from "./environment-variables";
4
4
 
5
5
  const LOGGER_LEVELS = {
6
+ none: -1,
6
7
  error: 0,
7
8
  warn: 1,
8
- log: 2,
9
- debug: 3,
9
+ info: 2,
10
+ log: 3,
11
+ debug: 4,
10
12
  } as const;
11
13
 
12
14
  type LoggerLevel = keyof typeof LOGGER_LEVELS;
@@ -15,6 +17,7 @@ type LoggerLevel = keyof typeof LOGGER_LEVELS;
15
17
  const LOGGER_LEVEL_FORMAT_TYPE_MAP = {
16
18
  error: "error",
17
19
  warn: "warning",
20
+ info: undefined,
18
21
  log: undefined,
19
22
  debug: undefined,
20
23
  } as const;
@@ -31,17 +34,21 @@ class Logger {
31
34
  columns = process.stdout.columns;
32
35
 
33
36
  debug = (...args: unknown[]) => this.doLog("debug", args);
37
+ info = (...args: unknown[]) => this.doLog("info", args);
34
38
  log = (...args: unknown[]) => this.doLog("log", args);
35
39
  warn = (...args: unknown[]) => this.doLog("warn", args);
36
40
  error = (...args: unknown[]) => this.doLog("error", args);
37
41
 
38
- private doLog(messageLevel: LoggerLevel, args: unknown[]) {
42
+ private doLog(messageLevel: Exclude<LoggerLevel, "none">, args: unknown[]) {
39
43
  if (LOGGER_LEVELS[this.loggerLevel] >= LOGGER_LEVELS[messageLevel]) {
40
44
  console[messageLevel](this.formatMessage(messageLevel, format(...args)));
41
45
  }
42
46
  }
43
47
 
44
- private formatMessage(level: LoggerLevel, message: string): string {
48
+ private formatMessage(
49
+ level: Exclude<LoggerLevel, "none">,
50
+ message: string
51
+ ): string {
45
52
  const kind = LOGGER_LEVEL_FORMAT_TYPE_MAP[level];
46
53
  if (kind) {
47
54
  // Format the message using the esbuild formatter.
@@ -5,7 +5,6 @@ import {
5
5
  } from "@miniflare/durable-objects";
6
6
  import {
7
7
  Log,
8
- LogLevel,
9
8
  Miniflare,
10
9
  Response as MiniflareResponse,
11
10
  Request as MiniflareRequest,
@@ -14,7 +13,6 @@ import yargs from "yargs";
14
13
  import { hideBin } from "yargs/helpers";
15
14
  import { FatalError } from "../errors";
16
15
  import generateASSETSBinding from "./assets";
17
- import { enumKeys } from "./enum-keys";
18
16
  import { getRequestContextCheckOptions } from "./request-context";
19
17
  import type { Options } from "./assets";
20
18
  import type { AddressInfo } from "net";
@@ -35,26 +33,23 @@ class NoOpLog extends Log {
35
33
  }
36
34
 
37
35
  async function main() {
38
- const args = await yargs(hideBin(process.argv))
39
- .help(false)
40
- .version(false)
41
- .option("log", {
42
- choices: enumKeys(LogLevel),
43
- }).argv;
44
-
45
- const logLevel = LogLevel[args.log ?? "INFO"];
36
+ const args = await yargs(hideBin(process.argv)).help(false).version(false)
37
+ .argv;
38
+
46
39
  const requestContextCheckOptions = await getRequestContextCheckOptions();
47
40
  const config = {
48
41
  ...JSON.parse((args._[0] as string) ?? "{}"),
49
42
  ...requestContextCheckOptions,
50
43
  };
51
- //miniflare's logLevel 0 still logs routes, so lets override the logger
52
- config.log = config.disableLogs
53
- ? new NoOpLog()
54
- : new Log(logLevel, config.logOptions);
44
+ const logLevel = config.logLevel.toUpperCase();
45
+
46
+ config.log =
47
+ config.logLevel === "none"
48
+ ? new NoOpLog()
49
+ : new Log(logLevel, config.logOptions);
55
50
 
56
- if (logLevel > LogLevel.INFO) {
57
- console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
51
+ if (logLevel === "DEBUG" || logLevel === "VERBOSE") {
52
+ console.log("MINIFLARE OPTIONS:\n", JSON.stringify(config, null, 2));
58
53
  }
59
54
 
60
55
  config.bindings = {
package/src/pages/dev.tsx CHANGED
@@ -99,6 +99,10 @@ export function Options(yargs: Argv) {
99
99
  description: "KV namespace to bind (--kv KV_BINDING)",
100
100
  alias: "k",
101
101
  },
102
+ d1: {
103
+ type: "array",
104
+ description: "D1 database to bind",
105
+ },
102
106
  do: {
103
107
  type: "array",
104
108
  description: "Durable Object to bind (--do NAME=CLASS)",
@@ -146,12 +150,9 @@ export function Options(yargs: Argv) {
146
150
  type: "string",
147
151
  hidden: true,
148
152
  },
149
-
150
153
  "log-level": {
151
- // "none" will currently default to "error" for Wrangler Logger
152
154
  choices: ["debug", "info", "log", "warn", "error", "none"] as const,
153
155
  describe: "Specify logging level",
154
- default: "log",
155
156
  },
156
157
  })
157
158
  .epilogue(pagesBetaWarning);
@@ -170,6 +171,7 @@ export const Handler = async ({
170
171
  binding: bindings = [],
171
172
  kv: kvs = [],
172
173
  do: durableObjects = [],
174
+ d1: d1s = [],
173
175
  r2: r2s = [],
174
176
  "live-reload": liveReload,
175
177
  "local-protocol": localProtocol,
@@ -186,12 +188,8 @@ export const Handler = async ({
186
188
 
187
189
  type LogLevelArg = "debug" | "info" | "log" | "warn" | "error" | "none";
188
190
  if (logLevel) {
189
- // we don't define a "none" logLevel, so "error" will do for now.
190
191
  // The YargsOptionsToInterface doesn't handle the passing in of Unions from choices in Yargs
191
- logger.loggerLevel =
192
- (logLevel as LogLevelArg) === "none"
193
- ? "error"
194
- : (logLevel as Exclude<"none", LogLevelArg>);
192
+ logger.loggerLevel = logLevel as LogLevelArg;
195
193
  }
196
194
 
197
195
  if (!local) {
@@ -499,6 +497,12 @@ export const Handler = async ({
499
497
  return { binding: binding.toString(), bucket_name: "" };
500
498
  }),
501
499
 
500
+ d1Databases: d1s.map((binding) => ({
501
+ binding: binding.toString(),
502
+ database_id: "", // Required for types, but unused by dev
503
+ database_name: `local-${binding}`,
504
+ })),
505
+
502
506
  enablePagesAssetsServiceBinding: {
503
507
  proxyPort,
504
508
  directory,
@@ -508,8 +512,8 @@ export const Handler = async ({
508
512
  persistTo,
509
513
  showInteractiveDevSession: undefined,
510
514
  inspect: true,
511
- logLevel: "warn",
512
515
  logPrefix: "pages",
516
+ logLevel: logLevel ?? "warn",
513
517
  },
514
518
  { testMode: false, disableExperimentalWarning: true }
515
519
  );