wrangler 0.0.34 → 2.0.2

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/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  ## ⛅️ wrangler
2
2
 
3
+ > This package is for wrangler v2.x, released first in May 2022. If you're looking for v1.x of the `@cloudflare/wrangler` package, visit https://www.npmjs.com/package/@cloudflare/wrangler / https://github.com/cloudflare/wrangler.
4
+
3
5
  `wrangler` is a command line tool for building [Cloudflare Workers](https://workers.cloudflare.com/).
4
6
 
5
7
  ## Quick Start
@@ -22,7 +24,7 @@ npx wrangler init my-worker
22
24
  # try it out
23
25
  cd my-worker && npm run start
24
26
  # and then publish it
25
- npx wrangler publish
27
+ npm run publish
26
28
  ```
27
29
 
28
30
  ## Installation:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "0.0.34",
3
+ "version": "2.0.2",
4
4
  "author": "wrangler@cloudflare.com",
5
5
  "description": "Command-line interface for all things Cloudflare Workers",
6
6
  "bin": {
@@ -9,9 +9,9 @@
9
9
  },
10
10
  "license": "MIT OR Apache-2.0",
11
11
  "bugs": {
12
- "url": "https://github.com/cloudflare/wrangler/issues"
12
+ "url": "https://github.com/cloudflare/wrangler2/issues"
13
13
  },
14
- "homepage": "https://github.com/cloudflare/wrangler#readme",
14
+ "homepage": "https://github.com/cloudflare/wrangler2#readme",
15
15
  "keywords": [
16
16
  "wrangler",
17
17
  "cloudflare",
@@ -258,7 +258,7 @@ describe("pages", () => {
258
258
  🆙 Publish a directory of static assets as a Pages deployment
259
259
 
260
260
  Positionals:
261
- directory The directory of Pages Functions [string] [default: \\"functions\\"]
261
+ directory The directory of static files to upload [string]
262
262
 
263
263
  Flags:
264
264
  -c, --config Path to .toml configuration file [string]
@@ -267,11 +267,11 @@ describe("pages", () => {
267
267
  --legacy-env Use legacy environments [boolean]
268
268
 
269
269
  Options:
270
- --project-name The name of the project you want to list deployments for [string]
271
- --branch The branch of the project you want to list deployments for [string]
272
- --commit-hash The branch of the project you want to list deployments for [string]
273
- --commit-message The branch of the project you want to list deployments for [string]
274
- --commit-dirty The branch of the project you want to list deployments for [boolean]
270
+ --project-name The name of the project you want to deploy to [string]
271
+ --branch The name of the branch you want to deploy to [string]
272
+ --commit-hash The SHA to attach to this deployment [string]
273
+ --commit-message The commit message to attach to this deployment [string]
274
+ --commit-dirty Whether or not the workspace should be considered dirty for this deployment [boolean]
275
275
 
276
276
  🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
277
277
  `);
@@ -165,6 +165,10 @@ describe("parseTOML", () => {
165
165
  });
166
166
  }
167
167
  });
168
+
169
+ it("should cope with Windows line-endings", () => {
170
+ expect(parseTOML("# A comment with a Windows line-ending\r\n")).toEqual({});
171
+ });
168
172
  });
169
173
 
