wrangler 0.0.0-e88a54e → 0.0.0-e95e5a0

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 (88) hide show
  1. package/README.md +25 -14
  2. package/bin/wrangler.js +13 -1
  3. package/miniflare-dist/index.mjs +4828 -21
  4. package/package.json +29 -24
  5. package/pages/functions/buildPlugin.ts +92 -0
  6. package/pages/functions/buildWorker.ts +80 -4
  7. package/pages/functions/filepath-routing.test.ts +11 -0
  8. package/pages/functions/filepath-routing.ts +8 -0
  9. package/pages/functions/routes.ts +6 -1
  10. package/pages/functions/template-plugin.ts +146 -0
  11. package/pages/functions/template-worker.ts +21 -8
  12. package/src/__tests__/config-cache.test.ts +36 -0
  13. package/src/__tests__/configuration.test.ts +530 -201
  14. package/src/__tests__/dev.test.tsx +284 -18
  15. package/src/__tests__/guess-worker-format.test.ts +28 -1
  16. package/src/__tests__/helpers/mock-cfetch.ts +5 -1
  17. package/src/__tests__/helpers/mock-console.ts +20 -3
  18. package/src/__tests__/helpers/mock-dialogs.ts +26 -1
  19. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  20. package/src/__tests__/helpers/mock-istty.ts +27 -0
  21. package/src/__tests__/helpers/mock-oauth-flow.ts +255 -0
  22. package/src/__tests__/helpers/run-in-tmp.ts +7 -0
  23. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  24. package/src/__tests__/https-options.test.ts +5 -2
  25. package/src/__tests__/index.test.ts +27 -769
  26. package/src/__tests__/init.test.ts +1516 -0
  27. package/src/__tests__/jest.setup.ts +4 -4
  28. package/src/__tests__/kv.test.ts +133 -61
  29. package/src/__tests__/logger.test.ts +115 -0
  30. package/src/__tests__/pages.test.ts +311 -26
  31. package/src/__tests__/publish.test.ts +2789 -618
  32. package/src/__tests__/r2.test.ts +26 -10
  33. package/src/__tests__/route.test.ts +4 -4
  34. package/src/__tests__/secret.test.ts +55 -34
  35. package/src/__tests__/tail.test.ts +146 -20
  36. package/src/__tests__/user.test.ts +131 -0
  37. package/src/__tests__/whoami.test.tsx +14 -9
  38. package/src/bundle.ts +30 -3
  39. package/src/cfetch/internal.ts +0 -2
  40. package/src/cli.ts +5 -11
  41. package/src/config/README.md +1 -1
  42. package/src/config/config.ts +20 -4
  43. package/src/config/environment.ts +32 -4
  44. package/src/config/index.ts +4 -3
  45. package/src/config/validation-helpers.ts +96 -7
  46. package/src/config/validation.ts +388 -54
  47. package/src/config-cache.ts +45 -0
  48. package/src/create-worker-preview.ts +22 -13
  49. package/src/create-worker-upload-form.ts +32 -9
  50. package/src/dev/dev-vars.ts +36 -0
  51. package/src/dev/dev.tsx +132 -78
  52. package/src/dev/local.tsx +101 -21
  53. package/src/dev/remote.tsx +23 -13
  54. package/src/dev/use-esbuild.ts +23 -5
  55. package/src/dialogs.tsx +16 -6
  56. package/src/entry.ts +83 -24
  57. package/src/environment-variables.ts +3 -1
  58. package/src/errors.ts +11 -0
  59. package/src/https-options.ts +3 -2
  60. package/src/index.tsx +689 -394
  61. package/src/inspect.ts +17 -11
  62. package/src/intl-polyfill.d.ts +139 -0
  63. package/src/logger.ts +66 -0
  64. package/src/miniflare-cli/index.ts +4 -0
  65. package/src/miniflare-cli/request-context.ts +40 -0
  66. package/src/module-collection.ts +7 -7
  67. package/src/open-in-browser.ts +5 -4
  68. package/src/package-manager.ts +9 -8
  69. package/src/pages.tsx +875 -56
  70. package/src/parse.ts +1 -1
  71. package/src/proxy.ts +28 -19
  72. package/src/publish.ts +263 -141
  73. package/src/sites.tsx +27 -14
  74. package/src/tail/index.ts +2 -2
  75. package/src/tail/printing.ts +13 -8
  76. package/src/update-check.ts +19 -0
  77. package/src/user.tsx +116 -41
  78. package/src/whoami.tsx +2 -1
  79. package/src/worker.ts +15 -6
  80. package/templates/gitignore +171 -0
  81. package/templates/static-asset-facade.js +1 -1
  82. package/wrangler-dist/cli.js +21162 -50227
  83. package/miniflare-dist/index.mjs.map +0 -7
  84. package/src/__tests__/dev2.test.tsx +0 -154
  85. package/src/__tests__/logout.test.ts +0 -52
  86. package/src/__tests__/sentry.test.ts +0 -146
  87. package/src/reporting.ts +0 -131
  88. package/wrangler-dist/cli.js.map +0 -7
