wrangler 2.5.0 → 2.6.0
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/miniflare-dist/index.mjs +85 -41
- package/package.json +3 -3
- package/src/__tests__/configuration.test.ts +211 -0
- package/src/__tests__/dev.test.tsx +17 -0
- package/src/__tests__/init.test.ts +18 -3
- package/src/__tests__/metrics.test.ts +88 -43
- package/src/__tests__/pages-deployment-tail.test.ts +165 -101
- package/src/__tests__/publish.test.ts +94 -7
- package/src/__tests__/pubsub.test.ts +208 -88
- package/src/__tests__/tail.test.ts +1 -1
- package/src/__tests__/type-generation.test.ts +7 -0
- package/src/config/environment.ts +16 -0
- package/src/config/index.ts +31 -8
- package/src/config/validation.ts +49 -0
- package/src/create-worker-upload-form.ts +9 -0
- package/src/dev/local.tsx +48 -18
- package/src/dev/start-server.ts +1 -5
- package/src/dev.tsx +23 -2
- package/src/git-client.ts +15 -4
- package/src/index.tsx +1 -0
- package/src/init.ts +8 -0
- package/src/miniflare-cli/assets.ts +51 -29
- package/src/miniflare-cli/index.ts +1 -0
- package/src/pages/dev.tsx +7 -0
- package/src/publish/publish.ts +1 -0
- package/src/secret/index.ts +1 -0
- package/src/type-generation.ts +10 -2
- package/src/worker.ts +6 -0
- package/wrangler-dist/cli.d.ts +15 -0
- package/wrangler-dist/cli.js +1837 -473
package/src/dev/local.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { realpathSync } from "node:fs";
|
|
|
4
4
|
import { readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
+
import getPort from "get-port";
|
|
7
8
|
import { npxImport } from "npx-import";
|
|
8
9
|
import { useState, useEffect, useRef } from "react";
|
|
9
10
|
import onExit from "signal-exit";
|
|
@@ -11,6 +12,7 @@ import { performApiFetch } from "../cfetch/internal";
|
|
|
11
12
|
import { registerWorker } from "../dev-registry";
|
|
12
13
|
import useInspector from "../inspect";
|
|
13
14
|
import { logger } from "../logger";
|
|
15
|
+
import generateASSETSBinding from "../miniflare-cli/assets";
|
|
14
16
|
import {
|
|
15
17
|
DEFAULT_MODULE_RULES,
|
|
16
18
|
ModuleTypeToRuleType,
|
|
@@ -110,7 +112,6 @@ function useLocalWorker({
|
|
|
110
112
|
workerDefinitions,
|
|
111
113
|
assetPaths,
|
|
112
114
|
initialPort,
|
|
113
|
-
inspectorPort,
|
|
114
115
|
rules,
|
|
115
116
|
localPersistencePath,
|
|
116
117
|
liveReload,
|
|
@@ -134,6 +135,11 @@ function useLocalWorker({
|
|
|
134
135
|
const removeExperimentalLocalSignalExitListener = useRef<() => void>();
|
|
135
136
|
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
136
137
|
|
|
138
|
+
// Our inspector proxy server will be binding to `LocalProps`'s `inspectorPort`.
|
|
139
|
+
// If we attempted to bind Node.js/workerd to the same inspector port, we'd get a port already in use error.
|
|
140
|
+
// Therefore, generate a new random port for our runtime's to bind their inspector service to.
|
|
141
|
+
const runtimeInspectorPortRef = useRef<number>();
|
|
142
|
+
|
|
137
143
|
useEffect(() => {
|
|
138
144
|
if (bindings.services && bindings.services.length > 0) {
|
|
139
145
|
logger.warn(
|
|
@@ -159,13 +165,6 @@ function useLocalWorker({
|
|
|
159
165
|
async function startLocalWorker() {
|
|
160
166
|
if (!bundle || !format) return;
|
|
161
167
|
|
|
162
|
-
// port for the worker
|
|
163
|
-
await waitForPortToBeAvailable(initialPort, {
|
|
164
|
-
retryPeriod: 200,
|
|
165
|
-
timeout: 2000,
|
|
166
|
-
abortSignal: abortController.signal,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
168
|
// In local mode, we want to copy all referenced modules into
|
|
170
169
|
// the output bundle directory before starting up
|
|
171
170
|
for (const module of bundle.modules) {
|
|
@@ -197,6 +196,9 @@ function useLocalWorker({
|
|
|
197
196
|
bundle,
|
|
198
197
|
});
|
|
199
198
|
|
|
199
|
+
runtimeInspectorPortRef.current ??= await getPort();
|
|
200
|
+
const runtimeInspectorPort = runtimeInspectorPortRef.current;
|
|
201
|
+
|
|
200
202
|
const { forkOptions, miniflareCLIPath, options } = setupMiniflareOptions({
|
|
201
203
|
workerName,
|
|
202
204
|
port: initialPort,
|
|
@@ -236,11 +238,12 @@ function useLocalWorker({
|
|
|
236
238
|
format,
|
|
237
239
|
bundle,
|
|
238
240
|
log,
|
|
241
|
+
enablePagesAssetsServiceBinding,
|
|
239
242
|
kvNamespaces: bindings?.kv_namespaces,
|
|
240
243
|
r2Buckets: bindings?.r2_buckets,
|
|
241
244
|
authenticatedAccountId: accountId,
|
|
242
245
|
kvRemote: experimentalLocalRemoteKv,
|
|
243
|
-
inspectorPort,
|
|
246
|
+
inspectorPort: runtimeInspectorPort,
|
|
244
247
|
});
|
|
245
248
|
|
|
246
249
|
const current = experimentalLocalRef.current;
|
|
@@ -268,7 +271,7 @@ function useLocalWorker({
|
|
|
268
271
|
try {
|
|
269
272
|
// fetch the inspector JSON response from the DevTools Inspector protocol
|
|
270
273
|
const inspectorJSONArr = (await (
|
|
271
|
-
await fetch(`http://127.0.0.1:${
|
|
274
|
+
await fetch(`http://127.0.0.1:${runtimeInspectorPort}/json`)
|
|
272
275
|
).json()) as InspectorJSON;
|
|
273
276
|
|
|
274
277
|
const foundInspectorURL = inspectorJSONArr?.find((inspectorJSON) =>
|
|
@@ -295,10 +298,18 @@ function useLocalWorker({
|
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
300
|
|
|
301
|
+
// Wait for the Worker port to be available. We don't want to do this in experimental local
|
|
302
|
+
// mode, as we only `dispose()` the Miniflare 3 instance, and shutdown the server when
|
|
303
|
+
// unmounting the component, not when props change. If we did, we'd just timeout every time.
|
|
304
|
+
await waitForPortToBeAvailable(initialPort, {
|
|
305
|
+
retryPeriod: 200,
|
|
306
|
+
timeout: 2000,
|
|
307
|
+
abortSignal: abortController.signal,
|
|
308
|
+
});
|
|
309
|
+
|
|
298
310
|
const nodeOptions = setupNodeOptions({
|
|
299
311
|
inspect,
|
|
300
|
-
|
|
301
|
-
inspectorPort,
|
|
312
|
+
inspectorPort: runtimeInspectorPort,
|
|
302
313
|
});
|
|
303
314
|
logger.log("⎔ Starting a local server...");
|
|
304
315
|
|
|
@@ -386,7 +397,13 @@ function useLocalWorker({
|
|
|
386
397
|
}
|
|
387
398
|
|
|
388
399
|
startLocalWorker().catch((err) => {
|
|
389
|
-
|
|
400
|
+
if (err.code === "ERR_RUNTIME_FAILURE") {
|
|
401
|
+
// Don't log a full verbose stack-trace when Miniflare 3's workerd instance fails to start.
|
|
402
|
+
// workerd will log its own errors, and our stack trace won't have any useful information.
|
|
403
|
+
logger.error(err.message);
|
|
404
|
+
} else {
|
|
405
|
+
logger.error("local worker:", err);
|
|
406
|
+
}
|
|
390
407
|
});
|
|
391
408
|
|
|
392
409
|
return () => {
|
|
@@ -404,7 +421,6 @@ function useLocalWorker({
|
|
|
404
421
|
workerName,
|
|
405
422
|
format,
|
|
406
423
|
initialPort,
|
|
407
|
-
inspectorPort,
|
|
408
424
|
initialIp,
|
|
409
425
|
queueConsumers,
|
|
410
426
|
bindings.queues,
|
|
@@ -733,11 +749,9 @@ export function setupMiniflareOptions({
|
|
|
733
749
|
|
|
734
750
|
export function setupNodeOptions({
|
|
735
751
|
inspect,
|
|
736
|
-
ip,
|
|
737
752
|
inspectorPort,
|
|
738
753
|
}: {
|
|
739
754
|
inspect: boolean;
|
|
740
|
-
ip: string;
|
|
741
755
|
inspectorPort: number;
|
|
742
756
|
}) {
|
|
743
757
|
const nodeOptions = [
|
|
@@ -746,7 +760,7 @@ export function setupNodeOptions({
|
|
|
746
760
|
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
747
761
|
];
|
|
748
762
|
if (inspect) {
|
|
749
|
-
nodeOptions.push("--inspect=" +
|
|
763
|
+
nodeOptions.push("--inspect=" + `127.0.0.1:${inspectorPort}`); // start Miniflare listening for a debugger to attach
|
|
750
764
|
}
|
|
751
765
|
return nodeOptions;
|
|
752
766
|
}
|
|
@@ -761,6 +775,8 @@ export interface SetupMiniflare3Options {
|
|
|
761
775
|
// Miniflare's logger
|
|
762
776
|
log: Miniflare3LogType;
|
|
763
777
|
|
|
778
|
+
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
|
|
779
|
+
|
|
764
780
|
// Miniflare 3 accepts namespace/bucket names in addition to binding names.
|
|
765
781
|
// This means multiple workers persisting to the same location can have
|
|
766
782
|
// different binding names for the same namespace/bucket. Therefore, we need
|
|
@@ -798,6 +814,7 @@ export async function transformMf2OptionsToMf3Options({
|
|
|
798
814
|
format,
|
|
799
815
|
bundle,
|
|
800
816
|
log,
|
|
817
|
+
enablePagesAssetsServiceBinding,
|
|
801
818
|
kvNamespaces,
|
|
802
819
|
r2Buckets,
|
|
803
820
|
authenticatedAccountId,
|
|
@@ -833,6 +850,19 @@ export async function transformMf2OptionsToMf3Options({
|
|
|
833
850
|
log,
|
|
834
851
|
};
|
|
835
852
|
|
|
853
|
+
if (enablePagesAssetsServiceBinding !== undefined) {
|
|
854
|
+
options.serviceBindings = {
|
|
855
|
+
...options.serviceBindings,
|
|
856
|
+
ASSETS: (await generateASSETSBinding({
|
|
857
|
+
log,
|
|
858
|
+
...enablePagesAssetsServiceBinding,
|
|
859
|
+
tre: true,
|
|
860
|
+
// We can get rid of this `any` easily once we do experimental-local/tre by default
|
|
861
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
862
|
+
})) as any,
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
836
866
|
if (format === "modules") {
|
|
837
867
|
// Manually specify all modules from the bundle. If we didn't do this,
|
|
838
868
|
// Miniflare 3 would try collect them automatically again itself.
|
|
@@ -886,5 +916,5 @@ export async function getMiniflare3(): Promise<
|
|
|
886
916
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
887
917
|
typeof import("@miniflare/tre")
|
|
888
918
|
> {
|
|
889
|
-
return (miniflare3Module ??= await npxImport("@miniflare/tre@3.0.0-next.
|
|
919
|
+
return (miniflare3Module ??= await npxImport("@miniflare/tre@3.0.0-next.8"));
|
|
890
920
|
}
|
package/src/dev/start-server.ts
CHANGED
|
@@ -426,11 +426,7 @@ export async function startLocalServer({
|
|
|
426
426
|
return;
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
const nodeOptions = setupNodeOptions({
|
|
430
|
-
inspect,
|
|
431
|
-
ip: initialIp,
|
|
432
|
-
inspectorPort,
|
|
433
|
-
});
|
|
429
|
+
const nodeOptions = setupNodeOptions({ inspect, inspectorPort });
|
|
434
430
|
logger.log("⎔ Starting a local server...");
|
|
435
431
|
|
|
436
432
|
const child = (local = fork(miniflareCLIPath, forkOptions, {
|
package/src/dev.tsx
CHANGED
|
@@ -14,7 +14,7 @@ import { getEntry } from "./entry";
|
|
|
14
14
|
import { logger } from "./logger";
|
|
15
15
|
import * as metrics from "./metrics";
|
|
16
16
|
import { getAssetPaths, getSiteAssetPaths } from "./sites";
|
|
17
|
-
import { getAccountFromCache } from "./user";
|
|
17
|
+
import { getAccountFromCache, loginOrRefreshIfRequired } from "./user";
|
|
18
18
|
import { collectKeyValues } from "./utils/collectKeyValues";
|
|
19
19
|
import { identifyD1BindingsAsBeta } from "./worker";
|
|
20
20
|
import { getHostFromRoute, getZoneForRoute, getZoneIdFromHost } from "./zones";
|
|
@@ -328,6 +328,15 @@ export function devOptions(yargs: Argv<CommonYargsOptions>): Argv<DevArgs> {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
|
|
331
|
+
if (!args.local) {
|
|
332
|
+
const isLoggedIn = await loginOrRefreshIfRequired();
|
|
333
|
+
if (!isLoggedIn) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
"You must be logged in to use wrangler dev in remote mode. Try logging in, or run wrangler dev --local."
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
331
340
|
let watcher;
|
|
332
341
|
try {
|
|
333
342
|
const devInstance = await startDev(args);
|
|
@@ -892,10 +901,22 @@ async function getBindings(
|
|
|
892
901
|
],
|
|
893
902
|
dispatch_namespaces: configParam.dispatch_namespaces,
|
|
894
903
|
services: configParam.services,
|
|
904
|
+
analytics_engine_datasets: configParam.analytics_engine_datasets,
|
|
895
905
|
unsafe: configParam.unsafe?.bindings,
|
|
896
906
|
logfwdr: configParam.logfwdr,
|
|
897
907
|
d1_databases: identifyD1BindingsAsBeta([
|
|
898
|
-
...configParam.d1_databases
|
|
908
|
+
...(configParam.d1_databases ?? []).map((d1Db) => {
|
|
909
|
+
if (!d1Db.preview_database_id) {
|
|
910
|
+
throw new Error(
|
|
911
|
+
`In development, you should use a separate D1 database than the one you'd use in production. Please create a new D1 database with "wrangler d1 create <name>" and add its id as preview_database_id to the d1_database "${d1Db.binding}" in your wrangler.toml`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
return {
|
|
916
|
+
...d1Db,
|
|
917
|
+
database_id: d1Db.preview_database_id,
|
|
918
|
+
};
|
|
919
|
+
}),
|
|
899
920
|
...(args.d1Databases || []),
|
|
900
921
|
]),
|
|
901
922
|
};
|
package/src/git-client.ts
CHANGED
|
@@ -42,10 +42,21 @@ export async function getGitVersioon(): Promise<string | null> {
|
|
|
42
42
|
*/
|
|
43
43
|
export async function initializeGit(cwd: string) {
|
|
44
44
|
try {
|
|
45
|
-
//
|
|
46
|
-
await execa("git", [
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
// Get the default init branch name
|
|
46
|
+
const { stdout: defaultBranchName } = await execa("git", [
|
|
47
|
+
"config",
|
|
48
|
+
"--get",
|
|
49
|
+
"init.defaultBranch",
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
// Try to create the repository with the HEAD branch of defaultBranchName ?? `main`.
|
|
53
|
+
await execa(
|
|
54
|
+
"git",
|
|
55
|
+
["init", "--initial-branch", defaultBranchName.trim() ?? "main"],
|
|
56
|
+
{
|
|
57
|
+
cwd,
|
|
58
|
+
}
|
|
59
|
+
);
|
|
49
60
|
} catch {
|
|
50
61
|
// Unable to create the repo with a HEAD branch name, so just fall back to the default.
|
|
51
62
|
await execa("git", ["init"], {
|
package/src/index.tsx
CHANGED
|
@@ -543,6 +543,7 @@ export function createCLIParser(argv: string[]) {
|
|
|
543
543
|
r2_buckets: config.r2_buckets,
|
|
544
544
|
d1_databases: config.d1_databases,
|
|
545
545
|
services: config.services,
|
|
546
|
+
analytics_engine_datasets: config.analytics_engine_datasets,
|
|
546
547
|
dispatch_namespaces: config.dispatch_namespaces,
|
|
547
548
|
logfwdr: config.logfwdr,
|
|
548
549
|
unsafe: { bindings: config.unsafe?.bindings },
|
package/src/init.ts
CHANGED
|
@@ -862,6 +862,14 @@ async function getWorkerConfig(
|
|
|
862
862
|
];
|
|
863
863
|
}
|
|
864
864
|
break;
|
|
865
|
+
case "analytics_engine":
|
|
866
|
+
{
|
|
867
|
+
configObj.analytics_engine_datasets = [
|
|
868
|
+
...(configObj.analytics_engine_datasets ?? []),
|
|
869
|
+
{ binding: binding.name, dataset: binding.dataset },
|
|
870
|
+
];
|
|
871
|
+
}
|
|
872
|
+
break;
|
|
865
873
|
case "namespace":
|
|
866
874
|
{
|
|
867
875
|
configObj.dispatch_namespaces = [
|
|
@@ -3,59 +3,69 @@ import { join } from "node:path";
|
|
|
3
3
|
import { createMetadataObject } from "@cloudflare/pages-shared/metadata-generator/createMetadataObject";
|
|
4
4
|
import { parseHeaders } from "@cloudflare/pages-shared/metadata-generator/parseHeaders";
|
|
5
5
|
import { parseRedirects } from "@cloudflare/pages-shared/metadata-generator/parseRedirects";
|
|
6
|
-
import {
|
|
7
|
-
Response as MiniflareResponse,
|
|
8
|
-
Request as MiniflareRequest,
|
|
9
|
-
} from "@miniflare/core";
|
|
10
|
-
import { upgradingFetch as miniflareFetch } from "@miniflare/web-sockets";
|
|
11
6
|
import { watch } from "chokidar";
|
|
12
7
|
import { getType } from "mime";
|
|
13
8
|
import { hashFile } from "../pages/hash";
|
|
14
9
|
import type { Metadata } from "@cloudflare/pages-shared/asset-server/metadata";
|
|
15
|
-
import type {
|
|
16
|
-
fetch,
|
|
17
|
-
Request,
|
|
18
|
-
} from "@cloudflare/pages-shared/environment-polyfills/types";
|
|
19
10
|
import type {
|
|
20
11
|
ParsedRedirects,
|
|
21
12
|
ParsedHeaders,
|
|
22
13
|
} from "@cloudflare/pages-shared/metadata-generator/types";
|
|
23
|
-
import type {
|
|
24
|
-
|
|
14
|
+
import type {
|
|
15
|
+
RequestInfo as TreRequestInfo,
|
|
16
|
+
RequestInit as TreRequestInit,
|
|
17
|
+
} from "@miniflare/tre";
|
|
18
|
+
|
|
19
|
+
interface Logger {
|
|
20
|
+
log: (message: string) => void;
|
|
21
|
+
warn: (message: string) => void;
|
|
22
|
+
error: (error: Error) => void;
|
|
23
|
+
}
|
|
25
24
|
|
|
26
25
|
export interface Options {
|
|
27
|
-
log:
|
|
26
|
+
log: Logger;
|
|
28
27
|
proxyPort?: number;
|
|
29
28
|
directory?: string;
|
|
29
|
+
tre: boolean;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export default async function generateASSETSBinding(options: Options) {
|
|
33
33
|
const assetsFetch =
|
|
34
34
|
options.directory !== undefined
|
|
35
|
-
? await generateAssetsFetch(options.directory, options.log)
|
|
35
|
+
? await generateAssetsFetch(options.directory, options.log, options.tre)
|
|
36
36
|
: invalidAssetsFetch;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
const miniflare = options.tre
|
|
39
|
+
? await import("@miniflare/tre")
|
|
40
|
+
: await import("@miniflare/core");
|
|
41
|
+
|
|
42
|
+
const Request = miniflare.Request;
|
|
43
|
+
const Response = miniflare.Response;
|
|
44
|
+
// WebSockets won't work with `--experimental-local` until we expose something like `upgradingFetch` from `@miniflare/tre`.
|
|
45
|
+
const fetch = (
|
|
46
|
+
options.tre
|
|
47
|
+
? miniflare.fetch
|
|
48
|
+
: (await import("@miniflare/web-sockets")).upgradingFetch
|
|
49
|
+
) as (request: Request) => Promise<Response>;
|
|
50
|
+
|
|
51
|
+
return async function (miniflareRequest: Request) {
|
|
39
52
|
if (options.proxyPort) {
|
|
40
53
|
try {
|
|
41
54
|
const url = new URL(miniflareRequest.url);
|
|
42
55
|
url.host = `localhost:${options.proxyPort}`;
|
|
43
|
-
const proxyRequest = new
|
|
56
|
+
const proxyRequest = new Request(url, miniflareRequest);
|
|
44
57
|
if (proxyRequest.headers.get("Upgrade") === "websocket") {
|
|
45
58
|
proxyRequest.headers.delete("Sec-WebSocket-Accept");
|
|
46
59
|
proxyRequest.headers.delete("Sec-WebSocket-Key");
|
|
47
60
|
}
|
|
48
|
-
return await
|
|
61
|
+
return await fetch(proxyRequest as Request);
|
|
49
62
|
} catch (thrown) {
|
|
50
63
|
options.log.error(new Error(`Could not proxy request: ${thrown}`));
|
|
51
64
|
|
|
52
65
|
// TODO: Pretty error page
|
|
53
|
-
return new
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
status: 502,
|
|
57
|
-
}
|
|
58
|
-
);
|
|
66
|
+
return new Response(`[wrangler] Could not proxy request: ${thrown}`, {
|
|
67
|
+
status: 502,
|
|
68
|
+
});
|
|
59
69
|
}
|
|
60
70
|
} else {
|
|
61
71
|
try {
|
|
@@ -64,21 +74,33 @@ export default async function generateASSETSBinding(options: Options) {
|
|
|
64
74
|
options.log.error(new Error(`Could not serve static asset: ${thrown}`));
|
|
65
75
|
|
|
66
76
|
// TODO: Pretty error page
|
|
67
|
-
return new
|
|
77
|
+
return new Response(
|
|
68
78
|
`[wrangler] Could not serve static asset: ${thrown}`,
|
|
69
79
|
{ status: 502 }
|
|
70
80
|
);
|
|
71
81
|
}
|
|
72
82
|
}
|
|
73
|
-
}
|
|
83
|
+
};
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
async function generateAssetsFetch(
|
|
77
87
|
directory: string,
|
|
78
|
-
log:
|
|
88
|
+
log: Logger,
|
|
89
|
+
tre: boolean
|
|
79
90
|
): Promise<typeof fetch> {
|
|
80
91
|
// Defer importing miniflare until we really need it
|
|
81
|
-
|
|
92
|
+
if (tre) {
|
|
93
|
+
await import(
|
|
94
|
+
"@cloudflare/pages-shared/environment-polyfills/miniflare-tre"
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
await import("@cloudflare/pages-shared/environment-polyfills/miniflare");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const miniflare = tre
|
|
101
|
+
? await import("@miniflare/tre")
|
|
102
|
+
: await import("@miniflare/core");
|
|
103
|
+
const Request = miniflare.Request;
|
|
82
104
|
|
|
83
105
|
const { generateHandler, parseQualityWeightedList } = await import(
|
|
84
106
|
"@cloudflare/pages-shared/asset-server/handler"
|
|
@@ -207,10 +229,10 @@ async function generateAssetsFetch(
|
|
|
207
229
|
});
|
|
208
230
|
};
|
|
209
231
|
|
|
210
|
-
return async (input:
|
|
211
|
-
const request = new
|
|
232
|
+
return (async (input: TreRequestInfo, init?: TreRequestInit) => {
|
|
233
|
+
const request = new Request(input, init);
|
|
212
234
|
return await generateResponse(request as unknown as Request);
|
|
213
|
-
};
|
|
235
|
+
}) as typeof fetch;
|
|
214
236
|
}
|
|
215
237
|
|
|
216
238
|
const invalidAssetsFetch: typeof fetch = () => {
|
package/src/pages/dev.tsx
CHANGED
|
@@ -134,6 +134,11 @@ export function Options(yargs: Argv) {
|
|
|
134
134
|
type: "boolean",
|
|
135
135
|
hidden: true,
|
|
136
136
|
},
|
|
137
|
+
"experimental-local": {
|
|
138
|
+
describe: "Run on my machine using the Cloudflare Workers runtime",
|
|
139
|
+
type: "boolean",
|
|
140
|
+
default: false,
|
|
141
|
+
},
|
|
137
142
|
config: {
|
|
138
143
|
describe: "Pages does not support wrangler.toml",
|
|
139
144
|
type: "string",
|
|
@@ -168,6 +173,7 @@ export const Handler = async ({
|
|
|
168
173
|
persist,
|
|
169
174
|
persistTo,
|
|
170
175
|
"node-compat": nodeCompat,
|
|
176
|
+
"experimental-local": experimentalLocal,
|
|
171
177
|
config: config,
|
|
172
178
|
_: [_pages, _dev, ...remaining],
|
|
173
179
|
logLevel,
|
|
@@ -476,6 +482,7 @@ export const Handler = async ({
|
|
|
476
482
|
compatibilityDate,
|
|
477
483
|
compatibilityFlags,
|
|
478
484
|
nodeCompat,
|
|
485
|
+
experimentalLocal,
|
|
479
486
|
vars: Object.fromEntries(
|
|
480
487
|
bindings
|
|
481
488
|
.map((binding) => binding.toString().split("="))
|
package/src/publish/publish.ts
CHANGED
|
@@ -540,6 +540,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
|
|
|
540
540
|
r2_buckets: config.r2_buckets,
|
|
541
541
|
d1_databases: identifyD1BindingsAsBeta(config.d1_databases),
|
|
542
542
|
services: config.services,
|
|
543
|
+
analytics_engine_datasets: config.analytics_engine_datasets,
|
|
543
544
|
dispatch_namespaces: config.dispatch_namespaces,
|
|
544
545
|
logfwdr: config.logfwdr,
|
|
545
546
|
unsafe: config.unsafe?.bindings,
|
package/src/secret/index.ts
CHANGED
package/src/type-generation.ts
CHANGED
|
@@ -59,6 +59,14 @@ export async function generateTypes(
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
if (configToDTS.analytics_engine_datasets) {
|
|
63
|
+
for (const analyticsEngine of configToDTS.analytics_engine_datasets) {
|
|
64
|
+
envTypeStructure.push(
|
|
65
|
+
`${analyticsEngine.binding}: AnalyticsEngineDataset;`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
62
70
|
if (configToDTS.dispatch_namespaces) {
|
|
63
71
|
for (const namespace of configToDTS.dispatch_namespaces) {
|
|
64
72
|
envTypeStructure.push(`${namespace.binding}: any;`);
|
|
@@ -156,11 +164,11 @@ function writeDTSFile({
|
|
|
156
164
|
if (formatType === "modules") {
|
|
157
165
|
combinedTypeStrings += `interface Env {\n${envTypeStructure
|
|
158
166
|
.map((value) => `\t${value}`)
|
|
159
|
-
.join("\n")}
|
|
167
|
+
.join("\n")}\n}\n${modulesTypeStructure.join("\n")}`;
|
|
160
168
|
} else {
|
|
161
169
|
combinedTypeStrings += `export {};\ndeclare global {\n${envTypeStructure
|
|
162
170
|
.map((value) => `\tconst ${value}`)
|
|
163
|
-
.join("\n")}
|
|
171
|
+
.join("\n")}\n}\n${modulesTypeStructure.join("\n")}`;
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
if (envTypeStructure.length || modulesTypeStructure.length) {
|
package/src/worker.ts
CHANGED
|
@@ -144,6 +144,11 @@ interface CfService {
|
|
|
144
144
|
environment?: string;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
interface CfAnalyticsEngineDataset {
|
|
148
|
+
binding: string;
|
|
149
|
+
dataset?: string;
|
|
150
|
+
}
|
|
151
|
+
|
|
147
152
|
interface CfDispatchNamespace {
|
|
148
153
|
binding: string;
|
|
149
154
|
namespace: string;
|
|
@@ -207,6 +212,7 @@ export interface CfWorkerInit {
|
|
|
207
212
|
r2_buckets: CfR2Bucket[] | undefined;
|
|
208
213
|
d1_databases: CfD1Database[] | undefined;
|
|
209
214
|
services: CfService[] | undefined;
|
|
215
|
+
analytics_engine_datasets: CfAnalyticsEngineDataset[] | undefined;
|
|
210
216
|
dispatch_namespaces: CfDispatchNamespace[] | undefined;
|
|
211
217
|
logfwdr: CfLogfwdr | undefined;
|
|
212
218
|
unsafe: CfUnsafeBinding[] | undefined;
|
package/wrangler-dist/cli.d.ts
CHANGED
|
@@ -527,6 +527,21 @@ declare interface EnvironmentNonInheritable {
|
|
|
527
527
|
/** The environment of the service (e.g. production, staging, etc). */
|
|
528
528
|
environment?: string;
|
|
529
529
|
}[] | undefined;
|
|
530
|
+
/**
|
|
531
|
+
* Specifies analytics engine datasets that are bound to this Worker environment.
|
|
532
|
+
*
|
|
533
|
+
* NOTE: This field is not automatically inherited from the top level environment,
|
|
534
|
+
* and so must be specified in every named environment.
|
|
535
|
+
*
|
|
536
|
+
* @default `[]`
|
|
537
|
+
* @nonInheritable
|
|
538
|
+
*/
|
|
539
|
+
analytics_engine_datasets: {
|
|
540
|
+
/** The binding name used to refer to the dataset in the worker. */
|
|
541
|
+
binding: string;
|
|
542
|
+
/** The name of this dataset to write to. */
|
|
543
|
+
dataset?: string;
|
|
544
|
+
}[];
|
|
530
545
|
/**
|
|
531
546
|
* "Unsafe" tables for features that aren't directly supported by wrangler.
|
|
532
547
|
*
|