170
174
  describe("parseJSON", () => {
@@ -1,6 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import * as TOML from "@iarna/toml";
4
+ import * as esbuild from "esbuild";
4
5
  import { writeAuthConfigFile } from "../user";
5
6
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
6
7
  import {
@@ -878,6 +879,77 @@ export default{
878
879
  expect(std.err).toMatchInlineSnapshot(`""`);
879
880
  });
880
881
 
882
+ it("should preserve exports on a module format worker", async () => {
883
+ writeWranglerToml();
884
+ fs.writeFileSync(
885
+ "index.js",
886
+ `
887
+ export const abc = 123;
888
+ export const def = "show me the money";
889
+ export default {};`
890
+ );
891
+
892
+ await runWrangler("publish index.js --dry-run --outdir out");
893
+
894
+ expect(
895
+ (
896
+ await esbuild.build({
897
+ entryPoints: [path.resolve("./out/index.js")],
898
+ metafile: true,
899
+ write: false,
900
+ })
901
+ ).metafile?.outputs["index.js"].exports
902
+ ).toMatchInlineSnapshot(`
903
+ Array [
904
+ "abc",
905
+ "def",
906
+ "default",
907
+ ]
908
+ `);
909
+ expect(std).toMatchInlineSnapshot(`
910
+ Object {
911
+ "debug": "",
912
+ "err": "",
913
+ "out": "--dry-run: exiting now.",
914
+ "warn": "",
915
+ }
916
+ `);
917
+ });
918
+
919
+ it("should not preserve exports on a service-worker format worker", async () => {
920
+ writeWranglerToml();
921
+ fs.writeFileSync(
922
+ "index.js",
923
+ `
924
+ export const abc = 123;
925
+ export const def = "show me the money";
926
+ addEventListener('fetch', event => {});`
927
+ );
928
+
929
+ await runWrangler("publish index.js --dry-run --outdir out --minify");
930
+
931
+ expect(
932
+ (
933
+ await esbuild.build({
934
+ entryPoints: [path.resolve("./out/index.js")],
935
+ metafile: true,
936
+ write: false,
937
+ })
938
+ ).metafile?.outputs["index.js"].exports
939
+ ).toMatchInlineSnapshot(`Array []`);
940
+
941
+ expect(std).toMatchInlineSnapshot(`
942
+ Object {
943
+ "debug": "",
944
+ "err": "",
945
+ "out": "--dry-run: exiting now.",
946
+ "warn": "▲ [WARNING] The entrypoint index.js has exports like an ES Module, but hasn't defined a default export like a module worker normally would. Building the worker using \\"service-worker\\" format...
947
+
948
+ ",
949
+ }
950
+ `);
951
+ });
952
+
881
953
  it("should be able to transpile entry-points in sub-directories (sw)", async () => {
882
954
  writeWranglerToml();
883
955
  writeWorkerSource({ basePath: "./src", type: "sw" });
package/src/bundle.ts CHANGED
@@ -66,7 +66,7 @@ export async function bundleWorker(
66
66
  absWorkingDir: entry.directory,
67
67
  outdir: destination,
68
68
  external: ["__STATIC_CONTENT_MANIFEST"],
69
- format: "esm",
69
+ format: entry.format === "modules" ? "esm" : "iife",
70
70
  target: "es2020",
71
71
  sourcemap: true,
72
72
  minify,
package/src/pages.tsx CHANGED
@@ -82,6 +82,8 @@ const PAGES_CONFIG_CACHE_FILENAME = "pages.json";
82
82
  export const pagesBetaWarning =
83
83
  "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
84
84
 
85
+ const isInPagesCI = !!process.env.CF_PAGES;
86
+
85
87
  const CLEANUP_CALLBACKS: (() => void)[] = [];
86
88
  const CLEANUP = () => {
87
89
  CLEANUP_CALLBACKS.forEach((callback) => callback());
@@ -802,34 +804,30 @@ const createDeployment: CommandModule<
802
804
  return yargs
803
805
  .positional("directory", {
804
806
  type: "string",
805
- default: "functions",
806
- description: "The directory of Pages Functions",
807
+ demandOption: true,
808
+ description: "The directory of static files to upload",
807
809
  })
808
810
  .options({
809
811
  "project-name": {
810
812
  type: "string",
811
- description:
812
- "The name of the project you want to list deployments for",
813
+ description: "The name of the project you want to deploy to",
813
814
  },
814
815
  branch: {
815
816
  type: "string",
816
- description:
817
- "The branch of the project you want to list deployments for",
817
+ description: "The name of the branch you want to deploy to",
818
818
  },
819
819
  "commit-hash": {
820
820
  type: "string",
821
- description:
822
- "The branch of the project you want to list deployments for",
821
+ description: "The SHA to attach to this deployment",
823
822
  },
824
823
  "commit-message": {
825
824
  type: "string",
826
- description:
827
- "The branch of the project you want to list deployments for",
825
+ description: "The commit message to attach to this deployment",
828
826
  },
829
827
  "commit-dirty": {
830
828
  type: "boolean",
831
829
  description:
832
- "The branch of the project you want to list deployments for",
830
+ "Whether or not the workspace should be considered dirty for this deployment",
833
831
  },
834
832
  })
835
833
  .epilogue(pagesBetaWarning);
@@ -842,6 +840,10 @@ const createDeployment: CommandModule<
842
840
  commitMessage,
843
841
  commitDirty,
844
842
  }) => {
843
+ if (!directory) {
844
+ throw new FatalError("Must specify a directory.", 1);
845
+ }
846
+
845
847
  const config = getConfigCache<PagesConfigCache>(
846
848
  PAGES_CONFIG_CACHE_FILENAME
847
849
  );
@@ -851,40 +853,45 @@ const createDeployment: CommandModule<
851
853
 
852
854
  const isInteractive = process.stdin.isTTY;
853
855
  if (!projectName && isInteractive) {
854
- const existingOrNew = await new Promise<"new" | "existing">((resolve) => {
855
- const { unmount } = render(
856
- <>
857
- <Text>
858
- No project selected. Would you like to create one or use an
859
- existing project?
860
- </Text>
861
- <SelectInput
862
- items={[
863
- {
864
- key: "new",
865
- label: "Create a new project",
866
- value: "new",
867
- },
868
- {
869
- key: "existing",
870
- label: "Use an existing project",
871
- value: "existing",
872
- },
873
- ]}
874
- onSelect={async (selected) => {
875
- resolve(selected.value as "new" | "existing");
876
- unmount();
877
- }}
878
- />
879
- </>
880
- );
881
- });
856
+ const projects = (await listProjects({ accountId })).filter(
857
+ (project) => !project.source
858
+ );
859
+
860
+ let existingOrNew: "existing" | "new" = "new";
861
+
862
+ if (projects.length > 0) {
863
+ existingOrNew = await new Promise<"new" | "existing">((resolve) => {
864
+ const { unmount } = render(
865
+ <>
866
+ <Text>
867
+ No project selected. Would you like to create one or use an
868
+ existing project?
869
+ </Text>
870
+ <SelectInput
871
+ items={[
872
+ {
873
+ key: "new",
874
+ label: "Create a new project",
875
+ value: "new",
876
+ },
877
+ {
878
+ key: "existing",
879
+ label: "Use an existing project",
880
+ value: "existing",
881
+ },
882
+ ]}
883
+ onSelect={async (selected) => {
884
+ resolve(selected.value as "new" | "existing");
885
+ unmount();
886
+ }}
887
+ />
888
+ </>
889
+ );
890
+ });
891
+ }
882
892
 
883
893
  switch (existingOrNew) {
884
894
  case "existing": {
885
- const projects = (await listProjects({ accountId })).filter(
886
- (project) => !project.source
887
- );
888
895
  projectName = await new Promise((resolve) => {
889
896
  const { unmount } = render(
890
897
  <>
@@ -1581,8 +1588,10 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
1581
1588
  watch,
1582
1589
  plugin,
1583
1590
  }) => {
1584
- // Beta message for `wrangler pages <commands>` usage
1585
- logger.log(pagesBetaWarning);
1591
+ if (!isInPagesCI) {
1592
+ // Beta message for `wrangler pages <commands>` usage
1593
+ logger.log(pagesBetaWarning);
1594
+ }
1586
1595
 
1587
1596
  await buildFunctions({
1588
1597
  outfile,
package/src/parse.ts CHANGED
@@ -77,7 +77,9 @@ type TomlError = Error & {
77
77
  */
78
78
  export function parseTOML(input: string, file?: string): TOML.JsonMap | never {
79
79
  try {
80
- return TOML.parse(input);
80
+ // Normalize CRLF to LF to avoid hitting https://github.com/iarna/iarna-toml/issues/33.
81
+ const normalizedInput = input.replace(/\r\n$/g, "\n");
82
+ return TOML.parse(normalizedInput);
81
83
  } catch (err) {
82
84
  const { name, message, line, col } = err as TomlError;
83
85
  if (name !== TOML_ERROR_NAME) {
package/src/proxy.ts CHANGED
@@ -210,6 +210,10 @@ export function usePreviewServer({
210
210
  const request = message.pipe(remote.request(headers));
211
211
  request.on("response", (responseHeaders) => {
212
212
  const status = responseHeaders[":status"] ?? 500;
213
+
214
+ // log all requests to terminal
215
+ logger.log(new Date().toLocaleTimeString(), method, url, status);
216
+
213
217
  rewriteRemoteHostToLocalHostInHeaders(
214
218
  responseHeaders,
215
219
  previewToken.host,
@@ -349,15 +353,6 @@ async function createProxyServer(
349
353
  : createHttpServer();
350
354
 
351
355
  return server
352
- .on("request", function (req, res) {
353
- // log all requests
354
- logger.log(
355
- new Date().toLocaleTimeString(),
356
- req.method,
357
- req.url,
358
- res.statusCode
359
- );
360
- })
361
356
  .on("upgrade", (req) => {
362
357
  // log all websocket connections
363
358
  logger.log(
@@ -104810,7 +104810,7 @@ var yargs_default = Yargs;
104810
104810
 
104811
104811
  // package.json
104812
104812
  var name = "wrangler";
104813
- var version = "0.0.34";
104813
+ var version = "2.0.2";
104814
104814
  var author = "wrangler@cloudflare.com";
104815
104815
  var description = "Command-line interface for all things Cloudflare Workers";
104816
104816
  var bin = {
@@ -104819,9 +104819,9 @@ var bin = {
104819
104819
  };
104820
104820
  var license = "MIT OR Apache-2.0";
104821
104821
  var bugs = {
104822
- url: "https://github.com/cloudflare/wrangler/issues"
104822
+ url: "https://github.com/cloudflare/wrangler2/issues"
104823
104823
  };
104824
- var homepage = "https://github.com/cloudflare/wrangler#readme";
104824
+ var homepage = "https://github.com/cloudflare/wrangler2#readme";
104825
104825
  var keywords = [
104826
104826
  "wrangler",
104827
104827
  "cloudflare",
@@ -105017,7 +105017,8 @@ var TOML_ERROR_NAME = "TomlError";
105017
105017
  var TOML_ERROR_SUFFIX = " at row ";
105018
105018
  function parseTOML(input, file) {
105019
105019
  try {
105020
- return import_toml.default.parse(input);
105020
+ const normalizedInput = input.replace(/\r\n$/g, "\n");
105021
+ return import_toml.default.parse(normalizedInput);
105021
105022
  } catch (err2) {
105022
105023
  const { name: name2, message, line, col } = err2;
105023
105024
  if (name2 !== TOML_ERROR_NAME) {
@@ -107438,6 +107439,7 @@ function usePreviewServer({
107438
107439
  const request = message.pipe(remote.request(headers));
107439
107440
  request.on("response", (responseHeaders) => {
107440
107441
  const status = responseHeaders[":status"] ?? 500;
107442
+ logger.log(new Date().toLocaleTimeString(), method, url3, status);
107441
107443
  rewriteRemoteHostToLocalHostInHeaders(responseHeaders, previewToken.host, port, localProtocol);
107442
107444
  for (const name2 of Object.keys(responseHeaders)) {
107443
107445
  if (name2.startsWith(":")) {
@@ -107522,9 +107524,7 @@ var HTTP1_HEADERS = /* @__PURE__ */ new Set([
107522
107524
  ]);
107523
107525
  async function createProxyServer(localProtocol) {
107524
107526
  const server = localProtocol === "https" ? (0, import_node_https.createServer)(await getHttpsOptions()) : (0, import_node_http2.createServer)();
107525
- return server.on("request", function(req, res) {
107526
- logger.log(new Date().toLocaleTimeString(), req.method, req.url, res.statusCode);
107527
- }).on("upgrade", (req) => {
107527
+ return server.on("upgrade", (req) => {
107528
107528
  logger.log(new Date().toLocaleTimeString(), req.method, req.url, 101, "(WebSocket)");
107529
107529
  }).on("error", (err2) => {
107530
107530
  logger.error(new Date().toLocaleTimeString(), err2);
@@ -108792,7 +108792,7 @@ async function bundleWorker(entry, destination, options) {
108792
108792
  absWorkingDir: entry.directory,
108793
108793
  outdir: destination,
108794
108794
  external: ["__STATIC_CONTENT_MANIFEST"],
108795
- format: "esm",
108795
+ format: entry.format === "modules" ? "esm" : "iife",
108796
108796
  target: "es2020",
108797
108797
  sourcemap: true,
108798
108798
  minify,
@@ -109952,6 +109952,7 @@ var getRequestContextCheckOptions = async () => {
109952
109952
  // src/pages.tsx
109953
109953
  var PAGES_CONFIG_CACHE_FILENAME = "pages.json";
109954
109954
  var pagesBetaWarning = "\u{1F6A7} 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
109955
+ var isInPagesCI = !!process.env.CF_PAGES;
109955
109956
  var CLEANUP_CALLBACKS = [];
109956
109957
  var CLEANUP = () => {
109957
109958
  CLEANUP_CALLBACKS.forEach((callback) => callback());
@@ -110422,28 +110423,28 @@ var createDeployment = {
110422
110423
  builder: (yargs) => {
110423
110424
  return yargs.positional("directory", {
110424
110425
  type: "string",
110425
- default: "functions",
110426
- description: "The directory of Pages Functions"
110426
+ demandOption: true,
110427
+ description: "The directory of static files to upload"
110427
110428
  }).options({
110428
110429
  "project-name": {
110429
110430
  type: "string",
110430
- description: "The name of the project you want to list deployments for"
110431
+ description: "The name of the project you want to deploy to"
110431
110432
  },
110432
110433
  branch: {
110433
110434
  type: "string",
110434
- description: "The branch of the project you want to list deployments for"
110435
+ description: "The name of the branch you want to deploy to"
110435
110436
  },
110436
110437
  "commit-hash": {
110437
110438
  type: "string",
110438
- description: "The branch of the project you want to list deployments for"
110439
+ description: "The SHA to attach to this deployment"
110439
110440
  },
110440
110441
  "commit-message": {
110441
110442
  type: "string",
110442
- description: "The branch of the project you want to list deployments for"
110443
+ description: "The commit message to attach to this deployment"
110443
110444
  },
110444
110445
  "commit-dirty": {
110445
110446
  type: "boolean",
110446
- description: "The branch of the project you want to list deployments for"
110447
+ description: "Whether or not the workspace should be considered dirty for this deployment"
110447
110448
  }
110448
110449
  }).epilogue(pagesBetaWarning);
110449
110450
  },
@@ -110455,34 +110456,40 @@ var createDeployment = {
110455
110456
  commitMessage,
110456
110457
  commitDirty
110457
110458
  }) => {
110459
+ if (!directory) {
110460
+ throw new FatalError("Must specify a directory.", 1);
110461
+ }
110458
110462
  const config = getConfigCache(PAGES_CONFIG_CACHE_FILENAME);
110459
110463
  const accountId = await requireAuth(config);
110460
110464
  projectName ??= config.project_name;
110461
110465
  const isInteractive = process.stdin.isTTY;
110462
110466
  if (!projectName && isInteractive) {
110463
- const existingOrNew = await new Promise((resolve11) => {
110464
- const { unmount: unmount2 } = (0, import_ink5.render)(/* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(import_ink5.Text, null, "No project selected. Would you like to create one or use an existing project?"), /* @__PURE__ */ import_react9.default.createElement(import_ink_select_input2.default, {
110465
- items: [
110466
- {
110467
- key: "new",
110468
- label: "Create a new project",
110469
- value: "new"
110470
- },
110471
- {
110472
- key: "existing",
110473
- label: "Use an existing project",
110474
- value: "existing"
110467
+ const projects = (await listProjects({ accountId })).filter((project) => !project.source);
110468
+ let existingOrNew = "new";
110469
+ if (projects.length > 0) {
110470
+ existingOrNew = await new Promise((resolve11) => {
110471
+ const { unmount: unmount2 } = (0, import_ink5.render)(/* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(import_ink5.Text, null, "No project selected. Would you like to create one or use an existing project?"), /* @__PURE__ */ import_react9.default.createElement(import_ink_select_input2.default, {
110472
+ items: [
110473
+ {
110474
+ key: "new",
110475
+ label: "Create a new project",
110476
+ value: "new"
110477
+ },
110478
+ {
110479
+ key: "existing",
110480
+ label: "Use an existing project",
110481
+ value: "existing"
110482
+ }
110483
+ ],
110484
+ onSelect: async (selected) => {
110485
+ resolve11(selected.value);
110486
+ unmount2();
110475
110487
  }
110476
- ],
110477
- onSelect: async (selected) => {
110478
- resolve11(selected.value);
110479
- unmount2();
110480
- }
110481
- })));
110482
- });
110488
+ })));
110489
+ });
110490
+ }
110483
110491
  switch (existingOrNew) {
110484
110492
  case "existing": {
110485
- const projects = (await listProjects({ accountId })).filter((project) => !project.source);
110486
110493
  projectName = await new Promise((resolve11) => {
110487
110494
  const { unmount: unmount2 } = (0, import_ink5.render)(/* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(import_ink5.Text, null, "Select a project:"), /* @__PURE__ */ import_react9.default.createElement(import_ink_select_input2.default, {
110488
110495
  items: projects.map((project) => ({
@@ -110960,7 +110967,9 @@ var pages = (yargs) => {
110960
110967
  watch: watch3,
110961
110968
  plugin
110962
110969
  }) => {
110963
- logger.log(pagesBetaWarning);
110970
+ if (!isInPagesCI) {
110971
+ logger.log(pagesBetaWarning);
110972
+ }
110964
110973
  await buildFunctions({
110965
110974
  outfile,
110966
110975
  outputConfigPath,