wrangler 0.0.0-b2c2c2b → 0.0.0-b36ef43

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/bin/wrangler.js CHANGED
@@ -52,9 +52,6 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
52
52
  return spawn(
53
53
  process.execPath,
54
54
  [
55
- ...(semiver(process.versions.node, "18.0.0") >= 0
56
- ? ["--no-experimental-fetch"] // TODO: remove this when https://github.com/cloudflare/wrangler2/issues/834 is properly fixed
57
- : []),
58
55
  "--no-warnings",
59
56
  "--experimental-vm-modules",
60
57
  ...process.execArgv,
@@ -4846,6 +4846,13 @@ var getRequestContextCheckOptions = async () => {
4846
4846
  };
4847
4847
 
4848
4848
  // src/miniflare-cli/index.ts
4849
+ var NoOpLog = class extends Log {
4850
+ log() {
4851
+ }
4852
+ error(message) {
4853
+ throw message;
4854
+ }
4855
+ };
4849
4856
  async function main() {
4850
4857
  const args = await yargs_default(hideBin(process.argv)).help(false).version(false).option("log", {
4851
4858
  choices: enumKeys(LogLevel)
@@ -4854,9 +4861,9 @@ async function main() {
4854
4861
  const requestContextCheckOptions = await getRequestContextCheckOptions();
4855
4862
  const config = {
4856
4863
  ...JSON.parse(args._[0] ?? "{}"),
4857
- ...requestContextCheckOptions,
4858
- log: new Log(logLevel)
4864
+ ...requestContextCheckOptions
4859
4865
  };
4866
+ config.log = config.disableLogs ? new NoOpLog() : new Log(logLevel);
4860
4867
  if (logLevel > LogLevel.INFO) {
4861
4868
  console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
4862
4869
  }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "0.0.0-b2c2c2b",
3
+ "version": "0.0.0-b36ef43",
4
4
  "author": "wrangler@cloudflare.com",
5
5
  "description": "Command-line interface for all things Cloudflare Workers",
6
6
  "bin": {
7
7
  "wrangler": "./bin/wrangler.js",
8
8
  "wrangler2": "./bin/wrangler.js"
9
9
  },
10
+ "main": "wrangler-dist/cli.js",
10
11
  "license": "MIT OR Apache-2.0",
11
12
  "bugs": {
12
13
  "url": "https://github.com/cloudflare/wrangler2/issues"
@@ -40,7 +41,7 @@
40
41
  "@esbuild-plugins/node-globals-polyfill": "^0.1.1",
41
42
  "@esbuild-plugins/node-modules-polyfill": "^0.1.4",
42
43
  "blake3-wasm": "^2.1.5",
43
- "esbuild": "0.14.34",
44
+ "esbuild": "0.14.47",
44
45
  "miniflare": "^2.5.1",
45
46
  "nanoid": "^3.3.3",
46
47
  "path-to-regexp": "^6.2.0",
@@ -2480,13 +2480,16 @@ addEventListener('fetch', event => {});`
2480
2480
 
2481
2481
  await runWrangler("publish");
2482
2482
 
2483
- // We expect this to be uploaded in 3 batches
2484
- // The first batch has 11 files (88mb)
2483
+ // We expect this to be uploaded in 4 batches
2484
+
2485
+ // The first batch has 11 files
2485
2486
  expect(requests[0].uploads.length).toEqual(11);
2486
- // The next batch has 5 files (93mb)
2487
+ // The next batch has 5 files
2487
2488
  expect(requests[1].uploads.length).toEqual(5);
2488
- // And the last one has 4 files (98mb)
2489
- expect(requests[2].uploads.length).toEqual(4);
2489
+ // And the next one has 3 files
2490
+ expect(requests[2].uploads.length).toEqual(3);
2491
+ // And just 1 in the last batch
2492
+ expect(requests[3].uploads.length).toEqual(1);
2490
2493
 
2491
2494
  let assetIndex = 0;
2492
2495
  for (const request of requests) {
package/src/api/dev.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { startDev } from "../dev";
2
+ import { logger } from "../logger";
3
+ interface DevOptions {
4
+ env?: string;
5
+ ip?: string;
6
+ port?: number;
7
+ localProtocol?: "http" | "https";
8
+ assets?: string;
9
+ site?: string;
10
+ siteInclude?: string[];
11
+ siteExclude?: string[];
12
+ nodeCompat?: boolean;
13
+ experimentalEnableLocalPersistence?: boolean;
14
+ _: (string | number)[]; //yargs wants this
15
+ $0: string; //yargs wants this
16
+ }
17
+
18
+ export async function unstable_dev(script: string, options: DevOptions) {
19
+ logger.warn(
20
+ `unstable_dev() is experimental\nunstable_dev()'s behaviour will likely change in future releases`
21
+ );
22
+
23
+ return new Promise<{ stop: () => void }>((resolve) => {
24
+ //lmao
25
+ return new Promise<Awaited<ReturnType<typeof startDev>>>((ready) => {
26
+ const devServer = startDev({
27
+ script: script,
28
+ ...options,
29
+ local: true,
30
+ onReady: () => ready(devServer),
31
+ inspect: false,
32
+ logLevel: "none",
33
+ showInteractiveDevSession: false,
34
+ });
35
+ }).then((devServer) => {
36
+ resolve({ stop: devServer.stop });
37
+ });
38
+ });
39
+ }
@@ -0,0 +1 @@
1
+ export { unstable_dev } from "./dev";
package/src/cli.ts CHANGED
@@ -1,13 +1,27 @@
1
1
  import "dotenv/config"; // Grab locally specified env params from a `.env` file.
2
2
  import process from "process";
3
3
  import { hideBin } from "yargs/helpers";
4
+ import { unstable_dev } from "./api";
4
5
  import { FatalError } from "./errors";
5
6
  import { main } from ".";
6
7
 
7
- main(hideBin(process.argv)).catch((e) => {
8
- // The logging of any error that was thrown from `main()` is handled in the `yargs.fail()` handler.
9
- // Here we just want to ensure that the process exits with a non-zero code.
10
- // We don't want to do this inside the `main()` function, since that would kill the process when running our tests.
11
- const exitCode = (e instanceof FatalError && e.code) || 1;
12
- process.exit(exitCode);
13
- });
8
+ /**
9
+ * The main entrypoint for the CLI.
10
+ * main only gets called when the script is run directly, not when it's imported as a module.
11
+ */
12
+ if (require.main) {
13
+ main(hideBin(process.argv)).catch((e) => {
14
+ // The logging of any error that was thrown from `main()` is handled in the `yargs.fail()` handler.
15
+ // Here we just want to ensure that the process exits with a non-zero code.
16
+ // We don't want to do this inside the `main()` function, since that would kill the process when running our tests.
17
+ const exitCode = (e instanceof FatalError && e.code) || 1;
18
+ process.exit(exitCode);
19
+ });
20
+ }
21
+
22
+ /**
23
+ * This is how we're exporting the API.
24
+ * It makes it possible to import wrangler from 'wrangler',
25
+ * and call wrangler.unstable_dev().
26
+ */
27
+ module.exports = { unstable_dev };
package/src/dev/dev.tsx CHANGED
@@ -55,6 +55,10 @@ export type DevProps = {
55
55
  zone: string | undefined;
56
56
  host: string | undefined;
57
57
  routes: Route[] | undefined;
58
+ inspect: boolean | undefined;
59
+ logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
60
+ onReady: (() => void) | undefined;
61
+ showInteractiveDevSession: boolean | undefined;
58
62
  };
59
63
 
60
64
  export function DevImplementation(props: DevProps): JSX.Element {
@@ -88,7 +92,8 @@ export function DevImplementation(props: DevProps): JSX.Element {
88
92
 
89
93
  // only load the UI if we're running in a supported environment
90
94
  const { isRawModeSupported } = useStdin();
91
- return isRawModeSupported ? (
95
+
96
+ return props.showInteractiveDevSession ?? isRawModeSupported ? (
92
97
  <InteractiveDevSession {...props} />
93
98
  ) : (
94
99
  <DevSession {...props} local={props.initialMode === "local"} />
@@ -171,6 +176,9 @@ function DevSession(props: DevSessionProps) {
171
176
  crons={props.crons}
172
177
  localProtocol={props.localProtocol}
173
178
  localUpstream={props.localUpstream}
179
+ logLevel={props.logLevel}
180
+ inspect={props.inspect}
181
+ onReady={props.onReady}
174
182
  />
175
183
  ) : (
176
184
  <Remote
@@ -193,6 +201,7 @@ function DevSession(props: DevSessionProps) {
193
201
  zone={props.zone}
194
202
  host={props.host}
195
203
  routes={props.routes}
204
+ onReady={props.onReady}
196
205
  />
197
206
  );
198
207
  }
package/src/dev/local.tsx CHANGED
@@ -31,6 +31,9 @@ interface LocalProps {
31
31
  crons: Config["triggers"]["crons"];
32
32
  localProtocol: "http" | "https";
33
33
  localUpstream: string | undefined;
34
+ inspect: boolean | undefined;
35
+ onReady: (() => void) | undefined;
36
+ logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
34
37
  }
35
38
 
36
39
  export function Local(props: LocalProps) {
@@ -59,6 +62,9 @@ function useLocalWorker({
59
62
  crons,
60
63
  localProtocol,
61
64
  localUpstream,
65
+ inspect,
66
+ onReady,
67
+ logLevel,
62
68
  }: LocalProps) {
63
69
  // TODO: pass vars via command line
64
70
  const local = useRef<ReturnType<typeof spawn>>();
@@ -220,6 +226,7 @@ function useLocalWorker({
220
226
  logUnhandledRejections: true,
221
227
  crons,
222
228
  upstream,
229
+ disableLogs: logLevel === "none",
223
230
  };
224
231
 
225
232
  // The path to the Miniflare CLI assumes that this file is being run from
@@ -232,20 +239,25 @@ function useLocalWorker({
232
239
  const optionsArg = JSON.stringify(options, null);
233
240
 
234
241
  logger.log("⎔ Starting a local server...");
235
- local.current = spawn(
236
- "node",
237
- [
238
- "--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
239
- "--no-warnings", // hide annoying Node warnings
240
- "--inspect", // start Miniflare listening for a debugger to attach
241
- miniflareCLIPath,
242
- optionsArg,
243
- // "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
244
- ],
245
- {
246
- cwd: path.dirname(scriptPath),
247
- }
248
- );
242
+ const localServerOptions = [
243
+ "--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
244
+ "--no-warnings", // hide annoying Node warnings
245
+ miniflareCLIPath,
246
+ optionsArg,
247
+ // "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
248
+ ];
249
+ if (inspect) {
250
+ localServerOptions.push("--inspect"); // start Miniflare listening for a debugger to attach
251
+ }
252
+ // spawn isn't technically synchronous here
253
+ local.current = spawn("node", localServerOptions, {
254
+ cwd: path.dirname(scriptPath),
255
+ });
256
+ //TODO: instead of being lucky with spawn's timing, have miniflare-cli notify wrangler that it's ready in packages/wrangler/src/miniflare-cli/index.ts, after the mf.startScheduler promise resolves
257
+ if (onReady) {
258
+ await new Promise((resolve) => setTimeout(resolve, 200));
259
+ onReady();
260
+ }
249
261
 
250
262
  local.current.on("close", (code) => {
251
263
  if (code) {
@@ -330,6 +342,9 @@ function useLocalWorker({
330
342
  crons,
331
343
  localProtocol,
332
344
  localUpstream,
345
+ inspect,
346
+ logLevel,
347
+ onReady,
333
348
  ]);
334
349
  return { inspectorUrl };
335
350
  }
@@ -36,6 +36,7 @@ export function Remote(props: {
36
36
  zone: string | undefined;
37
37
  host: string | undefined;
38
38
  routes: Route[] | undefined;
39
+ onReady?: () => void;
39
40
  }) {
40
41
  const [accountId, setAccountId] = useState(props.accountId);
41
42
  const accountChoicesRef = useRef<Promise<ChooseAccountItem[]>>();
@@ -59,6 +60,7 @@ export function Remote(props: {
59
60
  zone: props.zone,
60
61
  host: props.host,
61
62
  routes: props.routes,
63
+ onReady: props.onReady,
62
64
  });
63
65
 
64
66
  usePreviewServer({
@@ -129,6 +131,7 @@ export function useWorker(props: {
129
131
  zone: string | undefined;
130
132
  host: string | undefined;
131
133
  routes: Route[] | undefined;
134
+ onReady?: () => void;
132
135
  }): CfPreviewToken | undefined {
133
136
  const {
134
137
  name,
@@ -142,6 +145,7 @@ export function useWorker(props: {
142
145
  compatibilityFlags,
143
146
  usageModel,
144
147
  port,
148
+ onReady,
145
149
  } = props;
146
150
  const [token, setToken] = useState<CfPreviewToken | undefined>();
147
151
 
@@ -239,6 +243,7 @@ export function useWorker(props: {
239
243
  abortController.signal
240
244
  )
241
245
  );
246
+ onReady?.();
242
247
  }
243
248
  start().catch((err) => {
244
249
  // we want to log the error, but not end the process
@@ -283,6 +288,7 @@ export function useWorker(props: {
283
288
  props.zone,
284
289
  props.host,
285
290
  props.routes,
291
+ onReady,
286
292
  ]);
287
293
  return token;
288
294
  }
package/src/dev.tsx CHANGED
@@ -57,6 +57,9 @@ interface DevArgs {
57
57
  minify?: boolean;
58
58
  "node-compat"?: boolean;
59
59
  "experimental-enable-local-persistence"?: boolean;
60
+ onReady?: () => void;
61
+ logLevel?: "none" | "error" | "log" | "warn" | "debug";
62
+ showInteractiveDevSession?: boolean;
60
63
  }
61
64
 
62
65
  export function devOptions(yargs: Argv): Argv<DevArgs> {
@@ -231,9 +234,27 @@ export function devOptions(yargs: Argv): Argv<DevArgs> {
231
234
  }
232
235
 
233
236
  export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
237
+ let watcher;
238
+ try {
239
+ const devInstance = await startDev(args);
240
+ watcher = devInstance.watcher;
241
+ const { waitUntilExit } = devInstance.devReactElement;
242
+ await waitUntilExit();
243
+ } finally {
244
+ await watcher?.close();
245
+ }
246
+ }
247
+
248
+ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
234
249
  let watcher: ReturnType<typeof watch> | undefined;
250
+ let rerender: (node: React.ReactNode) => void | undefined;
235
251
  try {
252
+ if (args.logLevel) {
253
+ // we don't define a "none" logLevel, so "error" will do for now.
254
+ logger.loggerLevel = args.logLevel === "none" ? "error" : args.logLevel;
255
+ }
236
256
  await printWranglerBanner();
257
+
237
258
  const configPath =
238
259
  (args.config as ConfigPath) ||
239
260
  ((args.script &&
@@ -274,6 +295,7 @@ export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
274
295
  }
275
296
 
276
297
  if (args.inspect) {
298
+ //devtools are enabled by default, but we still need to disable them if the caller doesn't want them
277
299
  logger.warn(
278
300
  "Passing --inspect is unnecessary, now you can always connect to devtools."
279
301
  );
@@ -469,13 +491,25 @@ export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
469
491
  usageModel={config.usage_model}
470
492
  bindings={bindings}
471
493
  crons={config.triggers.crons}
494
+ logLevel={args.logLevel}
495
+ onReady={args.onReady}
496
+ inspect={args.inspect}
497
+ showInteractiveDevSession={args.showInteractiveDevSession}
472
498
  />
473
499
  );
474
500
  }
475
- const { waitUntilExit, rerender } = render(
476
- await getDevReactElement(config)
477
- );
478
- await waitUntilExit();
501
+ const devReactElement = render(await getDevReactElement(config));
502
+ rerender = devReactElement.rerender;
503
+ return {
504
+ devReactElement,
505
+ watcher,
506
+ stop: async () => {
507
+ devReactElement.unmount();
508
+ await devReactElement.waitUntilExit();
509
+ await watcher?.close();
510
+ process.exit(0);
511
+ },
512
+ };
479
513
  } finally {
480
514
  await watcher?.close();
481
515
  }
@@ -4,6 +4,16 @@ import { hideBin } from "yargs/helpers";
4
4
  import { enumKeys } from "./enum-keys";
5
5
  import { getRequestContextCheckOptions } from "./request-context";
6
6
 
7
+ // miniflare defines this but importing it throws:
8
+ // Dynamic require of "path" is not supported
9
+ class NoOpLog extends Log {
10
+ log(): void {}
11
+
12
+ error(message: Error): void {
13
+ throw message;
14
+ }
15
+ }
16
+
7
17
  async function main() {
8
18
  const args = await yargs(hideBin(process.argv))
9
19
  .help(false)
@@ -17,8 +27,9 @@ async function main() {
17
27
  const config = {
18
28
  ...JSON.parse((args._[0] as string) ?? "{}"),
19
29
  ...requestContextCheckOptions,
20
- log: new Log(logLevel),
21
30
  };
31
+ //miniflare's logLevel 0 still logs routes, so lets override the logger
32
+ config.log = config.disableLogs ? new NoOpLog() : new Log(logLevel);
22
33
 
23
34
  if (logLevel > LogLevel.INFO) {
24
35
  console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
package/src/preview.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { DeprecationError } from "./errors";
2
+ import type { Argv } from "yargs";
3
+
4
+ export function previewOptions(yargs: Argv) {
5
+ return yargs
6
+ .positional("method", {
7
+ type: "string",
8
+ describe: "Type of request to preview your worker",
9
+ })
10
+ .positional("body", {
11
+ type: "string",
12
+ describe: "Body string to post to your preview worker request.",
13
+ })
14
+ .option("env", {
15
+ type: "string",
16
+ requiresArg: true,
17
+ describe: "Perform on a specific environment",
18
+ })
19
+ .option("watch", {
20
+ default: true,
21
+ describe: "Enable live preview",
22
+ type: "boolean",
23
+ });
24
+ }
25
+
26
+ export function previewHandler() {
27
+ throw new DeprecationError(
28
+ "The `wrangler preview` command has been deprecated.\n" +
29
+ "Try using `wrangler dev` to to try out a worker during development.\n"
30
+ );
31
+ }
package/src/sites.tsx CHANGED
@@ -138,9 +138,9 @@ export async function syncAssets(
138
138
 
139
139
  const manifest: Record<string, string> = {};
140
140
 
141
- // A batch of uploads where each bucket has to be less than 100mb
141
+ // A batch of uploads where each bucket has to be less than 98mb
142
142
  const uploadBuckets: KeyValue[][] = [];
143
- // The "live" bucket that we'll keep filling until it's just below 100mb
143
+ // The "live" bucket that we'll keep filling until it's just below 98mb
144
144
  let uploadBucket: KeyValue[] = [];
145
145
  // A size counter for the live bucket
146
146
  let uploadBucketSize = 0;
@@ -166,7 +166,7 @@ export async function syncAssets(
166
166
  const content = await readFile(absAssetFile, "base64");
167
167
  await validateAssetSize(absAssetFile, assetFile);
168
168
  // while KV accepts files that are 25 MiB **before** b64 encoding
169
- // the overall bucket size must be below 100 MiB **after** b64 encoding
169
+ // the overall bucket size must be below 100 MB **after** b64 encoding
170
170
  const assetSize = Buffer.from(content).length;
171
171
  const assetKey = hashAsset(hasher, assetFile, content);
172
172
  validateAssetKey(assetKey);
@@ -176,8 +176,8 @@ export async function syncAssets(
176
176
  logger.log(`Uploading as ${assetKey}...`);
177
177
 
178
178
  // Check if adding this asset to the bucket would
179
- // push it over the 100 MiB limit KV bulk API limit
180
- if (uploadBucketSize + assetSize > 100 * 1024 * 1024) {
179
+ // push it over the 98 MiB limit KV bulk API limit
180
+ if (uploadBucketSize + assetSize > 98 * 1000 * 1000) {
181
181
  // If so, move the current bucket into the batch,
182
182
  // and reset the counter/bucket
183
183
  uploadBuckets.push(uploadBucket);