wrangler 0.0.0-e178d6fb → 0.0.0-e1c2f5b9
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 +16 -2
- package/bin/wrangler.js +31 -11
- package/miniflare-dist/index.mjs +1340 -330
- package/package.json +40 -13
- package/src/__tests__/access.test.ts +25 -0
- package/src/__tests__/api-dev.test.ts +238 -0
- package/src/__tests__/api-devregistry.test.js +64 -0
- package/src/__tests__/api.test.ts +80 -0
- package/src/__tests__/configuration.test.ts +683 -470
- package/src/__tests__/d1.test.ts +123 -0
- package/src/__tests__/delete.test.ts +263 -0
- package/src/__tests__/deployments.test.ts +105 -0
- package/src/__tests__/dev.test.tsx +453 -70
- package/src/__tests__/dialogs.test.tsx +40 -0
- package/src/__tests__/generate.test.ts +235 -0
- package/src/__tests__/get-host-from-url.test.ts +16 -0
- package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-cfetch.ts +92 -26
- package/src/__tests__/helpers/mock-console.ts +11 -2
- package/src/__tests__/helpers/mock-dialogs.ts +1 -1
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
- package/src/__tests__/helpers/mock-known-routes.ts +7 -0
- package/src/__tests__/helpers/mock-kv.ts +1 -1
- package/src/__tests__/helpers/mock-oauth-flow.ts +74 -53
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +59 -0
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
- package/src/__tests__/helpers/msw/handlers/oauth.ts +31 -0
- package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
- package/src/__tests__/helpers/msw/handlers/script.ts +75 -0
- package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
- package/src/__tests__/helpers/msw/handlers/zones.ts +22 -0
- package/src/__tests__/helpers/msw/index.ts +21 -0
- package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
- package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
- package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
- package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
- package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
- package/src/__tests__/index.test.ts +103 -97
- package/src/__tests__/init.test.ts +1484 -382
- package/src/__tests__/jest.setup.ts +88 -5
- package/src/__tests__/kv.test.ts +655 -540
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +95 -45
- package/src/__tests__/middleware.scheduled.test.ts +145 -0
- package/src/__tests__/middleware.test.ts +750 -0
- package/src/__tests__/pages-deployment-tail.test.ts +884 -0
- package/src/__tests__/pages.test.ts +1301 -119
- package/src/__tests__/paths.test.ts +39 -0
- package/src/__tests__/publish.test.ts +2266 -1180
- package/src/__tests__/pubsub.test.ts +211 -88
- package/src/__tests__/queues.test.ts +522 -0
- package/src/__tests__/r2.test.ts +363 -203
- package/src/__tests__/secret.test.ts +261 -59
- package/src/__tests__/tail.test.ts +352 -151
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/type-generation.test.ts +233 -0
- package/src/__tests__/user.test.ts +59 -73
- package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
- package/src/__tests__/validate-dev-props.test.ts +56 -0
- package/src/__tests__/whoami.test.tsx +114 -66
- package/src/__tests__/worker-namespace.test.ts +154 -155
- package/src/api/dev.ts +170 -38
- package/src/api/index.ts +1 -0
- package/src/bundle-reporter.tsx +41 -2
- package/src/bundle.ts +668 -81
- package/src/cfetch/index.ts +40 -3
- package/src/cfetch/internal.ts +144 -32
- package/src/cli.ts +4 -3
- package/src/config/config.ts +27 -3
- package/src/config/environment.ts +131 -7
- package/src/config/index.ts +128 -8
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +411 -14
- package/src/config-cache.ts +3 -2
- package/src/create-worker-preview.ts +31 -6
- package/src/create-worker-upload-form.ts +84 -22
- package/src/d1/backups.tsx +223 -0
- package/src/d1/constants.ts +2 -0
- package/src/d1/create.tsx +63 -0
- package/src/d1/delete.tsx +56 -0
- package/src/d1/execute.tsx +352 -0
- package/src/d1/formatTimeAgo.ts +14 -0
- package/src/d1/index.ts +101 -0
- package/src/d1/list.tsx +48 -0
- package/src/d1/migrations/apply.tsx +196 -0
- package/src/d1/migrations/create.tsx +77 -0
- package/src/d1/migrations/helpers.ts +147 -0
- package/src/d1/migrations/index.tsx +3 -0
- package/src/d1/migrations/list.tsx +79 -0
- package/src/d1/migrations/options.ts +18 -0
- package/src/d1/options.ts +22 -0
- package/src/d1/types.tsx +24 -0
- package/src/d1/utils.ts +48 -0
- package/src/delete.ts +108 -0
- package/src/deployments.ts +83 -0
- package/src/deprecated/index.ts +145 -0
- package/src/dev/dev-vars.ts +11 -8
- package/src/dev/dev.tsx +220 -58
- package/src/dev/get-local-persistence-path.tsx +31 -0
- package/src/dev/local.tsx +740 -181
- package/src/dev/remote.tsx +340 -123
- package/src/dev/start-server.ts +543 -0
- package/src/dev/use-esbuild.ts +61 -7
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +201 -0
- package/src/dev.tsx +614 -258
- package/src/dialogs.tsx +41 -8
- package/src/{worker-namespace.ts → dispatch-namespace.ts} +23 -22
- package/src/docs/index.ts +97 -0
- package/src/entry.ts +3 -2
- package/src/environment-variables/factory.ts +88 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +300 -0
- package/src/git-client.ts +100 -7
- package/src/index.tsx +249 -1560
- package/src/init.ts +626 -150
- package/src/inspect.ts +137 -32
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/is-interactive.ts +4 -0
- package/src/jest.d.ts +4 -0
- package/src/{kv.ts → kv/helpers.ts} +3 -3
- package/src/kv/index.ts +596 -0
- package/src/logger.ts +27 -8
- package/src/metrics/index.ts +1 -0
- package/src/metrics/metrics-config.ts +4 -4
- package/src/metrics/metrics-dispatcher.ts +1 -0
- package/src/metrics/metrics-usage-headers.ts +24 -0
- package/src/metrics/send-event.ts +13 -8
- package/src/miniflare-cli/assets.ts +172 -465
- package/src/miniflare-cli/index.ts +149 -24
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/module-collection.ts +12 -3
- package/src/pages/build.tsx +108 -42
- package/src/pages/constants.ts +11 -0
- package/src/pages/deployment-tails.tsx +284 -0
- package/src/pages/deployments.tsx +9 -31
- package/src/pages/dev.tsx +417 -108
- package/src/pages/errors.ts +66 -0
- package/src/pages/functions/buildPlugin.ts +86 -84
- package/src/pages/functions/buildWorker.ts +121 -106
- package/src/pages/functions/routes-consolidation.test.ts +250 -0
- package/src/pages/functions/routes-consolidation.ts +73 -0
- package/src/pages/functions/routes-transformation.test.ts +282 -0
- package/src/pages/functions/routes-transformation.ts +115 -0
- package/src/pages/functions/routes-validation.test.ts +403 -0
- package/src/pages/functions/routes-validation.ts +202 -0
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/functions.tsx +82 -0
- package/src/pages/hash.tsx +13 -0
- package/src/pages/index.tsx +73 -55
- package/src/pages/projects.tsx +9 -3
- package/src/pages/prompt-select-project.tsx +31 -0
- package/src/pages/publish.tsx +183 -60
- package/src/pages/types.ts +1 -0
- package/src/pages/upload.tsx +107 -56
- package/src/pages/utils.ts +13 -2
- package/src/paths.ts +49 -4
- package/src/proxy.ts +375 -157
- package/src/publish/index.ts +270 -0
- package/src/{publish.ts → publish/publish.ts} +431 -188
- package/src/pubsub/pubsub-commands.tsx +4 -3
- package/src/queues/cli/commands/consumer/add.ts +71 -0
- package/src/queues/cli/commands/consumer/index.ts +22 -0
- package/src/queues/cli/commands/consumer/remove.ts +38 -0
- package/src/queues/cli/commands/create.ts +25 -0
- package/src/queues/cli/commands/delete.ts +26 -0
- package/src/queues/cli/commands/index.ts +36 -0
- package/src/queues/cli/commands/list.ts +25 -0
- package/src/queues/client.ts +135 -0
- package/src/queues/utils.ts +18 -0
- package/src/r2/constants.ts +4 -0
- package/src/r2/helpers.ts +131 -0
- package/src/r2/index.ts +289 -0
- package/src/routes.ts +140 -0
- package/src/secret/index.ts +379 -0
- package/src/sites.tsx +3 -3
- package/src/tail/createTail.ts +379 -0
- package/src/tail/filters.ts +4 -6
- package/src/tail/index.ts +199 -284
- package/src/tail/printing.ts +43 -3
- package/src/tsconfig-sanity.ts +16 -0
- package/src/type-generation.ts +181 -0
- package/src/user/access.ts +68 -0
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -1
- package/src/user/index.ts +0 -1
- package/src/user/user.tsx +116 -49
- package/src/utils/collectKeyValues.ts +14 -0
- package/src/whoami.tsx +80 -2
- package/src/worker.ts +69 -9
- package/src/yargs-types.ts +24 -0
- package/src/zones.ts +124 -9
- package/templates/__tests__/pages-dev-util.test.ts +128 -0
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/d1-beta-facade.js +205 -0
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +19 -0
- package/templates/format-dev-errors.ts +33 -0
- package/templates/init-tests/test-jest-new-worker.js +23 -0
- package/templates/init-tests/test-vitest-new-worker.js +24 -0
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/common.ts +62 -0
- package/templates/middleware/loader-modules.ts +82 -0
- package/templates/middleware/loader-sw.ts +233 -0
- package/templates/middleware/middleware-miniflare3-json-error.ts +20 -0
- package/templates/middleware/middleware-pretty-error.ts +40 -0
- package/templates/middleware/middleware-scheduled.ts +15 -0
- package/templates/new-worker.js +1 -1
- package/templates/pages-dev-pipeline.ts +31 -0
- package/templates/pages-dev-util.ts +52 -0
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +21 -5
- package/templates/pages-template-worker.ts +37 -9
- package/templates/{static-asset-facade.js → serve-static-assets.ts} +23 -7
- package/templates/service-bindings-module-facade.js +54 -0
- package/templates/service-bindings-sw-facade.js +42 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +106 -0
- package/templates/tsconfig.json +5 -102
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +621 -42
- package/wrangler-dist/cli.js +144441 -102606
- package/src/environment-variables.ts +0 -35
- package/src/faye-websocket.d.ts +0 -6
- package/src/generate.ts +0 -33
- package/src/miniflare-cli/enum-keys.ts +0 -17
- package/src/preview.ts +0 -31
- package/src/r2.ts +0 -50
- package/src/user/env-vars.ts +0 -46
package/src/pages/dev.tsx
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
import { execSync, spawn } from "node:child_process";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { homedir, tmpdir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { watch } from "chokidar";
|
|
6
|
+
import * as esbuild from "esbuild";
|
|
6
7
|
import { unstable_dev } from "../api";
|
|
8
|
+
import { esbuildAliasExternalPlugin } from "../bundle";
|
|
7
9
|
import { FatalError } from "../errors";
|
|
8
10
|
import { logger } from "../logger";
|
|
9
11
|
import * as metrics from "../metrics";
|
|
12
|
+
import { getBasePath } from "../paths";
|
|
10
13
|
import { buildFunctions } from "./build";
|
|
11
|
-
import { SECONDS_TO_WAIT_FOR_PROXY } from "./constants";
|
|
14
|
+
import { ROUTES_SPEC_VERSION, SECONDS_TO_WAIT_FOR_PROXY } from "./constants";
|
|
15
|
+
import { FunctionsNoRoutesError, getFunctionsNoRoutesWarning } from "./errors";
|
|
16
|
+
import { validateRoutes } from "./functions/routes-validation";
|
|
12
17
|
import { CLEANUP, CLEANUP_CALLBACKS, pagesBetaWarning } from "./utils";
|
|
13
|
-
import type {
|
|
14
|
-
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"script-path": string;
|
|
22
|
-
binding?: (string | number)[];
|
|
23
|
-
kv?: (string | number)[];
|
|
24
|
-
do?: (string | number)[];
|
|
25
|
-
"live-reload": boolean;
|
|
26
|
-
"local-protocol"?: "https" | "http";
|
|
27
|
-
"node-compat": boolean;
|
|
28
|
-
};
|
|
18
|
+
import type { AdditionalDevProps } from "../dev";
|
|
19
|
+
import type { YargsOptionsToInterface } from "../yargs-types";
|
|
20
|
+
import type { RoutesJSONSpec } from "./functions/routes-transformation";
|
|
21
|
+
import type { Argv } from "yargs";
|
|
22
|
+
|
|
23
|
+
const DURABLE_OBJECTS_BINDING_REGEXP = new RegExp(
|
|
24
|
+
/^(?<binding>[^=]+)=(?<className>[^@\s]+)(@(?<scriptName>.*)$)?$/
|
|
25
|
+
);
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
type PagesDevArgs = YargsOptionsToInterface<typeof Options>;
|
|
28
|
+
|
|
29
|
+
export function Options(yargs: Argv) {
|
|
31
30
|
return yargs
|
|
32
31
|
.positional("directory", {
|
|
33
32
|
type: "string",
|
|
@@ -45,11 +44,30 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
45
44
|
default: true,
|
|
46
45
|
description: "Run on my machine",
|
|
47
46
|
},
|
|
47
|
+
"compatibility-date": {
|
|
48
|
+
describe: "Date to use for compatibility checks",
|
|
49
|
+
type: "string",
|
|
50
|
+
},
|
|
51
|
+
"compatibility-flags": {
|
|
52
|
+
describe: "Flags to use for compatibility checks",
|
|
53
|
+
alias: "compatibility-flag",
|
|
54
|
+
type: "string",
|
|
55
|
+
array: true,
|
|
56
|
+
},
|
|
57
|
+
ip: {
|
|
58
|
+
type: "string",
|
|
59
|
+
default: "0.0.0.0",
|
|
60
|
+
description: "The IP address to listen on",
|
|
61
|
+
},
|
|
48
62
|
port: {
|
|
49
63
|
type: "number",
|
|
50
64
|
default: 8788,
|
|
51
65
|
description: "The port to listen on (serve from)",
|
|
52
66
|
},
|
|
67
|
+
"inspector-port": {
|
|
68
|
+
type: "number",
|
|
69
|
+
describe: "Port for devtools to connect to",
|
|
70
|
+
},
|
|
53
71
|
proxy: {
|
|
54
72
|
type: "number",
|
|
55
73
|
description: "The port to proxy (where the static assets are served)",
|
|
@@ -67,14 +85,22 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
67
85
|
},
|
|
68
86
|
kv: {
|
|
69
87
|
type: "array",
|
|
70
|
-
description: "KV namespace to bind",
|
|
88
|
+
description: "KV namespace to bind (--kv KV_BINDING)",
|
|
71
89
|
alias: "k",
|
|
72
90
|
},
|
|
91
|
+
d1: {
|
|
92
|
+
type: "array",
|
|
93
|
+
description: "D1 database to bind",
|
|
94
|
+
},
|
|
73
95
|
do: {
|
|
74
96
|
type: "array",
|
|
75
|
-
description: "Durable Object to bind (NAME=CLASS)",
|
|
97
|
+
description: "Durable Object to bind (--do NAME=CLASS)",
|
|
76
98
|
alias: "o",
|
|
77
99
|
},
|
|
100
|
+
r2: {
|
|
101
|
+
type: "array",
|
|
102
|
+
description: "R2 bucket to bind (--r2 R2_BINDING)",
|
|
103
|
+
},
|
|
78
104
|
"live-reload": {
|
|
79
105
|
type: "boolean",
|
|
80
106
|
default: false,
|
|
@@ -84,17 +110,44 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
84
110
|
describe: "Protocol to listen to requests on, defaults to http.",
|
|
85
111
|
choices: ["http", "https"] as const,
|
|
86
112
|
},
|
|
113
|
+
"experimental-enable-local-persistence": {
|
|
114
|
+
describe:
|
|
115
|
+
"Enable persistence for local mode (deprecated, use --persist)",
|
|
116
|
+
type: "boolean",
|
|
117
|
+
deprecated: true,
|
|
118
|
+
hidden: true,
|
|
119
|
+
},
|
|
120
|
+
persist: {
|
|
121
|
+
describe:
|
|
122
|
+
"Enable persistence for local mode, using default path: .wrangler/state",
|
|
123
|
+
type: "boolean",
|
|
124
|
+
},
|
|
125
|
+
"persist-to": {
|
|
126
|
+
describe:
|
|
127
|
+
"Specify directory to use for local persistence (implies --persist)",
|
|
128
|
+
type: "string",
|
|
129
|
+
requiresArg: true,
|
|
130
|
+
},
|
|
87
131
|
"node-compat": {
|
|
88
132
|
describe: "Enable node.js compatibility",
|
|
89
133
|
default: false,
|
|
90
134
|
type: "boolean",
|
|
91
135
|
hidden: true,
|
|
92
136
|
},
|
|
137
|
+
"experimental-local": {
|
|
138
|
+
describe: "Run on my machine using the Cloudflare Workers runtime",
|
|
139
|
+
type: "boolean",
|
|
140
|
+
default: false,
|
|
141
|
+
},
|
|
93
142
|
config: {
|
|
94
143
|
describe: "Pages does not support wrangler.toml",
|
|
95
144
|
type: "string",
|
|
96
145
|
hidden: true,
|
|
97
146
|
},
|
|
147
|
+
"log-level": {
|
|
148
|
+
choices: ["debug", "info", "log", "warn", "error", "none"] as const,
|
|
149
|
+
describe: "Specify logging level",
|
|
150
|
+
},
|
|
98
151
|
})
|
|
99
152
|
.epilogue(pagesBetaWarning);
|
|
100
153
|
}
|
|
@@ -102,21 +155,38 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
102
155
|
export const Handler = async ({
|
|
103
156
|
local,
|
|
104
157
|
directory,
|
|
158
|
+
"compatibility-date": compatibilityDate,
|
|
159
|
+
"compatibility-flags": compatibilityFlags,
|
|
160
|
+
ip,
|
|
105
161
|
port,
|
|
162
|
+
"inspector-port": inspectorPort,
|
|
106
163
|
proxy: requestedProxyPort,
|
|
107
164
|
"script-path": singleWorkerScriptPath,
|
|
108
165
|
binding: bindings = [],
|
|
109
166
|
kv: kvs = [],
|
|
110
167
|
do: durableObjects = [],
|
|
168
|
+
d1: d1s = [],
|
|
169
|
+
r2: r2s = [],
|
|
111
170
|
"live-reload": liveReload,
|
|
112
171
|
"local-protocol": localProtocol,
|
|
172
|
+
experimentalEnableLocalPersistence,
|
|
173
|
+
persist,
|
|
174
|
+
persistTo,
|
|
113
175
|
"node-compat": nodeCompat,
|
|
176
|
+
"experimental-local": experimentalLocal,
|
|
114
177
|
config: config,
|
|
115
178
|
_: [_pages, _dev, ...remaining],
|
|
116
|
-
|
|
179
|
+
logLevel,
|
|
180
|
+
}: PagesDevArgs) => {
|
|
117
181
|
// Beta message for `wrangler pages <commands>` usage
|
|
118
182
|
logger.log(pagesBetaWarning);
|
|
119
183
|
|
|
184
|
+
type LogLevelArg = "debug" | "info" | "log" | "warn" | "error" | "none";
|
|
185
|
+
if (logLevel) {
|
|
186
|
+
// The YargsOptionsToInterface doesn't handle the passing in of Unions from choices in Yargs
|
|
187
|
+
logger.loggerLevel = logLevel as LogLevelArg;
|
|
188
|
+
}
|
|
189
|
+
|
|
120
190
|
if (!local) {
|
|
121
191
|
throw new FatalError("Only local mode is supported at the moment.", 1);
|
|
122
192
|
}
|
|
@@ -125,14 +195,16 @@ export const Handler = async ({
|
|
|
125
195
|
throw new FatalError("Pages does not support wrangler.toml", 1);
|
|
126
196
|
}
|
|
127
197
|
|
|
128
|
-
const functionsDirectory = "./functions";
|
|
129
|
-
const usingFunctions = existsSync(functionsDirectory);
|
|
130
|
-
|
|
131
198
|
const command = remaining;
|
|
132
199
|
|
|
133
200
|
let proxyPort: number | undefined;
|
|
134
201
|
|
|
135
|
-
if (directory
|
|
202
|
+
if (directory !== undefined && command.length > 0) {
|
|
203
|
+
throw new FatalError(
|
|
204
|
+
"Specify either a directory OR a proxy command, not both.",
|
|
205
|
+
1
|
|
206
|
+
);
|
|
207
|
+
} else if (directory === undefined) {
|
|
136
208
|
proxyPort = await spawnProxyProcess({
|
|
137
209
|
port: requestedProxyPort,
|
|
138
210
|
command,
|
|
@@ -142,15 +214,71 @@ export const Handler = async ({
|
|
|
142
214
|
directory = resolve(directory);
|
|
143
215
|
}
|
|
144
216
|
|
|
217
|
+
if (!compatibilityDate) {
|
|
218
|
+
const currentDate = new Date().toISOString().substring(0, 10);
|
|
219
|
+
logger.warn(
|
|
220
|
+
`No compatibility_date was specified. Using today's date: ${currentDate}.\n` +
|
|
221
|
+
"Pass it in your terminal:\n" +
|
|
222
|
+
"```\n" +
|
|
223
|
+
`--compatibility-date=${currentDate}\n` +
|
|
224
|
+
"```\n" +
|
|
225
|
+
"See https://developers.cloudflare.com/workers/platform/compatibility-dates/ for more information."
|
|
226
|
+
);
|
|
227
|
+
compatibilityDate = currentDate;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (experimentalEnableLocalPersistence) {
|
|
231
|
+
logger.warn(
|
|
232
|
+
`--experimental-enable-local-persistence is deprecated.\n` +
|
|
233
|
+
`Move any existing data to .wrangler/state and use --persist, or\n` +
|
|
234
|
+
`use --persist-to=./wrangler-local-state to keep using the old path.`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
145
238
|
let scriptReadyResolve: () => void;
|
|
146
239
|
const scriptReadyPromise = new Promise<void>(
|
|
147
240
|
(promiseResolve) => (scriptReadyResolve = promiseResolve)
|
|
148
241
|
);
|
|
149
242
|
|
|
150
|
-
|
|
243
|
+
const workerScriptPath =
|
|
244
|
+
directory !== undefined
|
|
245
|
+
? join(directory, singleWorkerScriptPath)
|
|
246
|
+
: singleWorkerScriptPath;
|
|
247
|
+
const usingWorkerScript = existsSync(workerScriptPath);
|
|
248
|
+
|
|
249
|
+
const functionsDirectory = "./functions";
|
|
250
|
+
let usingFunctions = !usingWorkerScript && existsSync(functionsDirectory);
|
|
251
|
+
|
|
252
|
+
let scriptPath = "";
|
|
253
|
+
|
|
254
|
+
if (usingWorkerScript) {
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
256
|
+
scriptReadyResolve!();
|
|
151
257
|
|
|
152
|
-
|
|
153
|
-
|
|
258
|
+
scriptPath = workerScriptPath;
|
|
259
|
+
|
|
260
|
+
const runBuild = async () => {
|
|
261
|
+
try {
|
|
262
|
+
await esbuild.build({
|
|
263
|
+
entryPoints: [scriptPath],
|
|
264
|
+
write: false,
|
|
265
|
+
// we need it to be bundled so that any imports that are used are affected by the blocker plugin
|
|
266
|
+
bundle: true,
|
|
267
|
+
plugins: [blockWorkerJsImports],
|
|
268
|
+
});
|
|
269
|
+
} catch {}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
await runBuild();
|
|
273
|
+
watch([scriptPath], {
|
|
274
|
+
persistent: true,
|
|
275
|
+
ignoreInitial: true,
|
|
276
|
+
}).on("all", async () => {
|
|
277
|
+
await runBuild();
|
|
278
|
+
});
|
|
279
|
+
} else if (usingFunctions) {
|
|
280
|
+
// Try to use Functions
|
|
281
|
+
const outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.mjs`);
|
|
154
282
|
scriptPath = outfile;
|
|
155
283
|
|
|
156
284
|
if (nodeCompat) {
|
|
@@ -160,111 +288,264 @@ export const Handler = async ({
|
|
|
160
288
|
}
|
|
161
289
|
|
|
162
290
|
logger.log(`Compiling worker to "${outfile}"...`);
|
|
163
|
-
|
|
291
|
+
const onEnd = () => scriptReadyResolve();
|
|
164
292
|
try {
|
|
165
293
|
await buildFunctions({
|
|
166
294
|
outfile,
|
|
167
295
|
functionsDirectory,
|
|
168
296
|
sourcemap: true,
|
|
169
297
|
watch: true,
|
|
170
|
-
onEnd
|
|
298
|
+
onEnd,
|
|
171
299
|
buildOutputDirectory: directory,
|
|
172
300
|
nodeCompat,
|
|
301
|
+
local: true,
|
|
173
302
|
});
|
|
174
303
|
await metrics.sendMetricsEvent("build pages functions");
|
|
175
|
-
} catch {}
|
|
176
304
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
305
|
+
// If Functions found routes, continue using Functions
|
|
306
|
+
watch([functionsDirectory], {
|
|
307
|
+
persistent: true,
|
|
308
|
+
ignoreInitial: true,
|
|
309
|
+
}).on("all", async () => {
|
|
310
|
+
try {
|
|
311
|
+
await buildFunctions({
|
|
312
|
+
outfile,
|
|
313
|
+
functionsDirectory,
|
|
314
|
+
sourcemap: true,
|
|
315
|
+
watch: true,
|
|
316
|
+
onEnd,
|
|
317
|
+
buildOutputDirectory: directory,
|
|
318
|
+
nodeCompat,
|
|
319
|
+
local: true,
|
|
320
|
+
});
|
|
321
|
+
await metrics.sendMetricsEvent("build pages functions");
|
|
322
|
+
} catch (e) {
|
|
323
|
+
if (e instanceof FunctionsNoRoutesError) {
|
|
324
|
+
logger.warn(
|
|
325
|
+
getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
|
|
326
|
+
);
|
|
327
|
+
} else {
|
|
328
|
+
throw e;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
189
331
|
});
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
332
|
+
} catch (e) {
|
|
333
|
+
// If there are no Functions, then Pages will only serve assets.
|
|
334
|
+
if (e instanceof FunctionsNoRoutesError) {
|
|
335
|
+
logger.warn(
|
|
336
|
+
getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
|
|
337
|
+
);
|
|
338
|
+
// Resolve anyway and run without Functions
|
|
339
|
+
onEnd();
|
|
340
|
+
// Turn off Functions
|
|
341
|
+
usingFunctions = false;
|
|
342
|
+
} else {
|
|
343
|
+
throw e;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Depending on the result of building Functions, we may not actually be using
|
|
349
|
+
// Functions even if the directory exists.
|
|
350
|
+
if (!usingFunctions && !usingWorkerScript) {
|
|
193
351
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
194
352
|
scriptReadyResolve!();
|
|
195
353
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
354
|
+
logger.log("No functions. Shimming...");
|
|
355
|
+
scriptPath = resolve(getBasePath(), "templates/pages-shim.ts");
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
await scriptReadyPromise;
|
|
359
|
+
|
|
360
|
+
if (scriptPath === "") {
|
|
361
|
+
// Failed to get a script with or without Functions,
|
|
362
|
+
// something really bad must have happend.
|
|
363
|
+
throw new FatalError(
|
|
364
|
+
"Failed to start wrangler pages dev due to an unknown error",
|
|
365
|
+
1
|
|
366
|
+
);
|
|
367
|
+
}
|
|
200
368
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
369
|
+
let entrypoint = scriptPath;
|
|
370
|
+
|
|
371
|
+
// custom _routes.json apply only to Functions or Advanced Mode Pages projects
|
|
372
|
+
if (directory && (usingFunctions || usingWorkerScript)) {
|
|
373
|
+
const routesJSONPath = join(directory, "_routes.json");
|
|
374
|
+
|
|
375
|
+
if (existsSync(routesJSONPath)) {
|
|
376
|
+
let routesJSONContents: string;
|
|
377
|
+
const runBuild = async (
|
|
378
|
+
entrypointFile: string,
|
|
379
|
+
outfile: string,
|
|
380
|
+
routes: string
|
|
381
|
+
) => {
|
|
382
|
+
await esbuild.build({
|
|
383
|
+
entryPoints: [
|
|
384
|
+
resolve(getBasePath(), "templates/pages-dev-pipeline.ts"),
|
|
385
|
+
],
|
|
386
|
+
bundle: true,
|
|
387
|
+
sourcemap: true,
|
|
388
|
+
format: "esm",
|
|
389
|
+
plugins: [
|
|
390
|
+
esbuildAliasExternalPlugin({
|
|
391
|
+
__ENTRY_POINT__: entrypointFile,
|
|
392
|
+
"./pages-dev-util": resolve(
|
|
393
|
+
getBasePath(),
|
|
394
|
+
"templates/pages-dev-util.ts"
|
|
395
|
+
),
|
|
396
|
+
}),
|
|
397
|
+
],
|
|
398
|
+
outfile,
|
|
399
|
+
define: {
|
|
400
|
+
__ROUTES__: routes,
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
try {
|
|
406
|
+
// always run the routes validation first. If _routes.json is invalid we
|
|
407
|
+
// want to throw accordingly and exit.
|
|
408
|
+
routesJSONContents = readFileSync(routesJSONPath, "utf-8");
|
|
409
|
+
validateRoutes(JSON.parse(routesJSONContents), directory);
|
|
410
|
+
|
|
411
|
+
entrypoint = join(
|
|
412
|
+
tmpdir(),
|
|
413
|
+
`${Math.random().toString(36).slice(2)}.js`
|
|
414
|
+
);
|
|
415
|
+
await runBuild(scriptPath, entrypoint, routesJSONContents);
|
|
416
|
+
} catch (err) {
|
|
417
|
+
if (err instanceof FatalError) {
|
|
418
|
+
throw err;
|
|
419
|
+
} else {
|
|
420
|
+
throw new FatalError(
|
|
421
|
+
`Could not validate _routes.json at ${directory}: ${err}`,
|
|
422
|
+
1
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
watch([routesJSONPath], {
|
|
428
|
+
persistent: true,
|
|
429
|
+
ignoreInitial: true,
|
|
430
|
+
}).on("all", async () => {
|
|
431
|
+
try {
|
|
432
|
+
/**
|
|
433
|
+
* Watch for _routes.json file changes and validate file each time.
|
|
434
|
+
* If file is valid proceed to running the build.
|
|
435
|
+
*/
|
|
436
|
+
routesJSONContents = readFileSync(routesJSONPath, "utf-8");
|
|
437
|
+
validateRoutes(JSON.parse(routesJSONContents), directory as string);
|
|
438
|
+
await runBuild(scriptPath, entrypoint, routesJSONContents);
|
|
439
|
+
} catch (err) {
|
|
440
|
+
/**
|
|
441
|
+
* If _routes.json is invalid, don't exit but instead fallback to a sensible default
|
|
442
|
+
* and continue to serve the assets. At the same time make sure we warn users that we
|
|
443
|
+
* we detected an invalid file and that we'll be using a default.
|
|
444
|
+
* This basically equivalates to serving a Functions or _worker.js project as is,
|
|
445
|
+
* without applying any additional routing rules on top.
|
|
446
|
+
*/
|
|
447
|
+
const error =
|
|
448
|
+
err instanceof FatalError
|
|
449
|
+
? err
|
|
450
|
+
: `Could not validate _routes.json at ${directory}: ${err}`;
|
|
451
|
+
const defaultRoutesJSONSpec: RoutesJSONSpec = {
|
|
452
|
+
version: ROUTES_SPEC_VERSION,
|
|
453
|
+
include: ["/*"],
|
|
454
|
+
exclude: [],
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
logger.error(error);
|
|
458
|
+
logger.warn(
|
|
459
|
+
`Falling back to the following _routes.json default: ${JSON.stringify(
|
|
460
|
+
defaultRoutesJSONSpec,
|
|
461
|
+
null,
|
|
462
|
+
2
|
|
463
|
+
)}`
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
routesJSONContents = JSON.stringify(defaultRoutesJSONSpec);
|
|
467
|
+
await runBuild(scriptPath, entrypoint, routesJSONContents);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
204
470
|
}
|
|
205
471
|
}
|
|
206
472
|
|
|
207
|
-
await
|
|
473
|
+
const { stop, waitUntilExit } = await unstable_dev(entrypoint, {
|
|
474
|
+
ip,
|
|
475
|
+
port,
|
|
476
|
+
inspectorPort,
|
|
477
|
+
watch: true,
|
|
478
|
+
localProtocol,
|
|
479
|
+
liveReload,
|
|
480
|
+
compatibilityDate,
|
|
481
|
+
compatibilityFlags,
|
|
482
|
+
nodeCompat,
|
|
483
|
+
experimentalLocal,
|
|
484
|
+
vars: Object.fromEntries(
|
|
485
|
+
bindings
|
|
486
|
+
.map((binding) => binding.toString().split("="))
|
|
487
|
+
.map(([key, ...values]) => [key, values.join("=")])
|
|
488
|
+
),
|
|
489
|
+
kv: kvs.map((binding) => ({
|
|
490
|
+
binding: binding.toString(),
|
|
491
|
+
id: "",
|
|
492
|
+
})),
|
|
493
|
+
durableObjects: durableObjects
|
|
494
|
+
.map((durableObject) => {
|
|
495
|
+
const { binding, className, scriptName } =
|
|
496
|
+
DURABLE_OBJECTS_BINDING_REGEXP.exec(durableObject.toString())
|
|
497
|
+
?.groups || {};
|
|
498
|
+
|
|
499
|
+
if (!binding || !className) {
|
|
500
|
+
logger.warn(
|
|
501
|
+
"Could not parse Durable Object binding:",
|
|
502
|
+
durableObject.toString()
|
|
503
|
+
);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
208
506
|
|
|
209
|
-
const { stop, waitUntilExit } = await unstable_dev(
|
|
210
|
-
scriptPath,
|
|
211
|
-
{
|
|
212
|
-
port,
|
|
213
|
-
watch: true,
|
|
214
|
-
localProtocol,
|
|
215
|
-
liveReload,
|
|
216
|
-
|
|
217
|
-
compatibilityDate: "2021-11-02",
|
|
218
|
-
nodeCompat,
|
|
219
|
-
vars: Object.fromEntries(
|
|
220
|
-
bindings
|
|
221
|
-
.map((binding) => binding.toString().split("="))
|
|
222
|
-
.map(([key, ...values]) => [key, values.join("=")])
|
|
223
|
-
),
|
|
224
|
-
kv: kvs.map((val) => ({
|
|
225
|
-
binding: val.toString(),
|
|
226
|
-
id: "",
|
|
227
|
-
})),
|
|
228
|
-
durableObjects: durableObjects.map((durableObject) => {
|
|
229
|
-
const [name, class_name] = durableObject.toString().split("=");
|
|
230
507
|
return {
|
|
231
|
-
name,
|
|
232
|
-
class_name,
|
|
508
|
+
name: binding,
|
|
509
|
+
class_name: className,
|
|
510
|
+
script_name: scriptName,
|
|
233
511
|
};
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
512
|
+
})
|
|
513
|
+
.filter(Boolean) as AdditionalDevProps["durableObjects"],
|
|
514
|
+
r2: r2s.map((binding) => {
|
|
515
|
+
return { binding: binding.toString(), bucket_name: "" };
|
|
516
|
+
}),
|
|
517
|
+
|
|
518
|
+
d1Databases: d1s.map((binding) => ({
|
|
519
|
+
binding: binding.toString(),
|
|
520
|
+
database_id: "", // Required for types, but unused by dev
|
|
521
|
+
database_name: `local-${binding}`,
|
|
522
|
+
})),
|
|
523
|
+
|
|
524
|
+
enablePagesAssetsServiceBinding: {
|
|
525
|
+
proxyPort,
|
|
526
|
+
directory,
|
|
245
527
|
},
|
|
246
|
-
true
|
|
247
|
-
|
|
528
|
+
forceLocal: true,
|
|
529
|
+
persist,
|
|
530
|
+
persistTo,
|
|
531
|
+
showInteractiveDevSession: undefined,
|
|
532
|
+
inspect: undefined,
|
|
533
|
+
logPrefix: "pages",
|
|
534
|
+
logLevel: logLevel ?? "warn",
|
|
535
|
+
experimental: { testMode: false, disableExperimentalWarning: true },
|
|
536
|
+
});
|
|
248
537
|
await metrics.sendMetricsEvent("run pages dev");
|
|
249
538
|
|
|
250
|
-
|
|
539
|
+
CLEANUP_CALLBACKS.push(stop);
|
|
540
|
+
|
|
541
|
+
void waitUntilExit().then(() => {
|
|
251
542
|
CLEANUP();
|
|
252
|
-
stop();
|
|
253
543
|
process.exit(0);
|
|
254
544
|
});
|
|
255
545
|
|
|
256
|
-
process.on("exit",
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
});
|
|
260
|
-
process.on("SIGINT", () => {
|
|
261
|
-
CLEANUP();
|
|
262
|
-
stop();
|
|
263
|
-
});
|
|
264
|
-
process.on("SIGTERM", () => {
|
|
265
|
-
CLEANUP();
|
|
266
|
-
stop();
|
|
267
|
-
});
|
|
546
|
+
process.on("exit", CLEANUP);
|
|
547
|
+
process.on("SIGINT", CLEANUP);
|
|
548
|
+
process.on("SIGTERM", CLEANUP);
|
|
268
549
|
};
|
|
269
550
|
|
|
270
551
|
function isWindows() {
|
|
@@ -306,7 +587,8 @@ function getPort(pid: number) {
|
|
|
306
587
|
let command: string, regExp: RegExp;
|
|
307
588
|
|
|
308
589
|
if (isWindows()) {
|
|
309
|
-
|
|
590
|
+
const drive = homedir().split(":\\")[0];
|
|
591
|
+
command = drive + ":\\windows\\system32\\netstat.exe -nao";
|
|
310
592
|
regExp = new RegExp(`TCP\\s+.*:(\\d+)\\s+.*:\\d+\\s+LISTENING\\s+${pid}`);
|
|
311
593
|
} else {
|
|
312
594
|
command = "lsof -nPi";
|
|
@@ -337,9 +619,13 @@ async function spawnProxyProcess({
|
|
|
337
619
|
command: (string | number)[];
|
|
338
620
|
}): Promise<undefined | number> {
|
|
339
621
|
if (command.length === 0) {
|
|
622
|
+
if (port !== undefined) {
|
|
623
|
+
return port;
|
|
624
|
+
}
|
|
625
|
+
|
|
340
626
|
CLEANUP();
|
|
341
627
|
throw new FatalError(
|
|
342
|
-
"Must specify a directory of static assets to serve or a command to run.",
|
|
628
|
+
"Must specify a directory of static assets to serve or a command to run or a proxy port.",
|
|
343
629
|
1
|
|
344
630
|
);
|
|
345
631
|
}
|
|
@@ -370,6 +656,8 @@ async function spawnProxyProcess({
|
|
|
370
656
|
|
|
371
657
|
proxy.on("close", (code) => {
|
|
372
658
|
logger.error(`Proxy exited with status ${code}.`);
|
|
659
|
+
CLEANUP();
|
|
660
|
+
process.exitCode = code ?? 0;
|
|
373
661
|
});
|
|
374
662
|
|
|
375
663
|
// Wait for proxy process to start...
|
|
@@ -399,3 +687,24 @@ async function spawnProxyProcess({
|
|
|
399
687
|
|
|
400
688
|
return port;
|
|
401
689
|
}
|
|
690
|
+
|
|
691
|
+
// TODO: Kill this once we have https://github.com/cloudflare/wrangler2/issues/2153
|
|
692
|
+
const blockWorkerJsImports: esbuild.Plugin = {
|
|
693
|
+
name: "block-worker-js-imports",
|
|
694
|
+
setup(build) {
|
|
695
|
+
build.onResolve({ filter: /.*/g }, (args) => {
|
|
696
|
+
// If it's the entrypoint, let it be as is
|
|
697
|
+
if (args.kind === "entry-point") {
|
|
698
|
+
return {
|
|
699
|
+
path: args.path,
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
// Otherwise, block any imports that the file is requesting
|
|
703
|
+
logger.error(
|
|
704
|
+
`_worker.js is importing from another file. This will throw an error if deployed.\nYou should bundle your Worker or remove the import if it is unused.`
|
|
705
|
+
);
|
|
706
|
+
// Miniflare will error with this briefly down the line -- there's no point in continuing.
|
|
707
|
+
process.exit(1);
|
|
708
|
+
});
|
|
709
|
+
},
|
|
710
|
+
};
|