@@ -1,154 +0,0 @@
1
- import * as fs from "node:fs";
2
- import React from "react";
3
- import TestRenderer from "react-test-renderer";
4
- import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
5
- import { unsetAllMocks } from "./helpers/mock-cfetch";
6
- import { mockConsoleMethods } from "./helpers/mock-console";
7
- import { runInTempDir } from "./helpers/run-in-tmp";
8
- import type { DevProps, default as DevType } from "../dev/dev";
9
-
10
- function sleep(period = 100): Promise<void> {
11
- return new Promise((resolve) => setTimeout(resolve, period));
12
- }
13
-
14
- // we use this ["mock"] form to avoid esbuild-jest from rewriting it
15
- jest["mock"]("../proxy", () => {
16
- return {
17
- usePreviewServer() {},
18
- waitForPortToBeAvailable() {},
19
- };
20
- });
21
- jest["mock"]("../inspect", () => {
22
- return () => {};
23
- });
24
-
25
- const Dev: typeof DevType = jest.requireActual("../dev/dev").DevImplementation;
26
-
27
- mockAccountId();
28
- mockApiToken();
29
- runInTempDir();
30
- mockConsoleMethods();
31
- afterEach(() => {
32
- unsetAllMocks();
33
- });
34
-
35
- describe("dev", () => {
36
- it("should render", async () => {
37
- fs.writeFileSync("./index.js", `export default {}`);
38
-
39
- const testRenderer = await renderDev({
40
- entry: {
41
- file: "./index.js",
42
- directory: process.cwd(),
43
- format: "modules",
44
- },
45
- });
46
- expect(testRenderer.toJSON()).toMatchInlineSnapshot(`
47
- <ink-box
48
- style={
49
- Object {
50
- "borderStyle": "round",
51
- "flexDirection": "row",
52
- "flexGrow": 0,
53
- "flexShrink": 1,
54
- "marginBottom": 0,
55
- "marginLeft": 0,
56
- "marginRight": 0,
57
- "marginTop": 0,
58
- "paddingBottom": 0,
59
- "paddingLeft": 1,
60
- "paddingRight": 1,
61
- "paddingTop": 0,
62
- }
63
- }
64
- >
65
- <ink-text
66
- internal_transform={[Function]}
67
- style={
68
- Object {
69
- "flexDirection": "row",
70
- "flexGrow": 0,
71
- "flexShrink": 1,
72
- "textWrap": "wrap",
73
- }
74
- }
75
- >
76
- B to open a browser, D to open Devtools, L to turn off local mode, X to exit
77
- </ink-text>
78
- </ink-box>
79
- `);
80
- await TestRenderer.act(async () => {
81
- // TODO: get rid of these sleep statements
82
- await sleep(50);
83
- testRenderer.unmount();
84
- await sleep(50);
85
- });
86
- await sleep(50);
87
- });
88
- });
89
-
90
- async function renderDev({
91
- name,
92
- entry = { file: "index.js", directory: "", format: "modules" },
93
- port,
94
- ip = "localhost",
95
- inspectorPort = 9229,
96
- accountId,
97
- legacyEnv = true,
98
- initialMode = "local",
99
- jsxFactory,
100
- jsxFragment,
101
- localProtocol = "http",
102
- upstreamProtocol = "https",
103
- rules = [],
104
- bindings = {
105
- kv_namespaces: [],
106
- vars: {},
107
- durable_objects: { bindings: [] },
108
- r2_buckets: [],
109
- wasm_modules: undefined,
110
- text_blobs: undefined,
111
- unsafe: [],
112
- },
113
- public: publicDir,
114
- assetPaths,
115
- compatibilityDate,
116
- compatibilityFlags,
117
- usageModel,
118
- buildCommand = {},
119
- enableLocalPersistence = false,
120
- env,
121
- zone,
122
- }: Partial<DevProps>): Promise<TestRenderer.ReactTestRenderer> {
123
- let instance: TestRenderer.ReactTestRenderer | undefined;
124
- await TestRenderer.act(async () => {
125
- instance = TestRenderer.create(
126
- <Dev
127
- name={name}
128
- entry={entry}
129
- env={env}
130
- rules={rules}
131
- port={port}
132
- ip={ip}
133
- inspectorPort={inspectorPort}
134
- legacyEnv={legacyEnv}
135
- buildCommand={buildCommand}
136
- initialMode={initialMode}
137
- localProtocol={localProtocol}
138
- upstreamProtocol={upstreamProtocol}
139
- jsxFactory={jsxFactory}
140
- jsxFragment={jsxFragment}
141
- accountId={accountId}
142
- assetPaths={assetPaths}
143
- public={publicDir}
144
- compatibilityDate={compatibilityDate}
145
- compatibilityFlags={compatibilityFlags}
146
- usageModel={usageModel}
147
- bindings={bindings}
148
- enableLocalPersistence={enableLocalPersistence}
149
- zone={zone}
150
- />
151
- );
152
- });
153
- return instance as TestRenderer.ReactTestRenderer;
154
- }
@@ -1,52 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import fetchMock from "jest-fetch-mock";
5
- import {
6
- reinitialiseAuthTokens,
7
- USER_AUTH_CONFIG_FILE,
8
- writeAuthConfigFile,
9
- } from "../user";
10
- import { mockConsoleMethods } from "./helpers/mock-console";
11
- import { runInTempDir } from "./helpers/run-in-tmp";
12
- import { runWrangler } from "./helpers/run-wrangler";
13
-
14
- describe("wrangler", () => {
15
- runInTempDir({ homedir: "./home" });
16
- const std = mockConsoleMethods();
17
-
18
- describe("logout", () => {
19
- it("should exit with a message stating the user is not logged in", async () => {
20
- await runWrangler("logout");
21
- expect(std.out).toMatchInlineSnapshot(`"Not logged in, exiting..."`);
22
- });
23
-
24
- it("should logout user that has been properly logged in", async () => {
25
- writeAuthConfigFile({
26
- oauth_token: "some-oauth-tok",
27
- refresh_token: "some-refresh-tok",
28
- });
29
- // Mock out the response for a request to revoke the auth tokens,
30
- // checking the form of the request is as expected.
31
- fetchMock.mockResponseOnce(async (req) => {
32
- expect(req.url).toEqual("https://dash.cloudflare.com/oauth2/revoke");
33
- expect(req.method).toEqual("POST");
34
- return "";
35
- });
36
-
37
- // Now that we have changed the auth tokens in the wrangler.toml we must reinitialize the user auth state.
38
- reinitialiseAuthTokens();
39
- await runWrangler("logout");
40
-
41
- expect(std.out).toMatchInlineSnapshot(`"Successfully logged out."`);
42
-
43
- // Make sure that we made the request to logout.
44
- expect(fetchMock).toHaveBeenCalledTimes(1);
45
-
46
- // Make sure that logout removed the config file containing the auth tokens.
47
- expect(existsSync(path.join(os.homedir(), USER_AUTH_CONFIG_FILE))).toBe(
48
- false
49
- );
50
- });
51
- });
52
- });
@@ -1,146 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as fsp from "node:fs/promises";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import * as TOML from "@iarna/toml";
6
- import * as Sentry from "@sentry/node";
7
- import prompts from "prompts";
8
-
9
- import { mockConsoleMethods } from "./helpers/mock-console";
10
- import { runInTempDir } from "./helpers/run-in-tmp";
11
- import { runWrangler } from "./helpers/run-wrangler";
12
- const { reportError } = jest.requireActual("../reporting");
13
-
14
- describe("Error Reporting", () => {
15
- runInTempDir({ homedir: "./home" });
16
- mockConsoleMethods();
17
- const reportingTOMLPath = ".wrangler/config/reporting.toml";
18
-
19
- const originalTTY = process.stdout.isTTY;
20
- beforeEach(() => {
21
- jest.mock("@sentry/node");
22
- jest.spyOn(Sentry, "captureException");
23
- process.stdout.isTTY = true;
24
- });
25
-
26
- afterEach(() => {
27
- jest.unmock("@sentry/node");
28
- jest.clearAllMocks();
29
- process.stdout.isTTY = originalTTY;
30
- });
31
-
32
- it("should confirm user will allow error reporting usage", async () => {
33
- jest.spyOn(prompts, "prompt").mockResolvedValue({ sentryDecision: true });
34
-
35
- await reportError(new Error("test error"), "testFalse");
36
-
37
- const { error_tracking_opt, error_tracking_opt_date } = TOML.parse(
38
- await fsp.readFile(path.join(os.homedir(), reportingTOMLPath), "utf-8")
39
- );
40
-
41
- expect(error_tracking_opt).toBe(true);
42
- expect(error_tracking_opt_date).toBeTruthy();
43
-
44
- expect(Sentry.captureException).toHaveBeenCalledWith(
45
- new Error("test error")
46
- );
47
- });
48
-
49
- it("should confirm user will disallow error reporting usage", async () => {
50
- jest.spyOn(prompts, "prompt").mockResolvedValue({ sentryDecision: false });
51
- await reportError(new Error("test error"), "testFalse");
52
-
53
- const { error_tracking_opt, error_tracking_opt_date } = TOML.parse(
54
- await fsp.readFile(path.join(os.homedir(), reportingTOMLPath), "utf-8")
55
- );
56
-
57
- expect(error_tracking_opt).toBe(false);
58
- expect(error_tracking_opt_date).toBeTruthy();
59
-
60
- expect(Sentry.captureException).not.toHaveBeenCalledWith(
61
- new Error("test error"),
62
- "testFalse"
63
- );
64
- });
65
-
66
- it("should confirm user will allow 'once' error reporting usage", async () => {
67
- jest.spyOn(prompts, "prompt").mockResolvedValue({ sentryDecision: "once" });
68
- await runWrangler();
69
- await reportError(new Error("test error"), "testFalse");
70
-
71
- expect(fs.existsSync(path.join(os.homedir(), reportingTOMLPath))).toBe(
72
- false
73
- );
74
-
75
- expect(Sentry.captureException).not.toHaveBeenCalledWith(
76
- new Error("test error"),
77
- "testFalse"
78
- );
79
- });
80
-
81
- it("should not prompt w/ subsequent Errors after user disallows error reporting", async () => {
82
- jest.spyOn(prompts, "prompt").mockResolvedValue({ sentryDecision: false });
83
- await reportError(new Error("test error"), "testFalse");
84
-
85
- expect(Sentry.captureException).not.toHaveBeenCalledWith(
86
- new Error("test error"),
87
- "testFalse"
88
- );
89
-
90
- await reportError(new Error("second test error"), "testFalse");
91
- expect(Sentry.captureException).not.toHaveBeenCalledWith(
92
- new Error("second test error"),
93
- "testFalse"
94
- );
95
- });
96
-
97
- it("should not prompt w/ subsequent Errors after user Always allows error reporting", async () => {
98
- jest.spyOn(prompts, "prompt").mockResolvedValue({ sentryDecision: true });
99
- await reportError(new Error("test error"), "testFalse");
100
-
101
- expect(Sentry.captureException).toHaveBeenCalledWith(
102
- new Error("test error")
103
- );
104
-
105
- await reportError(new Error("second test error"), "testFalse");
106
- expect(Sentry.captureException).toHaveBeenCalledWith(
107
- new Error("second test error")
108
- );
109
- });
110
-
111
- it("should prompt w/ subsequent Errors after user allows error reporting once", async () => {
112
- const promptSpy = jest
113
- .spyOn(prompts, "prompt")
114
- .mockResolvedValue({ sentryDecision: "once" });
115
- await reportError(new Error("test error"), "testFalse");
116
-
117
- expect(Sentry.captureException).toHaveBeenCalledWith(
118
- new Error("test error")
119
- );
120
-
121
- await reportError(new Error("second test error"), "testFalse");
122
- expect(Sentry.captureException).toHaveBeenCalledWith(
123
- new Error("second test error")
124
- );
125
-
126
- expect(promptSpy).toBeCalledTimes(2);
127
- });
128
-
129
- it("should not prompt in non-TTY environment", async () => {
130
- process.stdout.isTTY = false;
131
-
132
- await reportError(new Error("test error"), "testFalse");
133
-
134
- const { error_tracking_opt, error_tracking_opt_date } = TOML.parse(
135
- await fsp.readFile(path.join(os.homedir(), reportingTOMLPath), "utf-8")
136
- );
137
-
138
- expect(error_tracking_opt).toBe(false);
139
- expect(error_tracking_opt_date).toBeTruthy();
140
-
141
- expect(Sentry.captureException).not.toHaveBeenCalledWith(
142
- new Error("test error")
143
- );
144
- process.stdout.isTTY = originalTTY;
145
- });
146
- });
package/src/reporting.ts DELETED
@@ -1,131 +0,0 @@
1
- import * as fs from "node:fs";
2
- import { readFile, writeFile } from "node:fs/promises";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import TOML from "@iarna/toml";
6
- import { RewriteFrames } from "@sentry/integrations";
7
- import {
8
- captureException,
9
- getCurrentHub,
10
- startTransaction,
11
- init,
12
- Integrations,
13
- setContext,
14
- } from "@sentry/node";
15
- import { execaSync } from "execa";
16
- import prompts from "prompts";
17
- import * as pkj from "../package.json";
18
-
19
- export function initReporting() {
20
- init({
21
- release: `${pkj.name}@${pkj.version}`,
22
- initialScope: {
23
- tags: { [pkj.name]: pkj.version },
24
- },
25
- beforeBreadcrumb: (_breadcrumb, _hint) => {
26
- // eventually, we might want to actually start dropping our own breadcrumbs.
27
- // until then, we want to just ignore all of them, since sentry will
28
- // automatically include breadcrumbs for things like console output,
29
- // which can include unsanitized data that the user logs
30
- // from their worker during development
31
- return null;
32
- },
33
- dsn: "https://5089b76bf8a64a9c949bf5c2b5e8003c@o51786.ingest.sentry.io/6190959",
34
- tracesSampleRate: 1.0,
35
- integrations: [
36
- new RewriteFrames({
37
- root: "",
38
- prefix: "/",
39
- }),
40
- new Integrations.Http({ tracing: true }),
41
- ],
42
- });
43
-
44
- setContext("System Information", {
45
- OS: process.platform,
46
- node: process.version,
47
- npm: execaSync("npm", ["--version"]).stdout,
48
- wrangler: pkj.version,
49
- });
50
- }
51
-
52
- async function appendReportingDecision(userInput: "true" | "false") {
53
- const homePath = path.join(os.homedir(), ".wrangler/config/");
54
- const reportingConfigLocation = path.join(homePath, "reporting.toml");
55
- try {
56
- fs.mkdirSync(homePath, { recursive: true });
57
- await writeFile(
58
- reportingConfigLocation,
59
- `error_tracking_opt = ${userInput} # Sentry \nerror_tracking_opt_date = ${new Date().toISOString()} # Sentry Date Decision \n`,
60
- "utf-8"
61
- );
62
- } catch (err) {
63
- console.warn(
64
- `Unable to create wrangler's error reporting configuration file at ${reportingConfigLocation}: `,
65
- err
66
- );
67
- }
68
- }
69
-
70
- function exceptionTransaction(error: Error, origin = "") {
71
- const transaction = startTransaction({
72
- op: origin,
73
- name: error.name,
74
- });
75
- captureException(error);
76
- transaction.finish();
77
- }
78
-
79
- export async function reportError(err: Error, origin = "") {
80
- if (!process.stdout.isTTY) return await appendReportingDecision("false");
81
-
82
- const errorTrackingOpt = await reportingPermission();
83
-
84
- if (errorTrackingOpt === undefined) {
85
- const userInput = await prompts.prompt({
86
- type: "select",
87
- name: "sentryDecision",
88
- message: "Would you like to submit a report when an error occurs?",
89
- choices: [
90
- { title: "Always", value: true },
91
- { title: "Only this time", value: "once" },
92
- { title: "No", value: false },
93
- ],
94
- initial: 2,
95
- });
96
-
97
- if (userInput.sentryDecision === "once") {
98
- exceptionTransaction(err, origin);
99
- return;
100
- }
101
-
102
- userInput.sentryDecision
103
- ? await appendReportingDecision("true")
104
- : await appendReportingDecision("false");
105
- }
106
-
107
- if (!errorTrackingOpt) {
108
- const sentryClient = getCurrentHub().getClient();
109
- if (sentryClient !== undefined) sentryClient.getOptions().enabled = false;
110
- }
111
-
112
- exceptionTransaction(err, origin);
113
- }
114
-
115
- async function reportingPermission() {
116
- if (
117
- !fs.existsSync(path.join(os.homedir(), ".wrangler/config/reporting.toml"))
118
- )
119
- return undefined;
120
-
121
- const reportingTOML = TOML.parse(
122
- await readFile(path.join(os.homedir(), ".wrangler/config/reporting.toml"), {
123
- encoding: "utf-8",
124
- })
125
- );
126
- const { error_tracking_opt } = reportingTOML as {
127
- error_tracking_opt: string | undefined;
128
- };
129
-
130
- return error_tracking_opt;
131
- }